* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-26 13:14 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-26 13:14 UTC (permalink / raw
To: gentoo-commits
commit: 9298e87377b76ecd093535458d4566d890c7b2e8
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat May 26 13:14:04 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat May 26 13:14:04 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9298e873
roverlay,fileio, DescriptionReader:
field identifier aliases now in field ['alias'] [<alias_type>]
add ability to set default values for fields
field flag checking improved
modified: roverlay/fileio.py
---
roverlay/fileio.py | 336 +++++++++++++++++++++++++++++-----------------------
1 files changed, 189 insertions(+), 147 deletions(-)
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 88cca0f..6e905b9 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -9,39 +9,34 @@ import tarfile
# temporary import until logging is implemented
from sys import stderr as logging
-
-
# temporary import until config and real constants are implemented
from roverlay import tmpconst as const
class DescriptionReader:
+ """Description Reader"""
@classmethod
def __init__ ( self ):
"""Initializes a DESCRIPTION file reader."""
- self._mandatory_fields = []
+ pass
@classmethod
- def _get_mandatory_fields ( self, force_update=False ):
- """Returns a list of the fields a DESCRIPTION file must define.
+ def _get_fields_with_flag ( self, flag, foce_update=False ):
- arguments:
- * force_update -- enforce creation of a new list
- """
+ matching_fields = []
- # use previously calculated results (if item count > 0)
- if force_update or ( not len (self._mandatory_fields) ):
- field = None
- mandatory = []
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
- if 'mandatory' in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
- mandatory.append ( field )
+ field = None
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+ if flag is None:
+ matching_fields.append ( field )
+
+ elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
+ if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
+ matching_fields.append ( field )
- self._mandatory_fields = mandatory
- del field, mandatory
+ del field
+ return matching_fields
- return self._mandatory_fields
@classmethod
def _find_field ( self , field_identifier ):
@@ -62,7 +57,7 @@ class DescriptionReader:
# save some time by prevent searching if field_id is empty
if not field_identifier:
- return ''
+ return None
# search for real field names first
for field in const.DESCRIPTION_FIELD_MAP.keys():
@@ -73,29 +68,23 @@ class DescriptionReader:
for field in const.DESCRIPTION_FIELD_MAP.keys():
- # ?TODO : DESCRIPTION_FIELD_MAP ['alias'] [<alias_types>] instead of the current structure?
-
# does extra information (-> alias(es)) for this field exist?
- if isinstance ( const.DESCRIPTION_FIELD_MAP [field], dict ):
-
- for alias_type in const.DESCRIPTION_FIELD_MAP [field] . keys():
-
- if alias_type == 'withcase':
-
- for alias in const.DESCRIPTION_FIELD_MAP [field] [alias_type]:
- if field_identifier == alias:
- return field
+ if 'alias' in const.DESCRIPTION_FIELD_MAP [field]:
- elif alias_type == 'nocase':
+ if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
+ for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withcase']:
+ if field_identifier == alias:
+ return field
- for alias in const.DESCRIPTION_FIELD_MAP [field] [alias_type]:
- if field_id_lower == alias.lower():
- return field
+ if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
+ for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocase']:
+ if field_id_lower == alias.lower():
+ return field
- #elif other_alias_type:
+ #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
- # returning empty string if no valid field identifier matches
- return ''
+ # returning None if no valid field identifier matches
+ return None
@classmethod
def _make_values ( self, value_str, field_context=None ):
@@ -111,12 +100,16 @@ class DescriptionReader:
svalue_str = value_str.strip()
- if field_context is None:
+ if not svalue_str:
+ # empty value(s)
+ return []
+
+ elif field_context is None:
# default return if no context given
return [ svalue_str ]
- if self._check_fieldflag ( field_context ):
- # have flags for field_context, check these
+ elif self._check_fieldflag ( field_context ):
+ # value str is not empty and have flags for field_context, check these
if self._check_fieldflag ( field_context, 'isList' ):
# split up this list (that is separated by commata and/or semicolons)
@@ -142,12 +135,9 @@ class DescriptionReader:
"""
if field in const.DESCRIPTION_FIELD_MAP:
-
if 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
-
if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
return True
-
elif flag_to_check is None:
# 'flags' exist, return true
return True
@@ -155,52 +145,146 @@ class DescriptionReader:
return False
@staticmethod
- def _get_desc_from_tarball ( tarball, pkg_name='.' ):
- """
- Extracts the contents of the description file in the given tarball
- and returns them as list of str.
+ def _get_desc_from_file ( filepath, pkg_name='.' ):
+ """Reads a file returns the description data.
arguments:
- * tarball -- tarball to read
- * pkg_name -- name of the package, usually the description file is
- <pkg_name>/DESCRIPTION and this that arguments is
- required. Defaults to '.', set to None to disable.
+ * filepath -- file to read (str; path to tarball or file)
+ * pkg_name -- name of the package, in tarballs the description file
+ is located in <pkg_name>/ and thus this argument is required.
+ Defaults to '.', set to None to disable.
All exceptions are passed to the caller (TarError, IOErr, <custom>).
+ <filepath> can either be a tarball in which case the real DESCRIPTION
+ file is read (<pkg_name>/DESCRIPTION) or a normal file.
"""
- logging.write ( "Starting to read tarball file '" + tarball + "' ...\n" )
+ logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
- if not tarfile.is_tarfile ( tarball ):
- # not a tarball, <todo> real exception
- raise Exception ("tarball expected")
+ if not ( isinstance ( filepath, str ) and filepath ):
+ raise Exception ( "bad usage" )
- # open a file handle <fh> for the DESCRIPTION file using a tar handle <th>
- th = fh = None
+ # read describes how to import the lines from a file (e.g. rstrip())
+ # fh, th are file/tar handles
+ read = th = fh = None
- th = tarfile.open ( tarball, 'r' )
- if pkg_name:
- fh = th.extractfile (
- os.path.join ( pkg_name, const.DESCRIPTION_FILE_NAME )
- )
+ if tarfile.is_tarfile ( filepath ):
+ # filepath is a tarball, open tar handle + file handle
+ th = tarfile.open ( filepath, 'r' )
+ if pkg_name:
+ fh = th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_FILE_NAME ) )
+ else:
+ fh = th.extractfile ( const.DESCRIPTION_FILE_NAME )
+
+ # have to decode the lines
+ read = lambda lines : [ line.decode().rstrip() for line in lines ]
else:
- fh = th.extractfile ( const.DESCRIPTION_FILE_NAME )
+ # open file handle only
+ fh = open ( filepath, 'r' )
+ read = lambda lines : [ line.rstrip() for line in lines ]
x = None
- # get lines from <fh>, decode and remove end of line whitespace
- read_lines = [ x.decode().rstrip() for x in fh.readlines() ]
- del x
+ read_lines = read ( fh.readlines() )
+ del x, read
fh.close()
- th.close()
-
+ if not th is None: th.close()
del fh, th
+
return read_lines
+ @staticmethod
+ def _get_fileinfo ( filepath ):
+ """Returns some info about the given filepath as dict whose contents are
+ the file path, the file name ([as package_file with suffix and]
+ as filename with tarball suffix removed), the package name
+ and the package_version.
+
+ arguments:
+ * filepath --
+ """
+
+ package_file = os.path.basename ( filepath )
+
+ filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
+
+ # todo move that separator to const
+ package_name, sepa, package_version = filename.partition ( '_' )
+
+ if not sepa:
+ # file name unexpected, tarball extraction will (probably) fail
+ #raise Exception ("file name unexpected")
+ logging.write ( "unexpected file name '" + filename + "'.\n" )
+
+ return dict (
+ filepath = filepath,
+ filename = filename,
+ #package_file = package_file,
+ package_name = package_name,
+ package_version = package_version,
+ )
+
@classmethod
- def readfile ( self, file ):
+ def _verify_read_data ( self, read_data ):
+ """Verifies and fixes (e.g. add default values) read data"""
+
+ def stats ( data ):
+ """Temporary function that prints some info about the given data."""
+ field = None
+ logging.write ( "=== this is the list of read data ===\n" )
+ for field in read_data.keys():
+ logging.write ( field + " = " + str ( read_data [field] ) + "\n" )
+ logging.write ( "=== end of list ===\n" )
+ del field
+
+ stats ( read_data )
+
+ # "finalize" data
+ logging.write ( "Fixing data...\n" )
+ field = None
+
+ # join values to a single str
+ for field in self._get_fields_with_flag ( 'joinValues' ):
+ if field in read_data.keys():
+ read_data [field] = ' ' . join ( read_data [field] )
+
+ # verify that all necessary fields have been added and are set
+ missing_fields = dict()
+ for field in self._get_fields_with_flag ( 'mandatory' ):
+ if field in read_data:
+ if not len (read_data [field]):
+ missing_fields [field] = 'unset'
+ else:
+ missing_fields [field] = 'missing'
+
+ del field
+
+ if len (missing_fields):
+ logging.write (
+ "Verification of mandatory fields failed, the result leading to this was: " +
+ str (missing_fields) + "\n"
+ )
+
+ #<raise custom exception>
+ raise Exception ("^^^look above")
+
+ del missing_fields
+
+ # add/insert default values
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+ if not field in read_data and 'default_value' in const.DESCRIPTION_FIELD_MAP [field]:
+ read_data [field] = const.DESCRIPTION_FIELD_MAP [field] ['default_value']
+
+
+ stats ( read_data )
+
+ return True
+
+
+ @classmethod
+ def readfile ( self, filepath ):
"""Reads a DESCRIPTION file and returns the read data if successful, else None.
arguments:
@@ -216,56 +300,50 @@ class DescriptionReader:
with <field value> as str and <field values> as list.
"""
- # todo move that regex to const
- filename = re.sub ('[.](tgz|tbz2|(tar[.](gz|bz2)))',
- '',
- os.path.basename ( file )
+ read_data = dict (
+ _ = DescriptionReader._get_fileinfo ( filepath )
)
- # todo move that separator to const
- package_name, sepa, package_version = filename.partition ( '_' )
- if not sepa:
- # file name unexpected
- raise Exception ("file name unexpected")
try:
- desc_lines = DescriptionReader._get_desc_from_tarball ( file, package_name )
+ desc_lines = DescriptionReader._get_desc_from_file (
+ filepath, read_data ['_'] ['package_name']
+ )
+
except IOError as err:
# <todo>
raise
- read_data = dict()
field_context = val = line = sline = None
for line in desc_lines:
+
# using s(tripped)line whenever whitespace doesn't matter
sline = line.lstrip()
- if not sline:
- # empty line
+ if (not sline) or (line [0] == const.DESCRIPTION_COMMENT_CHAR):
+ # empty line or comment
pass
- elif line [0] == const.DESCRIPTION_COMMENT_CHAR:
- pass
-
- elif field_context and line [0] != sline [0]:
- # line starts with whitespace and context is set => append values
- for val in self._make_values ( sline, field_context ):
- read_data [field_context] . append ( val )
+ elif line [0] != sline [0]:
+ # line starts with whitespace
+ if field_context:
+ # context is set => append values
- elif line [0] != sline [0]:
- # line starts with whitespace and context is not set => ignore
- pass
+ for val in self._make_values ( sline, field_context ):
+ read_data [field_context] . append ( val )
+ else:
+ # no valid context => ignore line
+ pass
else:
- # new context, forget last one
+ # line introduces a new field context, forget last one
field_context = None
line_components = sline.partition ( const.DESCRIPTION_FIELD_SEPARATOR )
-
if line_components [1]:
# line contains a field separator, set field context
field_context = self._find_field ( line_components [0] )
@@ -274,10 +352,10 @@ class DescriptionReader:
# create a new empty list for field_context
read_data [field_context] = []
- if len ( line_components ) == 3:
- # add values to read_data
- for val in self._make_values ( line_components [2], field_context ):
- read_data [field_context] . append ( val )
+ # add values to read_data
+ # no need to check line_components [2] 'cause [1] was a true str
+ for val in self._make_values ( line_components [2], field_context ):
+ read_data [field_context] . append ( val )
else:
# useless line, skip
@@ -286,57 +364,21 @@ class DescriptionReader:
+ line_components [0] + "'\n"
)
- del line_components
-
else:
- # how to reach this block? -- remove later
- raise Exception ( "should-be unreachable code" )
-
- del val, line, sline, field_context
-
- def stats ( data ):
- """Temporary function that prints some info about the given data."""
- field = None
- logging.write ( "=== this is the list of read data ===\n" )
- for field in read_data.keys():
- logging.write ( field + " = " + str ( read_data [field] ) + "\n" )
- logging.write ( "=== end of list ===\n" )
- del field
+ # reaching this branch means that
+ # (a) line has no leading whitespace
+ # (b) line has no separator (:)
+ # this should not occur in description files (bad syntax?)
+ logging.write ( "***" + line_components [0] + "***\n")
+ raise Exception ( "bad file" )
- stats ( read_data )
+ del line_components
- # "finalize" data
- field = None
- for field in read_data.keys():
- if self._check_fieldflag ( field ):
- # has flags
- if self._check_fieldflag ( field, 'joinValues' ):
- read_data [field] = ' ' . join ( read_data [field] )
+ del sline, line, val, field_context
- # verify that all necessary fields have been added and are set
- missing_fields = dict()
- for field in self._get_mandatory_fields():
- if field in read_data:
- if not len (read_data [field]):
- missing_fields [field] = 'unset'
- else:
- missing_fields [field] = 'missing'
-
- if len (missing_fields):
- logging.write ("Verification of mandatory fields failed, the result leading to this is: " +
- str (missing_fields) + "\n"
- )
-
- #<raise custom exception>
- raise Exception ("^^^look above")
-
- del field, missing_fields
-
- # add default values
-
- logging.write ( "Fixing data...\n" )
- stats ( read_data )
-
- return read_data
+ if self._verify_read_data ( read_data ):
+ return read_data
+ else:
+ return None
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-26 13:14 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-26 13:14 UTC (permalink / raw
To: gentoo-commits
commit: 503c1170043d7a59ff39741ca740361340c9d508
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat May 26 13:13:45 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat May 26 13:13:45 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=503c1170
roverlay, ebuildcreator: minor changes
---
roverlay/ebuildcreator.py | 80 ++++++++++++++++++++++++++------------------
1 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index 442382e..fa648b8 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -31,23 +31,23 @@ class Ebuild:
"""Initializes an empty Ebuild. This is an object that can be used to
create text lines for an ebuild file."""
- self.name = ''
- self.version = ''
- self.origin = ''
- self.pkg_file = ''
- self.depend = ''
- self.rdepend = ''
- self.rsuggests = ''
- self.description = ''
+ #self.name = ''
+ #self.version = ''
+ #self.origin = ''
+ #self.pkg_file = ''
+ #self.depend = ''
+ #self.rdepend = ''
+ #self.rsuggests = ''
+ #self.description = ''
# temporary var
- self.TODO = ''
+ #self.TODO = ''
# this will be a list of str when exported data have been calculated
self._ebuild_export = None
@classmethod
- def get_ebuild ( self, force_update=False ):
+ def get_ebuild ( self, description_data, force_update=False ):
"""
Wrapper function that returns ebuild 'export' data.
This is a list of str that has no newline chars at the end of each str.
@@ -57,7 +57,7 @@ class Ebuild:
"""
if force_update or (self._ebuild_export is None):
- self._ebuild_export = self._make_export()
+ self._ebuild_export = self._make_export ( description_data )
return self._ebuild_export
@@ -98,10 +98,31 @@ class Ebuild:
# catch failure
return False
+ @classmethod
+ def _make_ebuild_lines ( self, ebuild_content ):
+ ebuild_export = []
+ last_line_empty = False
+ line = None
+
+ # remove repeated newlines ('repoman sez: ...')
+ for line in ebuild_content:
+ line = line.rstrip()
+ if line:
+ last_line_empty = False
+ elif not last_line_empty:
+ last_line_empty = True
+ else:
+ continue
+
+ ebuild_export.append ( line )
+
+ del last_line_empty, line
+ return ebuild_content
+
@staticmethod
- def _get_fileheader ( ebuild_header_file=None ):
+ def _get_ebuild_header ( ebuild_header_file=None ):
"""Reads and returns the content of an ebuild header file.
This is a normal file that can be included in ebuilds.
Every header file will only be read on first access, it's content will
@@ -152,7 +173,7 @@ class Ebuild:
return indent_level * EBUILD_INDENT + varname + '""'
@classmethod
- def _make_export ( self, ebuild_header=None ):
+ def _make_export ( self, description_data, ebuild_header=None ):
"""Creates ebuild data that can be written into stdout or a file
arguments:
@@ -163,13 +184,21 @@ class Ebuild:
# this method is todo
+ if not isinstance (description_data, dict):
+ #todo
+ raise Exception ( "bad description data" )
+
errors = dict()
- ebuild_content = _get_fileheader ( ebuild_header )
+ ebuild_content = Ebuild._get_ebuild_header ( ebuild_header )
# repeated and leading empty lines will be removed later
ebuild_content.append ( "" )
+ # the code below this line does not work
+ return
+ #raise Exception ( "under construction ..." )
+
if self.pkg_file:
ebuild_content.append ( _make_var ( "PKG_FILE" , self.pkg_file ) )
else:
@@ -225,27 +254,10 @@ class Ebuild:
raise Exception ( "^^^missing components for ebuild^^^" )
#return None
- ebuild_export = []
- last_line_empty = False
- line = None
-
- # remove repeated newlines ('repoman sez: ...')
- for line in ebuild_content:
- line = line.rstrip()
- if line:
- last_line_empty = False
- elif not last_line_empty:
- last_line_empty = True
- else:
- continue
-
- ebuild_export.append ( line )
-
-
- del last_line_empty, line, ebuild_content
- return ebuild_export
+ return self._make_ebuild_lines ( ebuild_content )
class EbuildCreator:
+# could move this to Ebuild
@classmethod
def __init__ ( self, description_data ):
@@ -290,6 +302,8 @@ class EbuildCreator:
# <dep resolution here?>
+ ebuild.get_ebuild ( self._description_data )
+
# todo
return None
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-29 17:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-29 17:09 UTC (permalink / raw
To: gentoo-commits
commit: 033f6e38ee070ee1e71563bbc8d3a308604706e0
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue May 29 17:00:56 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue May 29 17:00:56 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=033f6e38
roverlay, fileio: add possibility to ignore packages with unsuitable description data (os type); rename _verify_read_data -> _parse_read_data
modified: fileio.py
---
roverlay/fileio.py | 115 +++++++++++++++++++++++++++++++++++++--------------
1 files changed, 83 insertions(+), 32 deletions(-)
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 6e905b9..5d13cf8 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -49,7 +49,7 @@ class DescriptionReader:
a field listed in DESCRIPTION_FIELD_MAP (any match results in immediate return).
Then, a new iteration over the field map compares field_identifier
with all aliases until the first case-(in)sensitive match (-> immediate return).
- An emptry string will be returned if none of the above searches succeed.
+ None will be returned if none of the above searches succeed.
In other words: this method decides whether a field_identifier will be used and if so,
with which name.
@@ -224,11 +224,13 @@ class DescriptionReader:
package_version = package_version,
)
-
-
@classmethod
- def _verify_read_data ( self, read_data ):
- """Verifies and fixes (e.g. add default values) read data"""
+ def _parse_read_data ( self, read_data ):
+ """Verifies and parses/fixes read data.
+
+ arguments:
+ * read_data -- data from file, will be modified
+ """
def stats ( data ):
"""Temporary function that prints some info about the given data."""
@@ -239,49 +241,92 @@ class DescriptionReader:
logging.write ( "=== end of list ===\n" )
del field
+ def _value_in_strlist ( _val, _list, case_insensitive=True ):
+ """Returns true if value is in the given list."""
+ el = None
+ if case_insensitive:
+ lowval = _val.lower()
+ for el in _list:
+ if el.lower() == lowval:
+ return True
+ del lowval
+ else:
+ for el in _list:
+ if el == _val:
+ return True
+
+ del el
+ return False
+
+
stats ( read_data )
- # "finalize" data
- logging.write ( "Fixing data...\n" )
field = None
- # join values to a single str
+ # insert default values
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+ if not field in read_data and 'default_value' in const.DESCRIPTION_FIELD_MAP [field]:
+ read_data [field] = const.DESCRIPTION_FIELD_MAP [field] ['default_value']
+
+ # join values to a single string
for field in self._get_fields_with_flag ( 'joinValues' ):
if field in read_data.keys():
read_data [field] = ' ' . join ( read_data [field] )
- # verify that all necessary fields have been added and are set
- missing_fields = dict()
+ # ensure that all mandatory fields are set
+ missing_fields = list()
+
for field in self._get_fields_with_flag ( 'mandatory' ):
if field in read_data:
if not len (read_data [field]):
- missing_fields [field] = 'unset'
+ missing_fields.append ( field )
else:
- missing_fields [field] = 'missing'
+ missing_fields.append ( field )
- del field
- if len (missing_fields):
+
+
+ # check for fields that allow only certain values
+ unsuitable_fields = list()
+
+ for field in read_data.keys():
+ # skip _fileinfo
+ if field != '_fileinfo':
+ if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
+ if not _value_in_strlist ( read_data [field],
+ const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
+ ): unsuitable_fields.append ( field )
+
+
+ stats ( read_data )
+
+
+
+ valid = True
+
+ if len ( missing_fields ):
+ valid = False
+
logging.write (
"Verification of mandatory fields failed, the result leading to this was: " +
- str (missing_fields) + "\n"
+ str ( missing_fields ) + "\n"
)
#<raise custom exception>
raise Exception ("^^^look above")
- del missing_fields
+ if len ( unsuitable_fields ):
+ valid = False
- # add/insert default values
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if not field in read_data and 'default_value' in const.DESCRIPTION_FIELD_MAP [field]:
- read_data [field] = const.DESCRIPTION_FIELD_MAP [field] ['default_value']
-
-
- stats ( read_data )
+ logging.write (
+ "Some fields have values that forbid further parsing, the result leading to this was: " +
+ str ( unsuitable_fields ) + "\n"
+ )
- return True
+ del missing_fields
+ del field
+ return valid
@classmethod
def readfile ( self, filepath ):
@@ -296,18 +341,18 @@ class DescriptionReader:
-> split field values
-> filter out unwanted/useless fields
- The return value is a dict "<field name> => <field value[s]>"
- with <field value> as str and <field values> as list.
+ The return value is a dict { fileinfo , description_data } or None if
+ the read data are "useless" (not suited to create an ebuild for it,
+ e.g. if OS_TYPE is not unix).
"""
- read_data = dict (
- _ = DescriptionReader._get_fileinfo ( filepath )
- )
+ read_data = dict ()
+ fileinfo = DescriptionReader._get_fileinfo ( filepath )
try:
desc_lines = DescriptionReader._get_desc_from_file (
- filepath, read_data ['_'] ['package_name']
+ filepath, fileinfo ['package_name']
)
@@ -377,8 +422,14 @@ class DescriptionReader:
del sline, line, val, field_context
- if self._verify_read_data ( read_data ):
- return read_data
+ if self._parse_read_data ( read_data ):
+ logging.write ( '## success ##\n' )
+ logging.write ( ( str ( read_data ) ) )
+ return dict (
+ fileinfo = fileinfo,
+ description_data = read_data
+ )
else:
+ logging.write ( '## fail ##\n' )
return None
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-29 17:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-29 17:09 UTC (permalink / raw
To: gentoo-commits
commit: 2e76c1e480434d43b6be4ade11d6ebd7a7025718
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue May 29 17:06:35 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue May 29 17:06:35 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2e76c1e4
roverlay, ebuildcreator: module that accepts package_files, schedules their processing into jobs and returns ebuilds (but is todo)
modified: ebuildcreator.py
---
roverlay/ebuildcreator.py | 356 +++++++--------------------------------------
1 files changed, 54 insertions(+), 302 deletions(-)
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index fa648b8..f439c71 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -1,350 +1,102 @@
-# R Overlay -- ebuild creation
+# R Overlay -- ebuild creation, "master" module
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# temporary import until logging is implemented
-from sys import stderr as logging
+from roverlay import ebuildjob.EbuildJob
-# temporary import until config and real constants are implemented
-from roverlay import tmpconst as const
-from roverlay.fileio import DescriptionReader
-
-# misc TODO notes:
-# * could use caching via decorators instead of wrappers (-> later)
-# * instead of including the ebuild header in every ebuild 'export' data:
-# ** link that header
-# ** ebuild_export = [ <header_link>, str, [,str]* ]
-#
+class EbuildCreator:
-class Ebuild:
- # could move this to const
- EBUILD_INDENT = "\t"
- # reading every ebuild header file (copyright, inherit <eclass>) once at most
- # <ebuild header file> => [<content of this file>]
- # shared among all ebuilds
- ebuild_headers = dict()
@classmethod
def __init__ ( self ):
- """Initializes an empty Ebuild. This is an object that can be used to
- create text lines for an ebuild file."""
-
- #self.name = ''
- #self.version = ''
- #self.origin = ''
- #self.pkg_file = ''
- #self.depend = ''
- #self.rdepend = ''
- #self.rsuggests = ''
- #self.description = ''
+ """Initializes an EbuildCreator. This is an Object that controls the
+ R package -> ebuild creation. It continuously creates EbuildJobs for
+ every R package added.
+ """
+ self.ebuild_headers = dict ()
+ self.depresolve_main = None # TODO
+ self.ebuild_jobs = []
- # temporary var
- #self.TODO = ''
+ # --- end of init (...) ---
- # this will be a list of str when exported data have been calculated
- self._ebuild_export = None
@classmethod
- def get_ebuild ( self, description_data, force_update=False ):
- """
- Wrapper function that returns ebuild 'export' data.
- This is a list of str that has no newline chars at the end of each str.
+ def add_package ( self, package_file ):
+ """Adds an R package to the EbuildCreator, which means that an EbuildJob
+ will be created for it. Returns the EbuildJob, which is also stored
+ in the job queue.
arguments:
- * force_update -- force calculation of export data
-
+ * package_file -- path R package file
"""
- if force_update or (self._ebuild_export is None):
- self._ebuild_export = self._make_export ( description_data )
+ new_job = EbuildJob ( package_file, self.get_resolver ( False ) )
- return self._ebuild_export
+ self.ebuild_jobs.append ( new_job )
- @classmethod
- def suggest_filename ( self ):
- """Suggests a file name for the ebuild.
- Calculated using ebuild data, but TODO
- """
- # name-version
- return None
+ return new_job
+
+ # --- end of add_package (...) ---
@classmethod
- def write_ebuild ( self, file_to_write, force_update=False ):
- """Writes this ebuild into a file
+ def get_resolver ( self, readonly=True ):
+ """Returns a communication channel to the dependency resolver.
arguments:
- * file_to_write -- path of the file to write (will be overwritten if existent)
- * force_update -- force calculation of ebuild data, don't use cached results
-
- **TODO notes : mkdir -p $(dirname)
+ readonly -- whether the channel is listen-only (no write methods) or not
+ defaults to True
"""
- try:
- # try to get the ebuild lines before opening the file
- line = None
- # append newline here or add in _make_export()
- lines = [ line + "\n" for line in self.get_ebuild ( force_update ) ]
- del line
-
- fh = open ( file_to_write, 'w' )
- fh.writelines ( lines )
- fh.close ()
-
- del lines, fh
- return True
- except IOError as err:
- raise
-
- # catch failure
- return False
-
- @classmethod
- def _make_ebuild_lines ( self, ebuild_content ):
- ebuild_export = []
- last_line_empty = False
- line = None
-
- # remove repeated newlines ('repoman sez: ...')
- for line in ebuild_content:
- line = line.rstrip()
- if line:
- last_line_empty = False
- elif not last_line_empty:
- last_line_empty = True
- else:
- continue
-
- ebuild_export.append ( line )
+ # <TODO>
+ return None
+ #return self.depresolve_main.get_channel()
- del last_line_empty, line
- return ebuild_content
+ # --- end of get_resolver (...) ---
+ @classmethod
+ def run ( self ):
+ """Tells all EbuildJobs to run."""
+ for job in self.ebuild_jobs:
+ job.run()
+ @classmethod
+ def collect_ebuilds ( self ):
+ """Returns all ebuilds. (They may not be ready / TODO)"""
+ return [ job.get_ebuild() for job in self.ebuild_jobs ]
- @staticmethod
- def _get_ebuild_header ( ebuild_header_file=None ):
+ @classmethod
+ def get_ebuild_header ( self, ebuild_header_file=None ):
"""Reads and returns the content of an ebuild header file.
This is a normal file that can be included in ebuilds.
Every header file will only be read on first access, it's content will
- be stored in a dict that is shared among all Ebuild instances.
+ be stored in a dict that is shared among all EbuildCreator instances.
arguments:
- ebuild_header_file -- path to the header file; defaults to none which
- means that nothing will be read and an empty list
- is returned
+ * ebuild_header_file -- path to the header file; defaults to none which
+ means that nothing will be read and an empty list
+ is returned.
"""
+
if ebuild_header_file is None:
# nothing to read
return []
- elif (ebuild_header_file in ebuild_headers):
+ elif ebuild_header_file in self.ebuild_headers:
# previously read
- return ebuild_headers [ebuild_header_file]
+ return self.ebuild_headers [ebuild_header_file]
else:
- # do read
+ # read file
try:
- fh = open (ebuild_header_file, 'rU')
+ fh = open ( ebuild_header_file, 'r' )
lines = fh.readlines()
fh.close()
- ebuild_headers [ebuild_header_file] = lines
- del lines, fh
- return ebuild_headers [ebuild_header_file]
+ self.ebuild_headers [ebuild_header_file] = lines
+ del fh
+ return lines
except IOError as err:
+ # todo
raise
- @staticmethod
- def _make_var ( varname, value=None, indent_level=0 ):
- """Returns a variable definitions that can be used in ebuilds, optionally
- with indention.
-
- arguments:
- * varname -- name of the variable (e.g. DEPEND)
- * value -- value of the variable; an empty var (DEPEND="") will be returned
- if unset (the default)
- * indent_level -- indent var definition by indent_level levels
- """
-
- if value:
- return indent_level * EBUILD_INDENT + varname + '"' + value + '"'
- else:
- # empty var
- return indent_level * EBUILD_INDENT + varname + '""'
-
- @classmethod
- def _make_export ( self, description_data, ebuild_header=None ):
- """Creates ebuild data that can be written into stdout or a file
-
- arguments:
- ebuild_header_file -- path to the header file; defaults to none which
- means that nothing will be read and an empty list
- is returned
- """
-
- # this method is todo
-
- if not isinstance (description_data, dict):
- #todo
- raise Exception ( "bad description data" )
-
- errors = dict()
-
- ebuild_content = Ebuild._get_ebuild_header ( ebuild_header )
-
- # repeated and leading empty lines will be removed later
- ebuild_content.append ( "" )
-
- # the code below this line does not work
- return
- #raise Exception ( "under construction ..." )
-
- if self.pkg_file:
- ebuild_content.append ( _make_var ( "PKG_FILE" , self.pkg_file ) )
- else:
- # absense of a pkg source file is an error
- errors ['PKG_FILE'] = "missing"
-
- if self.origin:
- ebuild_content.append ( _make_var ( "PKG_ORIGIN", self.origin ) )
- else:
- errors ['PKG_ORIGIN'] = "missing"
-
- ebuild_content.append ( "" )
-
- if self.description:
- ebuild_content.append ( _make_var ( "DESCRIPTION", self.TODO ) )
- else:
- ebuild_content.append ( _make_var ( "DESCRIPTION", "<none>" ) )
- #errors ['DESCRIPTION'] = "missing"
-
- # determine SRC_URI (origin + pkg_file)
- if self.pkg_file and self.origin and False:
- # SRC_URI ~= <> + origin + pkg_file
- ebuild_content.append ( _make_var ( "SRC_URI", "" ) )
- else:
- # either RESTRICT+=" fetch" or treat missing SRC_URI as critical
- errors ['SRC_URI'] = "missing"
-
- ebuild_content.append ( "" )
-
- #LICENSE (!!)
-
- rdepend = '${DEPEND:-} ' + self.rdepend
-
- # inherit IUSE from eclass
- iuse = '${IUSE:-}'
-
- if self.rsuggests:
- iuse += ' R_suggests'
- rdepend += ' R_suggests ? ${R_SUGGESTS}'
- ebuild_content.append ( _make_var ( "R_SUGGESTS", self.rsuggests ) )
-
- ebuild_content.append ( _make_var ( "IUSE", iuse ) )
- ebuild_content.append ( "" )
-
- # DEPEND="${DEPEND:-} <pkg dependencies>" to inherit deps from eclass
- ebuild_content.append ( _make_var (
- "DEPEND", '${DEPEND:-} ' + self.depend ) )
-
- ebuild_content.append ( _make_var ( "RDEPEND", rdepend ) )
-
- # (!!) TODO
- if errors:
- raise Exception ( "^^^missing components for ebuild^^^" )
- #return None
-
- return self._make_ebuild_lines ( ebuild_content )
-
-class EbuildCreator:
-# could move this to Ebuild
-
- @classmethod
- def __init__ ( self, description_data ):
- """"Initializes an EbuildCreator.
- [todo]
- """
- self._description_data = description_data
-
- self._ebuild = None
-
- @classmethod
- def run ( self ):
- """Tells this EbuildCreator to operate which produces an Ebuild object
- that can later be shown or written into a file.
- """
- #todo
- self._ebuild = None
-
- if self._description_data is None:
- return False
-
- ebuild = Ebuild()
- dref = self._description_data
-
- ebuild.name = dref ['Package']
- ebuild.version = dref ['Version']
-
- ebuild.origin = "TODO"
- ebuild.pkg_file = "TODO"
-
- # depend rdepend rsuggest
- ebuild.depend = "TODO"
- ebuild.rdepend = "TODO"
- ebuild.suggest = "TODO"
-
- if 'Description' in dref:
- ebuild.description = dref ['Description']
- elif 'Title' in dref:
- ebuild.description = dref ['Title']
- else:
- ebuild.description = "<none>"
-
- # <dep resolution here?>
-
- ebuild.get_ebuild ( self._description_data )
-
- # todo
- return None
-
-
- @classmethod
- def show ( self ):
- """Prints the ebuild to stdout/err or into log"""
- pass
-
- @classmethod
- def write ( self ):
- """Writes the ebuild into a file"""
- pass
-
- @classmethod
- def ready ( self ):
- """Returns true if an Ebuild has been produced, else false."""
- return not (self._ebuild is None)
-
-
-class EbuildFactory:
-
- @classmethod
- def __init__ ( self ):
- """Initializes an ebuild factory. This continously produces EbuildCreator
- for every get_ebuild_creator ( tarball ) call.
- """
- self.desc_reader = DescriptionReader()
-
- @classmethod
- def get_ebuild_creator ( self, tarball ):
- """Creates and returns an ebuild creator that will handle
- the data retrieved from <tarball>.
-
- arguments:
- * tarball -- tarball to read
- """
- data = self.desc_reader.readfile ( tarball )
- if data:
- return EbuildCreator ( data )
- else:
- return None
-
-
+ # --- end of get_ebuild_header (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-29 17:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-29 17:09 UTC (permalink / raw
To: gentoo-commits
commit: 205a0fe164142e4b9c2328672e27f98b9b76a013
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue May 29 17:03:10 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue May 29 17:03:10 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=205a0fe1
temporary files, tmpconst: add allowed_values
---
roverlay/tmpconst.py | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/roverlay/tmpconst.py b/roverlay/tmpconst.py
index 3f10aaa..8519aad 100644
--- a/roverlay/tmpconst.py
+++ b/roverlay/tmpconst.py
@@ -15,7 +15,8 @@ DESCRIPTION_LIST_SPLIT_REGEX = '\s*[,;]{1}\s*'
DESCRIPTION_FILE_NAME = 'DESCRIPTION'
-DESCRIPTION_VALID_OS_TYPES = [ "unix" ]
+# moved to <field> -> 'allowed_values'
+##DESCRIPTION_VALID_OS_TYPES = [ "unix" ]
# note for 2012-05-25: make this struct more organized, assign real values
@@ -99,6 +100,7 @@ DESCRIPTION_FIELD_MAP = {
'alias' : {
'nocase' : [ 'OS_TYPE' ]
},
+ 'allowed_values' : [ 'unix' ],
},
'test-default' : {
'default_value' : 'some default value'
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-29 17:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-29 17:09 UTC (permalink / raw
To: gentoo-commits
commit: a60a7f76d1a2dd2d5f4d1bb3d9766a2e803f2655
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue May 29 17:03:43 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue May 29 17:03:43 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a60a7f76
roverlay, ebuild creation: Ebuild.py
* module that produces ebuild text lines
new file: ebuild.py
---
roverlay/ebuild.py | 335 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 335 insertions(+), 0 deletions(-)
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
new file mode 100644
index 0000000..495b189
--- /dev/null
+++ b/roverlay/ebuild.py
@@ -0,0 +1,335 @@
+# R Overlay -- ebuild creation, ebuild class
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+class Ebuild:
+ # could move this to const
+ EBUILD_INDENT = "\t"
+
+ @classmethod
+ def __init__ ( self ):
+ """Initializes an Ebuild.
+ This is an abstraction layer between the verified + calculated data
+ and the ebuild data, which can be written into a file / stdout / stdin.
+ Most functions here assume that everything is fine when it reaches them.
+ """
+
+ # elements in ebuild_data are either a str or a list of str
+ self._data = dict ()
+ self._ebuild_lines = None
+
+ # --- end of __init__ (...) ---
+
+ @classmethod
+ def cleanup ( self ):
+ """Removes stored data if ebuild_lines have already been calculated.
+ This saves some memory but makes this Ebuild read-only.
+ """
+ if self._ebuild_lines:
+ del self._data
+ self._data = None
+
+ # --- end of cleanup (...) ---
+
+ @classmethod
+ def prepare ( self, force_update=False, cleanup_after=False ):
+ """Tells this Ebuild to create ebuild lines.
+
+ arguments:
+ * force_update -- create ebuild lines if they exist; defaults to False
+ and ignored if this Ebuild has been cleaned up
+ * cleanup_after -- run cleanup() after successful creation
+
+ Returns True if ebuild_lines have been created or if they exist and
+ an update has not been enforced. Else returns False.
+ """
+ if self._ebuild_lines and not force_update:
+ return True
+ elif self._data:
+ self._ebuild_lines = self._make_ebuild_lines()
+ if self._ebuild_lines:
+ if cleanup_after: self.cleanup()
+ return True
+ elif self._ebuild_lines:
+ # self._data is None
+ return True
+
+
+ return False
+
+ # --- end of prepare (...) ---
+
+ @classmethod
+ def add ( self, key, value, append=True ):
+ """Adds data to this Ebuild.
+
+ arguments:
+ * key -- identifier of the data (e.g. DEPEND).
+ May be remapped here (e.g. merging 'Title' and 'Description')
+ * value --
+ * append -- whether to append values or overwrite existing ones,
+ defaults to True.
+
+ raises: Exception when ebuild data are readonly
+ """
+ if self._data is None:
+ # -- todo
+ raise Exception ("Ebuild data are readonly.")
+
+ if append and key in self._data:
+ if isinstance ( self._data [key], list ):
+ self._data [key].extend ( value )
+ else:
+ self._data [key] = [ self._data [key] ].extend ( value )
+
+ else:
+ self._data [key] = value
+
+ # --- end of add (...) ---
+
+ @classmethod
+ def write ( self, file_to_write ):
+ """Writes an ebuild file.
+
+ arguments:
+ * file_to_write -- path to the file that should be written
+ """
+ # prepare ebuild lines and open file handle after that
+ if self.prepare ( False, False ):
+ try:
+ fh = open ( file_to_write, 'w' )
+ self.show ( fh )
+ fh.close()
+ del fh
+ return True
+ except IOError as err:
+ # ? todo
+ raise
+
+ else:
+ # todo log this
+ raise Exception ("cannot write ebuild")
+
+ # --- end of write (...) ---
+
+ @classmethod
+ def show ( self, file_handle ):
+ """Prints the ebuild content into a file_handle.
+
+ arguments:
+ file_handle -- object that has a writelines ( list ) method, e.g. file.
+
+ Returns True if writing was successful, else False.
+ """
+ if self.prepare ( False, False ):
+ lines = [ line + "\n" for line in self._ebuild_lines ]
+ file_handle.writelines ( lines )
+ del lines
+ return True
+ else:
+ return False
+
+ # --- end of show (...) ---
+
+ def suggest_name ( self, fallback_name=None ):
+ """Suggests a file name for the ebuild. This is calculated using
+ pkg_name/version/revision. Returns a fallback_name if this is not
+ possible.
+
+ arguments:
+ fallback_name -- name to return if no suggestion available, defaults to None
+ """
+
+ if 'pkg_name' in self._data and 'pkg_version' in self._data:
+ join = [ 'pkg_name' , 'pkg_version' ]
+ if 'pkg_revision' in self._data: join.append ('pkg_revision')
+
+ return '-' . join ( [ self._data [c] for c in join ] )
+
+ else:
+ return fallback_name
+
+ # --- end of suggest_name (...) ---
+
+ @classmethod
+ def _make_ebuild_lines ( self ):
+ """Creates text lines for this Ebuild.
+ It assumes that enough data to do this are available. Exceptions (KeyError, NameError, ...)
+ are passed if that's not the case.
+ """
+
+ def get_dep_and_use():
+ """Creates values for the DEPEND, RDEPEND, IUSE and, if possible,
+ R_SUGGESTS variables and returns them as dict { VARNAME -> VALUE }.
+ """
+
+ # have suggests if they're set and not empty
+ have_suggests = bool ( 'RSUGGESTS' in self._data and self._data ['RSUGGESTS'] )
+
+ # set defaults: inherit eclass + include depend in rdepend
+ ret = dict (
+ DEPEND = [ '${DEPEND:-}' ],
+ RDEPEND = [ '${DEPEND:-}', '${RDEPEND:-}' ],
+ IUSE = [ '${IUSE:-}' ],
+ )
+
+ if 'DEPEND' in self._data:
+ ret ['DEPEND'].extend ( self._data ['DEPEND'] )
+
+ if 'RDEPEND' in self._data:
+ ret ['RDEPEND'].extend ( self._data ['RDEPEND'] )
+
+ if have_suggests:
+ ret ['R_SUGGESTS'] = self._data ['R_SUGGESTS']
+
+ # +R_SUGGESTS, -R_SUGGESTS?
+ ret ['IUSE'].append ( 'R_suggests' )
+ # do these braces help or confuse? TODO FIXME
+ ret ['RDEPEND'].append ( '( R_suggests ? ${R_SUGGESTS} )' )
+
+ return ret
+
+ # --- end of get_dep_and_use () ---
+
+ def make_var ( varname, value=None, oneline_list=True, indent_list=True, indent_level=0 ):
+ """Creates a <name>=<value> statement for ebuilds.
+
+ arguments:
+ * varname -- name of the variable
+ * value -- value of the variable. This has to be either None (the default),
+ str, or list of str.
+ * oneline_list -- if value is a list: controls whether it's components should be
+ put into one line (True) or multiple (False). Defaults to True.
+ * indent_list -- if value is a list and not oneline_list:
+ controls whether each value line should be indentend
+ (by indent_level + 1) or not ("by 0"). Defaults to True.
+ * indent_level -- current indentation level, defaults to 0
+
+ """
+
+ # assumption: value is either None, scalar with str representation or list of str
+ var_value = None
+
+ if not value:
+ var_value = ""
+
+ elif isinstance ( value, list ):
+ if oneline_list:
+ var_value = ' '.join ( value )
+ elif indent_list:
+ var_value = ('\n' + (indent_level + 1) * EBUILD_INDENT).join ( value )
+ else:
+ '\n'.join ( value )
+
+ else:
+ var_value = str ( value )
+
+ return indent_level * EBUILD_INDENT + varname + '"' + value_str + '"'
+
+ # --- end of make_var (...) ---
+
+ def remove_newlines ( line_list ):
+ """
+ Removes leading, ending and repeated empty/whitespace lines in line_list.
+
+ arguments:
+ * line_list
+ """
+ lines = []
+ line = None
+ last_line_empty = False
+
+ for line in line_list:
+ line = line.rstrip()
+ # re.sub \n{2,} \n :: FIXME?
+
+ if line:
+ last_line_empty = False
+ elif not last_line_empty:
+ last_line_empty = True
+ else:
+ continue
+
+ lines.append ( line )
+
+ # remove last line if empty
+ ##if last_line_empty: (?)
+ if len ( lines ) and not lines [-1]:
+ del lines [-1]
+
+ return lines
+
+ # --- end of remove_newlines (...) ---
+
+ def add_easyvar ( ebuild_content, varname, value_key=None, add_newline=False):
+ """Adds a 'simple' variable to the ebuild lines. This means that it
+ can directly be taken from self._data [value_key]. This method assumes
+ that value_key exists in self._data, any exceptions (KeyError) will be passed.
+
+ arguments:
+ * ebuild_content -- list of ebuild text lines, will be modified directly,
+ so copy it before calling addvar if you need the original list.
+ * varname -- name of the variable. Nothing happens if this is None.
+ * value_key -- key of the value, defaults to varname if it is None
+ * add_newline -- adds a newline after the var statement, defaults to False
+
+ Returns given list (ebuild_content), which will then have been modified.
+ """
+
+ if not varname is None:
+ if value_key is None:
+ ebuild_content.append ( make_var ( varname, self._data [varname] ) )
+ else:
+ ebuild_content.append ( make_var ( varname, self._data [value_key] ) )
+
+ if add_newline:
+ ebuild_content.append ( "" )
+
+ return ebuild_content
+
+ # --- end of add_easyvar (...) ---
+
+ try:
+ ebuild_lines = []
+
+ if 'ebuild_header' in self._data:
+ ebuild_lines = self._data ['ebuild_header']
+ ebuild_lines.append ( "" )
+
+ add_easyvar ( ebuild_lines, "PKG_FILE" )
+ if 'PKG_ORIGIN' in self._data:
+ add_easyvar ( ebuild_lines, "PKG_ORIGIN", None, True )
+
+ add_easyvar ( ebuild_lines, "DESCRIPTION" )
+
+ if 'SRC_URI' in self._data:
+ add_easyvar ( ebuild_lines, "SRC_URI" )
+ else:
+ # > calculate SRC_URI using self._data ['origin']
+ ebuild_lines.append ( make_var ( "SRC_URI" , None ) )
+ # (temporary, todo) setting restrict to fetch
+ ebuild_lines.append ( make_var ( "RESTRICT" , "fetch" ) )
+
+ ebuild_lines.append ( "" )
+
+ # LICENSE ?
+
+ dep_and_use = get_dep_and_use ()
+
+ ebuild_lines.append ( make_var ( "IUSE", dep_and_use ['IUSE'], True ) )
+
+ if 'R_SUGGESTS' in dep_and_use:
+ ebuild_lines.append ( make_var ( "R_SUGGESTS", dep_and_use ['R_SUGGESTS'], False ) )
+
+ ebuild_lines.append ( make_var ( "DEPEND", dep_and_use ['DEPEND'], False ) )
+ ebuild_lines.append ( make_var ( "RDEPEND", dep_and_use ['RDEPEND'], False ) )
+
+ del dep_and_use
+ return remove_newlines ( ebuild_lines )
+
+ except Exception as err:
+ # log this
+ ## ..
+ raise
+
+ # --- end of make_ebuild_lines (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-29 17:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-29 17:09 UTC (permalink / raw
To: gentoo-commits
commit: 583cc5d1d5d4c98754cde003d70a22bfe0a07f79
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue May 29 17:08:22 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue May 29 17:08:22 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=583cc5d1
roverlay, ebuildjob: module that reads a package file and creates an ebuild for it
new file: ebuildjob.py
---
roverlay/ebuildjob.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
new file mode 100644
index 0000000..0861b22
--- /dev/null
+++ b/roverlay/ebuildjob.py
@@ -0,0 +1,65 @@
+# R Overlay -- ebuild creation, "job" module
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from roverlay import ebuildcreator.EbuildCreator
+from roverlay import fileio.DescriptionReader
+from roverlay import ebuild.Ebuild
+
+class EbuildJob:
+
+ @classmethod
+ def __init__ ( self, package_file, dep_resolver=None ):
+ self.package_file = package_file
+ self.dep_resolver = dep_resolver
+ # get description reader from args?
+ self.description_reader = DescriptionReader()
+ self.ebuild = Ebuild()
+
+ self.status = 0 # todo
+
+
+ @classmethod
+ def status ( self, expected_status=None ):
+ """Returns the current status of this job or a bool that indicates
+ whether to current status matches the expected one.
+
+ arguments:
+ * expected_status -- if not None: check if this job's state is expected_status
+ """
+ if expected_status:
+ return self.status
+ else:
+ return bool ( self.status == expected_status )
+
+ @classmethod
+ def get_ebuild ( self ):
+ """Returns the Ebuild that is created by this object. Note that you should
+ check the status with status ( $TODO::EBUILD_READY ) before trying to use
+ the Ebuild.
+ """
+ return self.ebuild
+
+
+ @classmethod
+ def run ( self ):
+ """Tells this EbuildJob to run. This means that it reads the package file,
+ resolves dependencies (TODO) and creates an Ebuild object that is ready
+ to be written into a file.
+ """
+
+ # check status
+ ##
+
+ read_data = self.description_reader.readfile ( self.package_file )
+
+ if read_data is None
+ # set status accordingly
+ return None
+
+ # transfer data from read_data to self.ebuild
+ # have to resolve deps here
+ # <TODO>
+
+ return None
+
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 10:58 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 10:58 UTC (permalink / raw
To: gentoo-commits
commit: a432eb5c70a8d3108faa40a4725f6b2d531fc881
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 10:55:50 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 10:58:23 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a432eb5c
roverlay, ebuildcreator: fix imports, collect_ebuilds() returns only not None ebuilds now
---
roverlay/ebuildcreator.py | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index f439c71..f6935a8 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -2,8 +2,7 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from roverlay import ebuildjob.EbuildJob
-
+from roverlay.ebuildjob import EbuildJob
class EbuildCreator:
@@ -62,7 +61,8 @@ class EbuildCreator:
@classmethod
def collect_ebuilds ( self ):
"""Returns all ebuilds. (They may not be ready / TODO)"""
- return [ job.get_ebuild() for job in self.ebuild_jobs ]
+ ebuilds = [ job.get_ebuild() for job in self.ebuild_jobs ]
+ return [ ebuild for ebuild in ebuilds if (not ebuild is None) ]
@classmethod
def get_ebuild_header ( self, ebuild_header_file=None ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 10:58 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 10:58 UTC (permalink / raw
To: gentoo-commits
commit: 46138bd3fb3e24a9144bf93355cc47b9fe222d92
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 10:55:03 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 10:58:13 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=46138bd3
roverlay, fileio: include package_file in file info
modified: fileio.py
---
roverlay/fileio.py | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 5d13cf8..41aad23 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -219,8 +219,9 @@ class DescriptionReader:
return dict (
filepath = filepath,
filename = filename,
- #package_file = package_file,
+ package_file = package_file,
package_name = package_name,
+ #package_origin = ?,
package_version = package_version,
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 10:58 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 10:58 UTC (permalink / raw
To: gentoo-commits
commit: c2cba20189488dbf0b0419dddb94176963e054e3
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 10:54:31 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 10:54:31 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c2cba201
roverlay, ebuild: fix list.append() / list.extend()
modified: ebuild.py
---
roverlay/ebuild.py | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index 495b189..88dbde6 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -77,10 +77,13 @@ class Ebuild:
raise Exception ("Ebuild data are readonly.")
if append and key in self._data:
- if isinstance ( self._data [key], list ):
+ if not isinstance ( self._data [key], list ):
+ self._data [key] = [ self._data [key] ]
+
+ if isinstance ( value, list ):
self._data [key].extend ( value )
else:
- self._data [key] = [ self._data [key] ].extend ( value )
+ self._data [key].append ( value )
else:
self._data [key] = value
@@ -173,11 +176,22 @@ class Ebuild:
IUSE = [ '${IUSE:-}' ],
)
+ tmp = None
+
if 'DEPEND' in self._data:
- ret ['DEPEND'].extend ( self._data ['DEPEND'] )
+ # todo: search if there is a extend method that does not split string into chars
+ tmp = self._data ['DEPEND']
+ if isinstance ( tmp, list ):
+ ret ['DEPEND'].extend ( tmp )
+ else:
+ ret ['DEPEND'].append ( tmp )
if 'RDEPEND' in self._data:
- ret ['RDEPEND'].extend ( self._data ['RDEPEND'] )
+ tmp = self._data ['RDEPEND']
+ if isinstance ( tmp, list ):
+ ret ['RDEPEND'].extend ( tmp )
+ else:
+ ret ['RDEPEND'].append ( tmp )
if have_suggests:
ret ['R_SUGGESTS'] = self._data ['R_SUGGESTS']
@@ -217,14 +231,14 @@ class Ebuild:
if oneline_list:
var_value = ' '.join ( value )
elif indent_list:
- var_value = ('\n' + (indent_level + 1) * EBUILD_INDENT).join ( value )
+ var_value = ('\n' + (indent_level + 1) * Ebuild.EBUILD_INDENT).join ( value )
else:
'\n'.join ( value )
else:
var_value = str ( value )
- return indent_level * EBUILD_INDENT + varname + '"' + value_str + '"'
+ return indent_level * Ebuild.EBUILD_INDENT + varname + '="' + var_value + '"'
# --- end of make_var (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 10:58 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 10:58 UTC (permalink / raw
To: gentoo-commits
commit: d42aeffc50fdee5f835b06910f0792ba079e4ddc
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 10:56:32 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 10:58:23 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d42aeffc
roverlay, ebuildjob: fix imports, run () creates an ebuild now
---
roverlay/ebuildjob.py | 105 ++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 90 insertions(+), 15 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 0861b22..171150c 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -2,11 +2,12 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from roverlay import ebuildcreator.EbuildCreator
-from roverlay import fileio.DescriptionReader
-from roverlay import ebuild.Ebuild
+from roverlay.fileio import DescriptionReader
+from roverlay.ebuild import Ebuild
class EbuildJob:
+ STATUS_LIST = [ 'INIT', 'BUSY', 'WAIT', 'SUCCESS', 'FAIL' ]
+ STATUS_MAP = dict ( ( name, code ) for code, name in enumerate ( STATUS_LIST ) )
@classmethod
def __init__ ( self, package_file, dep_resolver=None ):
@@ -14,10 +15,26 @@ class EbuildJob:
self.dep_resolver = dep_resolver
# get description reader from args?
self.description_reader = DescriptionReader()
- self.ebuild = Ebuild()
- self.status = 0 # todo
+ self.ebuild = None
+ self._status = 0 # todo
+
+ # --- end of __init__ (...) ---
+
+ @staticmethod
+ def get_statuscode ( status_id ):
+ if status_id == 'ALL':
+ return EbuildJob.STATUS_LIST
+ elif isinstance ( status_id, int ):
+ if status_id > 0 and status_id < len ( STATUS_LIST ):
+ return EbuildJob.STATUS_LIST [status_id]
+ elif status_id in EbuildJob.STATUS_MAP:
+ return EbuildJob.STATUS_MAP [status_id]
+
+ return None
+
+ # --- end of get_statuscode (...) ---
@classmethod
def status ( self, expected_status=None ):
@@ -28,18 +45,35 @@ class EbuildJob:
* expected_status -- if not None: check if this job's state is expected_status
"""
if expected_status:
- return self.status
- else:
- return bool ( self.status == expected_status )
+ if isinstance ( expected_status, int ):
+ return bool ( self._status == expected_status )
+ elif expected_status in EbuildJob.STATUS_MAP:
+ return bool ( self._status == EbuildJob.STATUS_MAP [expected_status] )
+ else:
+ return False
+
+ return self._status
+
+ # --- end of status (...) ---
@classmethod
def get_ebuild ( self ):
"""Returns the Ebuild that is created by this object. Note that you should
check the status with status ( $TODO::EBUILD_READY ) before trying to use
the Ebuild.
+ ##fixme: it is guaranteed that self.ebuild is None unless the Ebuild is successfully created##
"""
return self.ebuild
+ # --- end of get_ebuild (...) ---
+
+ @classmethod
+ def _set_status ( self, new_status ):
+ self._status = EbuildJob.get_statuscode ( new_status )
+ return True
+
+ # --- end of _set_status (...) ---
+
@classmethod
def run ( self ):
@@ -49,17 +83,58 @@ class EbuildJob:
"""
# check status
- ##
+ if not self.status ( 'INIT' ):
+ return
+
+ if not self._set_status ( 'BUSY' ):
+ return False
read_data = self.description_reader.readfile ( self.package_file )
- if read_data is None
+ if read_data is None:
# set status accordingly
- return None
+ self._set_status ( 'FAIL' )
+ return False
- # transfer data from read_data to self.ebuild
- # have to resolve deps here
- # <TODO>
+ fileinfo = read_data ['fileinfo']
+ desc = read_data ['description_data']
+
+ ebuild = Ebuild()
+
+ have_description = False
+
+ print ( str ( desc ) )
+
+ if 'Title' in desc:
+ have_description = True
+ ebuild.add ( 'DESCRIPTION', desc ['Title'] )
+
+ if 'Description' in desc:
+ have_description = True
+ ebuild.add ( 'DESCRIPTION', ( '// ' if have_description else '' ) + desc ['Description'] )
+
+ if not have_description:
+ ebuild.add ( 'DESCRIPTION', '<none>' )
+ del have_description
+
+ # origin is todo (sync module knows the package origin)
+ ebuild.add ( 'PKG_ORIGIN', 'CRAN' )
+
+ ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] )
+
+ ebuild.add ( 'ebuild_header', [ '# test header' ], False )
+
+ ## have to resolve deps here
+
+ # enter status that allows transferring ebuild -> self.ebuild
+ if self._set_status ( 'WAIT' ):
+ # finalize self.ebuild: forced text creation + make it readonly
+ if ebuild.prepare ( True, True ):
+ self.ebuild = ebuild
+ return self._set_status ( 'SUCCESS' )
+
+ self._set_status ( 'FAIL' )
+ return False
- return None
+ # --- end of run (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 16:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 16:09 UTC (permalink / raw
To: gentoo-commits
commit: efc87322e3016a5178feb579b468ff44d8cc0b04
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 14:54:28 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 14:54:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=efc87322
roverlay, ebuildjob: status code and dep resolve logic
modified: ebuildjob.py
---
roverlay/ebuildjob.py | 260 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 181 insertions(+), 79 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 171150c..d45dfdf 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -6,11 +6,42 @@ from roverlay.fileio import DescriptionReader
from roverlay.ebuild import Ebuild
class EbuildJob:
- STATUS_LIST = [ 'INIT', 'BUSY', 'WAIT', 'SUCCESS', 'FAIL' ]
- STATUS_MAP = dict ( ( name, code ) for code, name in enumerate ( STATUS_LIST ) )
+ # move this to const / config
+ DEPENDENCY_FIELDS = {
+ 'R_SUGGESTS' : [ 'Suggests' ],
+ 'DEPENDS' : ['Depends', 'Imports' ],
+ 'RDEPENDS' : [ 'LinkingTo', 'SystemRequirements' ]
+ }
+
+ ##
+
+
+ STATUS_LIST = [ 'INIT', 'BUSY', 'WAIT_RESOLVE', 'SUCCESS', 'FAIL' ]
+
+ # status 'jump' control
+ # FAIL is always allowed, S -> S has to be explicitly allowed
+ STATUS_BRANCHMAP = dict (
+ INIT = [ 'BUSY' ],
+ BUSY = [ 'BUSY', 'WAIT_RESOLVE', 'SUCCESS' ],
+ WAIT_RESOLVE = [ 'BUSY' ],
+ SUCCESS = [],
+ FAIL = [],
+ )
@classmethod
def __init__ ( self, package_file, dep_resolver=None ):
+ """Initializes an EbuildJob, which creates an ebuild for an R package.
+
+ arguments:
+ * package_file -- path to the R package file
+ * dep_resolver -- dependency resolver
+ """
+
+ """Note:
+ it is intended to run this job as thread, that's why it has its own
+ dep resolver 'communication channel', status codes etc.
+ """
+
self.package_file = package_file
self.dep_resolver = dep_resolver
# get description reader from args?
@@ -18,44 +49,10 @@ class EbuildJob:
self.ebuild = None
- self._status = 0 # todo
+ self.status = 'INIT'
# --- end of __init__ (...) ---
- @staticmethod
- def get_statuscode ( status_id ):
- if status_id == 'ALL':
- return EbuildJob.STATUS_LIST
- elif isinstance ( status_id, int ):
- if status_id > 0 and status_id < len ( STATUS_LIST ):
- return EbuildJob.STATUS_LIST [status_id]
- elif status_id in EbuildJob.STATUS_MAP:
- return EbuildJob.STATUS_MAP [status_id]
-
- return None
-
- # --- end of get_statuscode (...) ---
-
- @classmethod
- def status ( self, expected_status=None ):
- """Returns the current status of this job or a bool that indicates
- whether to current status matches the expected one.
-
- arguments:
- * expected_status -- if not None: check if this job's state is expected_status
- """
- if expected_status:
- if isinstance ( expected_status, int ):
- return bool ( self._status == expected_status )
- elif expected_status in EbuildJob.STATUS_MAP:
- return bool ( self._status == EbuildJob.STATUS_MAP [expected_status] )
- else:
- return False
-
- return self._status
-
- # --- end of status (...) ---
-
@classmethod
def get_ebuild ( self ):
"""Returns the Ebuild that is created by this object. Note that you should
@@ -68,73 +65,178 @@ class EbuildJob:
# --- end of get_ebuild (...) ---
@classmethod
- def _set_status ( self, new_status ):
- self._status = EbuildJob.get_statuscode ( new_status )
- return True
+ def get_status ( self, expected_status=None ):
+ """Returns the current status of this job or a bool that indicates
+ whether to current status matches the expected one.
- # --- end of _set_status (...) ---
+ arguments:
+ * expected_status -- if not None: check if this job's state is expected_status
+ """
+ if not expected_status is None:
+ return bool ( self.status == expected_status )
+ else:
+ return self.status
+
+ # --- end of get_status (...) ---
+
+ @classmethod
+ def done_success ( self ):
+ """Returns True if this has been successfully finished."""
+ return get_status ( 'SUCCESS' )
+
+ # --- end of done_success (...) ---
@classmethod
def run ( self ):
"""Tells this EbuildJob to run. This means that it reads the package file,
- resolves dependencies (TODO) and creates an Ebuild object that is ready
- to be written into a file.
+ resolves dependencies using its resolver (TODO) and creates
+ an Ebuild object that is ready to be written into a file.
"""
- # check status
- if not self.status ( 'INIT' ):
- return
+ # TODO move hardcoded entries to config/const
- if not self._set_status ( 'BUSY' ):
- return False
+ try:
- read_data = self.description_reader.readfile ( self.package_file )
+ # set status or return
+ if not self._set_status ( 'BUSY', True ): return
- if read_data is None:
- # set status accordingly
- self._set_status ( 'FAIL' )
- return False
+ read_data = self.description_reader.readfile ( self.package_file )
- fileinfo = read_data ['fileinfo']
- desc = read_data ['description_data']
+ if read_data is None:
+ # set status accordingly
+ self._set_status ( 'FAIL' )
+ return
- ebuild = Ebuild()
+ fileinfo = read_data ['fileinfo']
+ desc = read_data ['description_data']
- have_description = False
+ ebuild = Ebuild()
- print ( str ( desc ) )
+ have_description = False
- if 'Title' in desc:
- have_description = True
- ebuild.add ( 'DESCRIPTION', desc ['Title'] )
+ if 'Title' in desc:
+ ebuild.add ( 'DESCRIPTION', desc ['Title'] )
+ have_description = True
- if 'Description' in desc:
- have_description = True
- ebuild.add ( 'DESCRIPTION', ( '// ' if have_description else '' ) + desc ['Description'] )
+ if 'Description' in desc:
+ ebuild.add ( 'DESCRIPTION', ( '// ' if have_description else '' ) + desc ['Description'] )
+ #have_description=True
- if not have_description:
- ebuild.add ( 'DESCRIPTION', '<none>' )
- del have_description
- # origin is todo (sync module knows the package origin)
- ebuild.add ( 'PKG_ORIGIN', 'CRAN' )
+ # origin is todo (sync module knows the package origin)
+ ebuild.add ( 'PKG_ORIGIN', 'CRAN' )
- ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] )
+ ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] )
- ebuild.add ( 'ebuild_header', [ '# test header' ], False )
+ ebuild.add ( 'ebuild_header',
+ [ '# test header, first line\n',
+ '# test header, second line\n\n\n\n',
+ '#third\n\n#fifth' ],
+ False
+ )
- ## have to resolve deps here
+ if self.dep_resolver and self.dep_resolver.enabled():
- # enter status that allows transferring ebuild -> self.ebuild
- if self._set_status ( 'WAIT' ):
- # finalize self.ebuild: forced text creation + make it readonly
+ # collect depdencies from desc and add them to the resolver
+ raw_depends = dict ()
+
+ dep_type = field = None
+
+ for dep_type in EbuildJob.DEPENDENCY_FIELDS.keys():
+
+ raw_depends [dep_type] = []
+
+ for field in EbuildJob.DEPENDENCY_FIELDS [dep_type]:
+
+ if field in desc:
+ if isinstance ( desc [field], list ):
+ raw_depends.extend ( desc [field] )
+ self.dep_resolver.add_dependencies ( desc [field] )
+
+ else:
+ raw_depends.append ( desc [field] )
+ self.dep_resolver.add_depency ( desc [field] )
+
+ del field, dep_type
+
+
+ while not self.dep_resolver.done():
+
+ if not self._set_status ( 'WAIT_RESOLVE' ): return
+
+ # tell the resolver to run (again)
+ self.dep_resolver.run()
+
+ if not self._set_status ( 'BUSY' ): return
+
+ if self.dep_resolver.satisfy_request():
+
+ dep_type = dep_str = dep = None
+
+ # dependencies resolved, add them to the ebuild
+ for dep_type in raw_depends.keys():
+
+ for dep_str in raw_depends [dep_type]:
+ # lookup (str) should return a str here
+ dep = self.dep_resolver.lookup ( dep_str )
+ if dep is None:
+ raise Exception (
+ "dep_resolver is broken: lookup() returns None but satisfy_request() says ok."
+ )
+ else:
+ # add depencies in append mode
+ dep = self.dep_resolver.lookup ( dep_str )
+ ebuild.add ( dep_type,
+ self.dep_resolver.lookup ( dep_str ),
+ True
+ )
+
+ del dep, dep_str, dep_type
+
+ # tell the dep resolver that we're done here
+ self.dep_resolver.close()
+
+ else:
+ # ebuild is not creatable, set status to FAIL and close dep resolver
+ self._set_status ( 'FAIL' )
+ self.dep_resolver.close()
+ return
+
+ ## finalize self.ebuild: forced text creation + make it readonly
if ebuild.prepare ( True, True ):
self.ebuild = ebuild
- return self._set_status ( 'SUCCESS' )
-
- self._set_status ( 'FAIL' )
- return False
+ return None
+ else:
+ return None
+ except Exception as any_exception:
+ # any exception means failure
+ self.status = 'FAIL'
+ raise
# --- end of run (...) ---
+
+ @classmethod
+ def _set_status ( self, new_status, ignore_invalid=False ):
+ """Changes the status of this job. May refuse to do that if invalid change
+ requested (e.g. 'FAIL' -> 'SUCCESS').
+
+ arguments:
+ new_status --
+ """
+
+ if new_status == 'FAIL':
+ # always allowed
+ self.status = new_status
+
+ if new_status and new_status in EbuildJob.STATUS_LIST:
+ # check if jumping from self.status to new_status is allowed
+ if new_status in EbuildJob.STATUS_BRANCHMAP [self.status]:
+ self.status = new_status
+ return True
+
+ # default return
+ return False
+
+ # --- end of _set_status (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 16:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 16:09 UTC (permalink / raw
To: gentoo-commits
commit: aa515930aca5c5b231bd2b00471183fc3deabf76
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 14:53:53 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 14:53:53 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=aa515930
"its" not "it's" :)
modified: ebuild.py
modified: ebuildcreator.py
modified: fileio.py
---
roverlay/ebuild.py | 2 +-
roverlay/ebuildcreator.py | 2 +-
roverlay/fileio.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index 88dbde6..6316495 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -212,7 +212,7 @@ class Ebuild:
* varname -- name of the variable
* value -- value of the variable. This has to be either None (the default),
str, or list of str.
- * oneline_list -- if value is a list: controls whether it's components should be
+ * oneline_list -- if value is a list: controls whether its components should be
put into one line (True) or multiple (False). Defaults to True.
* indent_list -- if value is a list and not oneline_list:
controls whether each value line should be indentend
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index f6935a8..54a1c6a 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -68,7 +68,7 @@ class EbuildCreator:
def get_ebuild_header ( self, ebuild_header_file=None ):
"""Reads and returns the content of an ebuild header file.
This is a normal file that can be included in ebuilds.
- Every header file will only be read on first access, it's content will
+ Every header file will only be read on first access, its content will
be stored in a dict that is shared among all EbuildCreator instances.
arguments:
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 41aad23..295d904 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -131,7 +131,7 @@ class DescriptionReader:
* field -- name of the field that should be checked
* flag_to_check -- name of the flag to check; optional, defaults to None
- This method acts as 'field has any flags?' if flag_to_check is None (it's default value).
+ This method acts as 'field has any flags?' if flag_to_check is None (its default value).
"""
if field in const.DESCRIPTION_FIELD_MAP:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 16:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 16:09 UTC (permalink / raw
To: gentoo-commits
commit: 0ab8e34e33388ff12025c4a05969a891a9dcb8c4
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 16:08:30 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 16:08:30 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0ab8e34e
roverlay, fileio: refactored and @classmethod decorators removed
---
roverlay/fileio.py | 457 +++++++++++++++++++++++++---------------------------
1 files changed, 223 insertions(+), 234 deletions(-)
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 295d904..7c89356 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -15,217 +15,13 @@ from roverlay import tmpconst as const
class DescriptionReader:
"""Description Reader"""
- @classmethod
def __init__ ( self ):
"""Initializes a DESCRIPTION file reader."""
pass
- @classmethod
- def _get_fields_with_flag ( self, flag, foce_update=False ):
+ # --- end of __init__ (...) ---
- matching_fields = []
- field = None
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if flag is None:
- matching_fields.append ( field )
-
- elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
- if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
- matching_fields.append ( field )
-
- del field
- return matching_fields
-
-
- @classmethod
- def _find_field ( self , field_identifier ):
- """Determines the real name of a field.
-
- arguments:
- * field_identifier -- name of the field as it appears in the DESCRIPTION file
-
- At first, it is checked whether field_identifier matches the name of
- a field listed in DESCRIPTION_FIELD_MAP (any match results in immediate return).
- Then, a new iteration over the field map compares field_identifier
- with all aliases until the first case-(in)sensitive match (-> immediate return).
- None will be returned if none of the above searches succeed.
-
- In other words: this method decides whether a field_identifier will be used and if so,
- with which name.
- """
-
- # save some time by prevent searching if field_id is empty
- if not field_identifier:
- return None
-
- # search for real field names first
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if field_identifier == field:
- return field
-
- field_id_lower = field_identifier.lower()
-
- for field in const.DESCRIPTION_FIELD_MAP.keys():
-
- # does extra information (-> alias(es)) for this field exist?
- if 'alias' in const.DESCRIPTION_FIELD_MAP [field]:
-
- if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
- for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withcase']:
- if field_identifier == alias:
- return field
-
- if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
- for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocase']:
- if field_id_lower == alias.lower():
- return field
-
- #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
-
- # returning None if no valid field identifier matches
- return None
-
- @classmethod
- def _make_values ( self, value_str, field_context=None ):
- """Extracts relevant data from value_str and returns them as list.
-
- arguments:
- * value_str -- string that represents the (just read) values
- * field_context -- field name the value belongs to; optional, defaults to None
-
- It's useful to set field_context 'cause several fields ('Depends') have
- multiple values arranged in a list (dep0, dep1 [, depK]*).
- """
-
- svalue_str = value_str.strip()
-
- if not svalue_str:
- # empty value(s)
- return []
-
- elif field_context is None:
- # default return if no context given
- return [ svalue_str ]
-
- elif self._check_fieldflag ( field_context ):
- # value str is not empty and have flags for field_context, check these
-
- if self._check_fieldflag ( field_context, 'isList' ):
- # split up this list (that is separated by commata and/or semicolons)
- return re.split (const.DESCRIPTION_LIST_SPLIT_REGEX, svalue_str, 0)
-
- elif self._check_fieldflag ( field_context, 'isWhitespaceList' ):
- # split up this list (that is separated whitespace)
- return re.split ( '\s+', svalue_str, 0 )
-
-
- # default return
- return [ svalue_str ]
-
- @classmethod
- def _check_fieldflag ( self, field, flag_to_check=None ):
- """Checks if the given field has the specified flag and returns a bool.
-
- arguments:
- * field -- name of the field that should be checked
- * flag_to_check -- name of the flag to check; optional, defaults to None
-
- This method acts as 'field has any flags?' if flag_to_check is None (its default value).
- """
-
- if field in const.DESCRIPTION_FIELD_MAP:
- if 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
- if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
- return True
- elif flag_to_check is None:
- # 'flags' exist, return true
- return True
-
- return False
-
- @staticmethod
- def _get_desc_from_file ( filepath, pkg_name='.' ):
- """Reads a file returns the description data.
-
- arguments:
- * filepath -- file to read (str; path to tarball or file)
- * pkg_name -- name of the package, in tarballs the description file
- is located in <pkg_name>/ and thus this argument is required.
- Defaults to '.', set to None to disable.
-
- All exceptions are passed to the caller (TarError, IOErr, <custom>).
- <filepath> can either be a tarball in which case the real DESCRIPTION
- file is read (<pkg_name>/DESCRIPTION) or a normal file.
- """
-
- logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
-
- if not ( isinstance ( filepath, str ) and filepath ):
- raise Exception ( "bad usage" )
-
- # read describes how to import the lines from a file (e.g. rstrip())
- # fh, th are file/tar handles
- read = th = fh = None
-
- if tarfile.is_tarfile ( filepath ):
- # filepath is a tarball, open tar handle + file handle
- th = tarfile.open ( filepath, 'r' )
- if pkg_name:
- fh = th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_FILE_NAME ) )
- else:
- fh = th.extractfile ( const.DESCRIPTION_FILE_NAME )
-
- # have to decode the lines
- read = lambda lines : [ line.decode().rstrip() for line in lines ]
- else:
- # open file handle only
- fh = open ( filepath, 'r' )
- read = lambda lines : [ line.rstrip() for line in lines ]
-
- x = None
- read_lines = read ( fh.readlines() )
- del x, read
-
- fh.close()
- if not th is None: th.close()
- del fh, th
-
- return read_lines
-
- @staticmethod
- def _get_fileinfo ( filepath ):
- """Returns some info about the given filepath as dict whose contents are
- the file path, the file name ([as package_file with suffix and]
- as filename with tarball suffix removed), the package name
- and the package_version.
-
- arguments:
- * filepath --
- """
-
- package_file = os.path.basename ( filepath )
-
- filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
-
- # todo move that separator to const
- package_name, sepa, package_version = filename.partition ( '_' )
-
- if not sepa:
- # file name unexpected, tarball extraction will (probably) fail
- #raise Exception ("file name unexpected")
- logging.write ( "unexpected file name '" + filename + "'.\n" )
-
- return dict (
- filepath = filepath,
- filename = filename,
- package_file = package_file,
- package_name = package_name,
- #package_origin = ?,
- package_version = package_version,
- )
-
- @classmethod
def _parse_read_data ( self, read_data ):
"""Verifies and parses/fixes read data.
@@ -233,16 +29,25 @@ class DescriptionReader:
* read_data -- data from file, will be modified
"""
- def stats ( data ):
- """Temporary function that prints some info about the given data."""
+ def get_fields_with_flag ( flag, foce_update=False ):
+
+ matching_fields = []
+
field = None
- logging.write ( "=== this is the list of read data ===\n" )
- for field in read_data.keys():
- logging.write ( field + " = " + str ( read_data [field] ) + "\n" )
- logging.write ( "=== end of list ===\n" )
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+ if flag is None:
+ matching_fields.append ( field )
+
+ elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
+ if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
+ matching_fields.append ( field )
+
del field
+ return matching_fields
- def _value_in_strlist ( _val, _list, case_insensitive=True ):
+ # --- end of get_fields_with_flag (...) ---
+
+ def value_in_strlist ( _val, _list, case_insensitive=True ):
"""Returns true if value is in the given list."""
el = None
if case_insensitive:
@@ -258,9 +63,7 @@ class DescriptionReader:
del el
return False
-
-
- stats ( read_data )
+ # --- end of value_in_strlist (...) ---
field = None
@@ -270,14 +73,14 @@ class DescriptionReader:
read_data [field] = const.DESCRIPTION_FIELD_MAP [field] ['default_value']
# join values to a single string
- for field in self._get_fields_with_flag ( 'joinValues' ):
+ for field in get_fields_with_flag ( 'joinValues' ):
if field in read_data.keys():
read_data [field] = ' ' . join ( read_data [field] )
# ensure that all mandatory fields are set
missing_fields = list()
- for field in self._get_fields_with_flag ( 'mandatory' ):
+ for field in get_fields_with_flag ( 'mandatory' ):
if field in read_data:
if not len (read_data [field]):
missing_fields.append ( field )
@@ -294,15 +97,10 @@ class DescriptionReader:
# skip _fileinfo
if field != '_fileinfo':
if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
- if not _value_in_strlist ( read_data [field],
+ if not value_in_strlist ( read_data [field],
const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
): unsuitable_fields.append ( field )
-
- stats ( read_data )
-
-
-
valid = True
if len ( missing_fields ):
@@ -328,8 +126,8 @@ class DescriptionReader:
del field
return valid
+ # --- end of _parse_read_data (...) ---
- @classmethod
def readfile ( self, filepath ):
"""Reads a DESCRIPTION file and returns the read data if successful, else None.
@@ -347,15 +145,205 @@ class DescriptionReader:
e.g. if OS_TYPE is not unix).
"""
- read_data = dict ()
- fileinfo = DescriptionReader._get_fileinfo ( filepath )
+ def get_fileinfo ( filepath ):
+ """Returns some info about the given filepath as dict whose contents are
+ the file path, the file name ([as package_file with suffix and]
+ as filename with tarball suffix removed), the package name
+ and the package_version.
+ arguments:
+ * filepath --
+ """
- try:
- desc_lines = DescriptionReader._get_desc_from_file (
- filepath, fileinfo ['package_name']
+ package_file = os.path.basename ( filepath )
+
+ filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
+
+ # todo move that separator to const
+ package_name, sepa, package_version = filename.partition ( '_' )
+
+ if not sepa:
+ # file name unexpected, tarball extraction will (probably) fail
+ #raise Exception ("file name unexpected")
+ logging.write ( "unexpected file name '" + filename + "'.\n" )
+
+ return dict (
+ filepath = filepath,
+ filename = filename,
+ package_file = package_file,
+ package_name = package_name,
+ #package_origin = ?,
+ package_version = package_version,
)
+ # --- end of get_fileinfo (...) ---
+
+
+ def make_values ( value_str, field_context=None ):
+ """Extracts relevant data from value_str and returns them as list.
+
+ arguments:
+ * value_str -- string that represents the (just read) values
+ * field_context -- field name the value belongs to; optional, defaults to None
+
+ It's useful to set field_context 'cause several fields ('Depends') have
+ multiple values arranged in a list (dep0, dep1 [, depK]*).
+ """
+
+ def check_fieldflag ( field, flag_to_check=None ):
+ """Checks if the given field has the specified flag and returns a bool.
+
+ arguments:
+ * field -- name of the field that should be checked
+ * flag_to_check -- name of the flag to check; optional, defaults to None
+
+ This method acts as 'field has any flags?' if flag_to_check is None (its default value).
+ """
+
+ if field in const.DESCRIPTION_FIELD_MAP:
+ if 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
+ if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
+ return True
+ elif flag_to_check is None:
+ # 'flags' exist, return true
+ return True
+
+ return False
+ # --- end of check_fieldflag (...) ---
+
+ svalue_str = value_str.strip()
+
+ if not svalue_str:
+ # empty value(s)
+ return []
+
+ elif field_context is None:
+ # default return if no context given
+ return [ svalue_str ]
+
+ elif check_fieldflag ( field_context ):
+ # value str is not empty and have flags for field_context, check these
+
+ if check_fieldflag ( field_context, 'isList' ):
+ # split up this list (that is separated by commata and/or semicolons)
+ return re.split (const.DESCRIPTION_LIST_SPLIT_REGEX, svalue_str, 0)
+
+ elif check_fieldflag ( field_context, 'isWhitespaceList' ):
+ # split up this list (that is separated whitespace)
+ return re.split ( '\s+', svalue_str, 0 )
+
+
+ # default return
+ return [ svalue_str ]
+
+ # --- end of make_values (...) ---
+
+ def get_desc_from_file ( filepath, pkg_name='.' ):
+ """Reads a file returns the description data.
+
+ arguments:
+ * filepath -- file to read (str; path to tarball or file)
+ * pkg_name -- name of the package, in tarballs the description file
+ is located in <pkg_name>/ and thus this argument is required.
+ Defaults to '.', set to None to disable.
+
+ All exceptions are passed to the caller (TarError, IOErr, <custom>).
+ <filepath> can either be a tarball in which case the real DESCRIPTION
+ file is read (<pkg_name>/DESCRIPTION) or a normal file.
+ """
+
+ logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
+
+ if not ( isinstance ( filepath, str ) and filepath ):
+ raise Exception ( "bad usage" )
+
+ # read describes how to import the lines from a file (e.g. rstrip())
+ # fh, th are file/tar handles
+ read = th = fh = None
+
+ if tarfile.is_tarfile ( filepath ):
+ # filepath is a tarball, open tar handle + file handle
+ th = tarfile.open ( filepath, 'r' )
+ if pkg_name:
+ fh = th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_FILE_NAME ) )
+ else:
+ fh = th.extractfile ( const.DESCRIPTION_FILE_NAME )
+
+ # have to decode the lines
+ read = lambda lines : [ line.decode().rstrip() for line in lines ]
+ else:
+ # open file handle only
+ fh = open ( filepath, 'r' )
+ read = lambda lines : [ line.rstrip() for line in lines ]
+
+ x = None
+ read_lines = read ( fh.readlines() )
+ del x, read
+
+ fh.close()
+ if not th is None: th.close()
+ del fh, th
+
+ return read_lines
+
+ # --- end of get_desc_from_file (...) ---
+
+ def find_field ( field_identifier ):
+ """Determines the real name of a field.
+
+ arguments:
+ * field_identifier -- name of the field as it appears in the DESCRIPTION file
+
+ At first, it is checked whether field_identifier matches the name of
+ a field listed in DESCRIPTION_FIELD_MAP (any match results in immediate return).
+ Then, a new iteration over the field map compares field_identifier
+ with all aliases until the first case-(in)sensitive match (-> immediate return).
+ None will be returned if none of the above searches succeed.
+
+ In other words: this method decides whether a field_identifier will be used and if so,
+ with which name.
+ """
+
+ # save some time by prevent searching if field_id is empty
+ if not field_identifier:
+ return None
+
+ # search for real field names first
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+ if field_identifier == field:
+ return field
+
+ field_id_lower = field_identifier.lower()
+
+ for field in const.DESCRIPTION_FIELD_MAP.keys():
+
+ # does extra information (-> alias(es)) for this field exist?
+ if 'alias' in const.DESCRIPTION_FIELD_MAP [field]:
+
+ if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
+ for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withcase']:
+ if field_identifier == alias:
+ return field
+
+ if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
+ for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocase']:
+ if field_id_lower == alias.lower():
+ return field
+
+ #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
+
+ # returning None if no valid field identifier matches
+ return None
+
+ # --- end of find_field (...) ---
+
+
+ read_data = dict ()
+ fileinfo = get_fileinfo ( filepath )
+
+
+ try:
+ desc_lines = get_desc_from_file ( filepath, fileinfo ['package_name'] )
except IOError as err:
# <todo>
@@ -378,7 +366,7 @@ class DescriptionReader:
if field_context:
# context is set => append values
- for val in self._make_values ( sline, field_context ):
+ for val in make_values ( sline, field_context ):
read_data [field_context] . append ( val )
else:
# no valid context => ignore line
@@ -392,7 +380,7 @@ class DescriptionReader:
if line_components [1]:
# line contains a field separator, set field context
- field_context = self._find_field ( line_components [0] )
+ field_context = find_field ( line_components [0] )
if field_context:
# create a new empty list for field_context
@@ -400,7 +388,7 @@ class DescriptionReader:
# add values to read_data
# no need to check line_components [2] 'cause [1] was a true str
- for val in self._make_values ( line_components [2], field_context ):
+ for val in make_values ( line_components [2], field_context ):
read_data [field_context] . append ( val )
else:
@@ -424,8 +412,8 @@ class DescriptionReader:
if self._parse_read_data ( read_data ):
- logging.write ( '## success ##\n' )
- logging.write ( ( str ( read_data ) ) )
+ #logging.write ( '## success ##\n' )
+ #logging.write ( ( str ( read_data ) ) )
return dict (
fileinfo = fileinfo,
description_data = read_data
@@ -434,3 +422,4 @@ class DescriptionReader:
logging.write ( '## fail ##\n' )
return None
+ # --- end of readfile (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 16:09 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 16:09 UTC (permalink / raw
To: gentoo-commits
commit: eecacfa624c9c07a6d5fab9b2867cf201599b869
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 16:07:34 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 16:07:34 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=eecacfa6
remove @classmethod decorators
modified: ebuild.py
modified: ebuildcreator.py
modified: ebuildjob.py
---
roverlay/ebuild.py | 7 -------
roverlay/ebuildcreator.py | 15 ++++++---------
roverlay/ebuildjob.py | 14 ++++----------
3 files changed, 10 insertions(+), 26 deletions(-)
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index 6316495..df2d028 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -6,7 +6,6 @@ class Ebuild:
# could move this to const
EBUILD_INDENT = "\t"
- @classmethod
def __init__ ( self ):
"""Initializes an Ebuild.
This is an abstraction layer between the verified + calculated data
@@ -20,7 +19,6 @@ class Ebuild:
# --- end of __init__ (...) ---
- @classmethod
def cleanup ( self ):
"""Removes stored data if ebuild_lines have already been calculated.
This saves some memory but makes this Ebuild read-only.
@@ -31,7 +29,6 @@ class Ebuild:
# --- end of cleanup (...) ---
- @classmethod
def prepare ( self, force_update=False, cleanup_after=False ):
"""Tells this Ebuild to create ebuild lines.
@@ -59,7 +56,6 @@ class Ebuild:
# --- end of prepare (...) ---
- @classmethod
def add ( self, key, value, append=True ):
"""Adds data to this Ebuild.
@@ -90,7 +86,6 @@ class Ebuild:
# --- end of add (...) ---
- @classmethod
def write ( self, file_to_write ):
"""Writes an ebuild file.
@@ -115,7 +110,6 @@ class Ebuild:
# --- end of write (...) ---
- @classmethod
def show ( self, file_handle ):
"""Prints the ebuild content into a file_handle.
@@ -154,7 +148,6 @@ class Ebuild:
# --- end of suggest_name (...) ---
- @classmethod
def _make_ebuild_lines ( self ):
"""Creates text lines for this Ebuild.
It assumes that enough data to do this are available. Exceptions (KeyError, NameError, ...)
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index 54a1c6a..bc74490 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -6,9 +6,6 @@ from roverlay.ebuildjob import EbuildJob
class EbuildCreator:
-
-
- @classmethod
def __init__ ( self ):
"""Initializes an EbuildCreator. This is an Object that controls the
R package -> ebuild creation. It continuously creates EbuildJobs for
@@ -20,8 +17,6 @@ class EbuildCreator:
# --- end of init (...) ---
-
- @classmethod
def add_package ( self, package_file ):
"""Adds an R package to the EbuildCreator, which means that an EbuildJob
will be created for it. Returns the EbuildJob, which is also stored
@@ -30,6 +25,7 @@ class EbuildCreator:
arguments:
* package_file -- path R package file
"""
+
new_job = EbuildJob ( package_file, self.get_resolver ( False ) )
self.ebuild_jobs.append ( new_job )
@@ -38,7 +34,6 @@ class EbuildCreator:
# --- end of add_package (...) ---
- @classmethod
def get_resolver ( self, readonly=True ):
"""Returns a communication channel to the dependency resolver.
@@ -52,19 +47,21 @@ class EbuildCreator:
# --- end of get_resolver (...) ---
- @classmethod
def run ( self ):
"""Tells all EbuildJobs to run."""
for job in self.ebuild_jobs:
job.run()
- @classmethod
+ # --- end of run (...) ---
+
def collect_ebuilds ( self ):
"""Returns all ebuilds. (They may not be ready / TODO)"""
ebuilds = [ job.get_ebuild() for job in self.ebuild_jobs ]
return [ ebuild for ebuild in ebuilds if (not ebuild is None) ]
- @classmethod
+ # --- end of collect_ebuilds (...) ---
+
+
def get_ebuild_header ( self, ebuild_header_file=None ):
"""Reads and returns the content of an ebuild header file.
This is a normal file that can be included in ebuilds.
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index d45dfdf..2767497 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -28,7 +28,6 @@ class EbuildJob:
FAIL = [],
)
- @classmethod
def __init__ ( self, package_file, dep_resolver=None ):
"""Initializes an EbuildJob, which creates an ebuild for an R package.
@@ -53,7 +52,6 @@ class EbuildJob:
# --- end of __init__ (...) ---
- @classmethod
def get_ebuild ( self ):
"""Returns the Ebuild that is created by this object. Note that you should
check the status with status ( $TODO::EBUILD_READY ) before trying to use
@@ -64,7 +62,6 @@ class EbuildJob:
# --- end of get_ebuild (...) ---
- @classmethod
def get_status ( self, expected_status=None ):
"""Returns the current status of this job or a bool that indicates
whether to current status matches the expected one.
@@ -79,7 +76,6 @@ class EbuildJob:
# --- end of get_status (...) ---
- @classmethod
def done_success ( self ):
"""Returns True if this has been successfully finished."""
return get_status ( 'SUCCESS' )
@@ -87,7 +83,6 @@ class EbuildJob:
# --- end of done_success (...) ---
- @classmethod
def run ( self ):
"""Tells this EbuildJob to run. This means that it reads the package file,
resolves dependencies using its resolver (TODO) and creates
@@ -125,7 +120,8 @@ class EbuildJob:
# origin is todo (sync module knows the package origin)
- ebuild.add ( 'PKG_ORIGIN', 'CRAN' )
+ ebuild.add ( 'PKG_ORIGIN', 'CRAN/BIOC/... TODO!' )
+ ebuild.add ( 'SRC_URI', 'where? TODO!' )
ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] )
@@ -206,9 +202,8 @@ class EbuildJob:
## finalize self.ebuild: forced text creation + make it readonly
if ebuild.prepare ( True, True ):
self.ebuild = ebuild
- return None
- else:
- return None
+
+ return None
except Exception as any_exception:
# any exception means failure
@@ -217,7 +212,6 @@ class EbuildJob:
# --- end of run (...) ---
- @classmethod
def _set_status ( self, new_status, ignore_invalid=False ):
"""Changes the status of this job. May refuse to do that if invalid change
requested (e.g. 'FAIL' -> 'SUCCESS').
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 19:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 19:36 UTC (permalink / raw
To: gentoo-commits
commit: 925f11b49cd410c164c822c29ef36884e6c22b99
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 19:35:47 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 19:35:47 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=925f11b4
roverlay, ebuild: reduce lines of code by not writing unchanged vars (IUSE="${IUSE:-}" etc.)
modified: roverlay/ebuild.py
---
roverlay/ebuild.py | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index df2d028..8c960a2 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -163,9 +163,11 @@ class Ebuild:
have_suggests = bool ( 'RSUGGESTS' in self._data and self._data ['RSUGGESTS'] )
# set defaults: inherit eclass + include depend in rdepend
+ # TODO: is ${DEPEND:-},... necessary?
ret = dict (
DEPEND = [ '${DEPEND:-}' ],
- RDEPEND = [ '${DEPEND:-}', '${RDEPEND:-}' ],
+ # RDEPEND: assuming that the eclass includes it's DEPEND in RDEPEND
+ RDEPEND = [ '${RDEPEND:-}' ],
IUSE = [ '${IUSE:-}' ],
)
@@ -305,7 +307,9 @@ class Ebuild:
add_easyvar ( ebuild_lines, "PKG_FILE" )
if 'PKG_ORIGIN' in self._data:
- add_easyvar ( ebuild_lines, "PKG_ORIGIN", None, True )
+ add_easyvar ( ebuild_lines, "PKG_ORIGIN", None, False )
+
+ ebuild_lines.append ( "" )
add_easyvar ( ebuild_lines, "DESCRIPTION" )
@@ -323,13 +327,20 @@ class Ebuild:
dep_and_use = get_dep_and_use ()
- ebuild_lines.append ( make_var ( "IUSE", dep_and_use ['IUSE'], True ) )
+ # check that IUSE has more than one element, don't write IUSE="${IUSE:-}" etc.
+ if len ( dep_and_use ['IUSE'] ) > 1:
+ ebuild_lines.append ( make_var ( "IUSE", dep_and_use ['IUSE'], True ) )
if 'R_SUGGESTS' in dep_and_use:
ebuild_lines.append ( make_var ( "R_SUGGESTS", dep_and_use ['R_SUGGESTS'], False ) )
- ebuild_lines.append ( make_var ( "DEPEND", dep_and_use ['DEPEND'], False ) )
- ebuild_lines.append ( make_var ( "RDEPEND", dep_and_use ['RDEPEND'], False ) )
+ # see IUSE
+ if len ( dep_and_use ['DEPEND'] ) > 1:
+ ebuild_lines.append ( make_var ( "DEPEND", dep_and_use ['DEPEND'], False ) )
+
+ # see IUSE
+ if len ( dep_and_use ['RDEPEND'] ) > 1:
+ ebuild_lines.append ( make_var ( "RDEPEND", dep_and_use ['RDEPEND'], False ) )
del dep_and_use
return remove_newlines ( ebuild_lines )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 19:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 19:36 UTC (permalink / raw
To: gentoo-commits
commit: 1486db8558672eae1054bd7b7bbc7e69913b8666
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 19:35:08 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 19:35:08 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1486db85
roverlay, ebuildjob: useful default ebuild header
modified: roverlay/ebuildjob.py
---
roverlay/ebuildjob.py | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 2767497..13800e2 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -2,6 +2,8 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import time
+
from roverlay.fileio import DescriptionReader
from roverlay.ebuild import Ebuild
@@ -120,15 +122,23 @@ class EbuildJob:
# origin is todo (sync module knows the package origin)
- ebuild.add ( 'PKG_ORIGIN', 'CRAN/BIOC/... TODO!' )
+ # could calculate SRC_URI in the eclass depending on origin
+ ##ebuild.add ( 'PKG_ORIGIN', 'CRAN/BIOC/... TODO!' )
ebuild.add ( 'SRC_URI', 'where? TODO!' )
ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] )
+ ## default ebuild header, could use some const here (eclass name,..)
ebuild.add ( 'ebuild_header',
- [ '# test header, first line\n',
- '# test header, second line\n\n\n\n',
- '#third\n\n#fifth' ],
+ [ '# Copyright 1999-' + str ( time.gmtime() [0] ) + ' Gentoo Foundation',
+ '',
+ '# Distributed under the terms of the GNU General Public License v2',
+ '# $Header: $',
+ '',
+ 'EAPI=4',
+ '',
+ 'inherit R-packages'
+ ],
False
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-30 20:15 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-30 20:15 UTC (permalink / raw
To: gentoo-commits
commit: 3eecf500d7f96746df2a0147150ad390ca4652dc
Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May 30 20:09:30 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May 30 20:09:30 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=3eecf500
remove newline in header
modified: roverlay/ebuildjob.py
---
roverlay/ebuildjob.py | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 13800e2..2d29643 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -131,7 +131,6 @@ class EbuildJob:
## default ebuild header, could use some const here (eclass name,..)
ebuild.add ( 'ebuild_header',
[ '# Copyright 1999-' + str ( time.gmtime() [0] ) + ' Gentoo Foundation',
- '',
'# Distributed under the terms of the GNU General Public License v2',
'# $Header: $',
'',
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-05-31 18:24 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-05-31 18:24 UTC (permalink / raw
To: gentoo-commits
commit: 2857235f05980e0ad98351850c1422993305c6e6
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu May 31 18:22:45 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu May 31 18:22:45 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2857235f
roverlay, 2012-05-31:
* basic logging
** replaced some errors cases by log entries
* started with the config module
---
roverlay/__init__.py | 19 ++++
roverlay/config.py | 60 +++++++++++++
roverlay/descriptionfields.py | 121 ++++++++++++++++++++++++++
roverlay/ebuild.py | 96 +++++++++++++++------
roverlay/ebuildjob.py | 38 ++++++---
roverlay/fileio.py | 186 +++++++++++++++++++++--------------------
6 files changed, 394 insertions(+), 126 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 863ab2b..b1557ef 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -2,4 +2,23 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import logging
+
+logging.basicConfig (
+ level=logging.DEBUG,
+ filename='roverlay.log',
+ filemode='a',
+ format='%(asctime)s %(levelname)-8s %(name)-14s -- %(message)s',
+ datefmt='%F %H:%M:%S'
+)
+
+# add console output to the logger
+ch = logging.StreamHandler()
+ch.setLevel ( logging.INFO )
+ch.setFormatter (
+ logging.Formatter ( '%(levelname)-8s %(name)-14s -- %(message)s' )
+)
+logging.getLogger().addHandler ( ch )
+del ch
+
VERSION = "0.0-pre1"
diff --git a/roverlay/config.py b/roverlay/config.py
new file mode 100644
index 0000000..248fc22
--- /dev/null
+++ b/roverlay/config.py
@@ -0,0 +1,60 @@
+# R overlay -- config module
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+from roverlay import descriptionfields
+
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
+def access():
+ return ConfigTree() if ConfigTree.instance is None else ConfigTree.instance
+
+class InitialLogger:
+
+ def __init__ ( self ):
+ self.debug = lambda x : sys.stderr.write ( "DBG " + str ( x ) + "\n" )
+ self.info = lambda x : sys.stderr.write ( "INFO " + str ( x ) + "\n" )
+ self.warning = lambda x : sys.stderr.write ( "WARN " + str ( x ) + "\n" )
+ self.error = lambda x : sys.stderr.write ( "ERR " + str ( x ) + "\n" )
+ self.critical = lambda x : sys.stderr.write ( "CRIT " + str ( x ) + "\n" )
+ self.exception = lambda x : sys.stderr.write ( "EXC! " + str ( x ) + "\n" )
+
+class ConfigTree:
+ # static access to the first created ConfigTree
+ instance = None
+
+ def __init__ ( self ):
+ if ConfigTree.instance is None:
+ ConfigTree.instance = self
+
+ self.logger = InitialLogger()
+
+ self.parser = dict()
+
+
+ def load_field_definition ( self, def_file, lenient=False ):
+ if not 'field_def' in self.parser:
+ self.parser ['field_def'] = configparser.SafeConfigParser ( allow_no_value=True )
+
+ try:
+ self.logger.debug ( "Reading description field definition file " + def_file + "." )
+ if lenient:
+ self.parser ['field_def'] . read ( def_file )
+ else:
+ fh = open ( def_file, 'r' )
+ self.parser ['field_def'] . readfp ( fh )
+ if fh:
+ fh.close()
+ except IOError as err:
+ self.logger.exception ( err )
+ raise
+ except configparser.MissingSectionHeaderError as mshe:
+ self.logger.exception ( mshe )
+ raise
+
+
diff --git a/roverlay/descriptionfields.py b/roverlay/descriptionfields.py
new file mode 100644
index 0000000..9c028c2
--- /dev/null
+++ b/roverlay/descriptionfields.py
@@ -0,0 +1,121 @@
+# R overlay -- description fields
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+
+# split from tmpconst / fileio to make configuration possible, but TODO
+
+class DescriptionField:
+
+ def __init__ ( self, name ):
+ if not name:
+ raise Exception ( "description field name is empty." )
+
+ self.name = name
+
+
+
+ def get_name ( self ):
+ return self.name
+
+ def add_flag ( self, flag, lowercase=True ):
+ if not hasattr ( self, flags ):
+ self.flags = set ()
+
+ self.flags.add ( flag, flag.lower() if lowercase else flag )
+
+ return None
+
+
+ def del_flag ( self, flag ):
+ if hasattr ( self, flags ):
+ self.flags.discard ( flag )
+ return None
+
+
+ def add_alias ( self, alias, alias_type='withcase' ):
+ if not hasattr ( self, aliases ):
+ self.aliases = dict ()
+
+ to_add = dict (
+ withcase = alias,
+ nocase = alias.lower(),
+ ) [alias_type]
+
+
+ if not alias_type in self.aliases:
+ self.aliases [alias_type] = set ()
+
+ self.aliases [alias_type] . add ( to_add )
+
+ return None
+
+
+
+ def add_simple_alias ( self, alias, withcase=True ):
+ if withcase:
+ return self.add_alias ( alias, alias_type='withcase' )
+ else:
+ return self.add_alias ( alias, alias_type='nocase' )
+
+
+
+ def get_default_value ( self ):
+ if hasattr ( self, 'default_value' ):
+ return self.default_value
+ else:
+ return None
+
+
+ def get ( self, key, fallback_value=None ):
+ if hasattr ( self, key ):
+ return self.key
+ else:
+ return fallback_value
+
+ def matches ( self, field_identifier ):
+ return bool ( self.name == field_identifier ) if field_identifier else False
+
+ def matches_alias ( self, field_identifier ):
+
+ if not field_identifier:
+ return False
+ if not hasattr ( self, aliases ):
+ return False
+
+ if 'withcase' in self.aliases:
+ if field_identifier in self.aliases ['withcase']:
+ return True
+
+ if 'nocase' in self.aliases:
+ field_id_lower = field_identifier.lower()
+ if field_id_lower in self.aliases ['nocase']:
+ return True
+
+ def has_flag ( self, flag, lowercase=True ):
+ if not hasattr ( self, flags ):
+ return False
+
+ return bool ( (flag.lower() if lowercase else flag) in self.flags )
+
+class DescriptionFields:
+
+ def __init__ ( self ):
+ fields = dict ()
+
+ def add ( self, desc_field ):
+ if desc_field:
+ if isinstance ( desc_field, DescriptionField ):
+ fields [desc_field.get_name()] = desc_field
+ return 1
+ elif isinstance ( desc_field, str ):
+ fields [desc_field] = DescriptionField ( desc_field )
+ return 2
+
+ return 0
+
+ def get ( self, field_name ):
+ return self.fields [field_name] if field_name in self.fields else None
+
+ # ... TODO
+
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index 8c960a2..1634ef3 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -6,16 +6,31 @@ class Ebuild:
# could move this to const
EBUILD_INDENT = "\t"
- def __init__ ( self ):
+ ADD_REMAP = {
+ # pkg vs package
+ 'package_name' : 'pkg_name',
+ 'package_version' : 'pkg_version',
+ 'package_revision' : 'pkg_revision',
+ # TITLE is in DESCRIPTION
+ 'TITLE' : 'DESCRIPTION',
+ }
+
+ def __init__ ( self, logger ):
"""Initializes an Ebuild.
This is an abstraction layer between the verified + calculated data
and the ebuild data, which can be written into a file / stdout / stdin.
Most functions here assume that everything is fine when it reaches them.
+
+ arguments:
+ * logger -- logger for this Ebuild
"""
+ self.logger = logger
+
# elements in ebuild_data are either a str or a list of str
self._data = dict ()
self._ebuild_lines = None
+ self._ebuild_name = None
# --- end of __init__ (...) ---
@@ -24,6 +39,8 @@ class Ebuild:
This saves some memory but makes this Ebuild read-only.
"""
if self._ebuild_lines:
+ # determine the ebuild name first
+ self._ebuild_name = self.suggest_name()
del self._data
self._data = None
@@ -56,12 +73,18 @@ class Ebuild:
# --- end of prepare (...) ---
+ def has_ebuild ( self ):
+ """Returns True if this object has ebuild text lines else False."""
+ return bool ( self._ebuild_lines )
+ # --- end of has_ebuild (...) ---
+
def add ( self, key, value, append=True ):
"""Adds data to this Ebuild.
arguments:
* key -- identifier of the data (e.g. DEPEND).
- May be remapped here (e.g. merging 'Title' and 'Description')
+ May be remapped (e.g. merging 'Title' and 'Description')
+ or even refused here
* value --
* append -- whether to append values or overwrite existing ones,
defaults to True.
@@ -72,17 +95,22 @@ class Ebuild:
# -- todo
raise Exception ("Ebuild data are readonly.")
- if append and key in self._data:
- if not isinstance ( self._data [key], list ):
- self._data [key] = [ self._data [key] ]
-
- if isinstance ( value, list ):
- self._data [key].extend ( value )
- else:
- self._data [key].append ( value )
+ _key = Ebuild.ADD_REMAP [key] if key in Ebuild.ADD_REMAP else key
+ if _key is None:
+ self.logger.debug ( "add (%s, %s): filtered key.", key, str ( value ) )
else:
- self._data [key] = value
+ if append and _key in self._data:
+ if not isinstance ( self._data [_key], list ):
+ self._data [_key] = [ self._data [_key] ]
+
+ if isinstance ( value, list ):
+ self._data [_key].extend ( value )
+ else:
+ self._data [_key].append ( value )
+
+ else:
+ self._data [_key] = value
# --- end of add (...) ---
@@ -99,14 +127,12 @@ class Ebuild:
self.show ( fh )
fh.close()
del fh
- return True
except IOError as err:
- # ? todo
+ self.logger.exception ( err )
raise
else:
- # todo log this
- raise Exception ("cannot write ebuild")
+ self.logger.warning ( "Cannot write ebuild - it's empty! (check with has_ebuild() before calling this method.)" )
# --- end of write (...) ---
@@ -128,20 +154,39 @@ class Ebuild:
# --- end of show (...) ---
- def suggest_name ( self, fallback_name=None ):
+ def suggest_dir_name ( self ):
+ """Suggests a direcory name for this Ebuild."""
+ return self._data ['pkg_name'] if 'pkg_name' in self._data else self.suggest_name().partition ( '-' )
+ # --- end of suggest_dir_name (...) ---
+
+ def suggest_name ( self, fallback_name='' ):
"""Suggests a file name for the ebuild. This is calculated using
pkg_name/version/revision. Returns a fallback_name if this is not
possible.
arguments:
- fallback_name -- name to return if no suggestion available, defaults to None
+ fallback_name -- name to return if no suggestion available, defaults to empty string
"""
- if 'pkg_name' in self._data and 'pkg_version' in self._data:
- join = [ 'pkg_name' , 'pkg_version' ]
- if 'pkg_revision' in self._data: join.append ('pkg_revision')
+ if self._ebuild_name:
+ return self._ebuild_name
+ elif (not self._data is None) and 'pkg_name' in self._data:
+ name_components = [ self._data ['pkg_name'] ]
+
+ if 'pkg_version' in self._data:
+ name_components.append ( self._data ['pkg_version'] )
+ else:
+ # default ver
+ name_components.append ( '1.0' )
+
+ if 'pkg_revision' in self._data:
+ rev = self._data ['pkg_revision']
+
+ # omit rev == 0 and invalid revisions
+ if isinstance ( rev, int ) and rev > 0:
+ name_components.append ( 'r' + rev )
- return '-' . join ( [ self._data [c] for c in join ] )
+ return '-'.join ( name_components )
else:
return fallback_name
@@ -316,7 +361,7 @@ class Ebuild:
if 'SRC_URI' in self._data:
add_easyvar ( ebuild_lines, "SRC_URI" )
else:
- # > calculate SRC_URI using self._data ['origin']
+ # > calculate SRC_URI using self._data ['origin'] -- either here or in eclass
ebuild_lines.append ( make_var ( "SRC_URI" , None ) )
# (temporary, todo) setting restrict to fetch
ebuild_lines.append ( make_var ( "RESTRICT" , "fetch" ) )
@@ -345,9 +390,8 @@ class Ebuild:
del dep_and_use
return remove_newlines ( ebuild_lines )
- except Exception as err:
- # log this
- ## ..
- raise
+ except ( ValueError, KeyError, NameError ) as err:
+ self.logger.error ( "Cannot create ebuild text lines. The error message was %s.", str ( err ) )
+ return None
# --- end of make_ebuild_lines (...) ---
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 2d29643..0357e77 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -3,11 +3,15 @@
# Distributed under the terms of the GNU General Public License v2
import time
+import logging
+import re
from roverlay.fileio import DescriptionReader
from roverlay.ebuild import Ebuild
class EbuildJob:
+ LOGGER = logging.getLogger ( 'EbuildJob' )
+
# move this to const / config
DEPENDENCY_FIELDS = {
'R_SUGGESTS' : [ 'Suggests' ],
@@ -43,10 +47,12 @@ class EbuildJob:
dep resolver 'communication channel', status codes etc.
"""
- self.package_file = package_file
+ #self.package_file = package_file
self.dep_resolver = dep_resolver
# get description reader from args?
- self.description_reader = DescriptionReader()
+ self.description_reader = DescriptionReader ( package_file )
+
+ self.logger = EbuildJob.LOGGER.getChild ( self.description_reader.get_log_name () )
self.ebuild = None
@@ -92,23 +98,29 @@ class EbuildJob:
"""
# TODO move hardcoded entries to config/const
+ # TODO metadata.xml creation
try:
# set status or return
if not self._set_status ( 'BUSY', True ): return
- read_data = self.description_reader.readfile ( self.package_file )
-
- if read_data is None:
- # set status accordingly
+ desc = self.description_reader.get_desc ( True )
+ if desc is None:
self._set_status ( 'FAIL' )
- return
+ self.logger.info ( 'Cannot create an ebuild for this package.' )
+
- fileinfo = read_data ['fileinfo']
- desc = read_data ['description_data']
+ fileinfo = self.description_reader.get_fileinfo ()
+
+ ebuild = Ebuild ( self.logger.getChild ( "Ebuild" ) )
+
+ ebuild.add ( 'pkg_name', fileinfo ['package_name'] )
+ # TODO move regex to config/const
+ ebuild.add ( 'pkg_version',
+ re.sub ( '[-]{1,}', '.', fileinfo ['package_version'] )
+ )
- ebuild = Ebuild()
have_description = False
@@ -216,7 +228,7 @@ class EbuildJob:
except Exception as any_exception:
# any exception means failure
- self.status = 'FAIL'
+ self._set_status ( 'FAIL' )
raise
# --- end of run (...) ---
@@ -231,15 +243,19 @@ class EbuildJob:
if new_status == 'FAIL':
# always allowed
+ self.logger.info ( "Entering status '%s'.", new_status )
self.status = new_status
+ return True
if new_status and new_status in EbuildJob.STATUS_LIST:
# check if jumping from self.status to new_status is allowed
if new_status in EbuildJob.STATUS_BRANCHMAP [self.status]:
+ self.logger.debug ( "Entering status '%s'.", new_status )
self.status = new_status
return True
# default return
+ self.logger.error ( "Cannot enter status '%s'.", new_status )
return False
# --- end of _set_status (...) ---
diff --git a/roverlay/fileio.py b/roverlay/fileio.py
index 7c89356..5c01527 100644
--- a/roverlay/fileio.py
+++ b/roverlay/fileio.py
@@ -3,11 +3,10 @@
# Distributed under the terms of the GNU General Public License v2
import re
-import os.path
import tarfile
+import logging
+import os.path
-# temporary import until logging is implemented
-from sys import stderr as logging
# temporary import until config and real constants are implemented
from roverlay import tmpconst as const
@@ -15,12 +14,70 @@ from roverlay import tmpconst as const
class DescriptionReader:
"""Description Reader"""
- def __init__ ( self ):
+ LOGGER = logging.getLogger ( 'DescriptionReader' )
+
+ def __init__ ( self, package_file, read_now=False ):
"""Initializes a DESCRIPTION file reader."""
- pass
+
+ self.fileinfo = self.make_fileinfo ( package_file )
+ self.logger = DescriptionReader.LOGGER.getChild ( self.get_log_name() )
+ self.desc_data = None
+
+
+ if read_now:
+ self.run()
# --- end of __init__ (...) ---
+ def get_log_name ( self ):
+ try:
+ return self.fileinfo ['filename']
+ except Exception as any_exception:
+ return '__undef__'
+
+ def get_desc ( self, run_if_unset=True ):
+ if self.desc_data is None:
+ self.run ()
+
+ return self.desc_data
+ # --- end of get_desc (...) ---
+
+ def get_fileinfo ( self ):
+ return self.fileinfo
+ # --- end of get_fileinfo (...) ---
+
+ def make_fileinfo ( self, filepath ):
+ """Returns some info about the given filepath as dict whose contents are
+ the file path, the file name ([as package_file with suffix and]
+ as filename with tarball suffix removed), the package name
+ and the package_version.
+
+ arguments:
+ * filepath --
+ """
+
+ package_file = os.path.basename ( filepath )
+
+ filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
+
+ # todo move that separator to const
+ package_name, sepa, package_version = filename.partition ( '_' )
+
+ if not sepa:
+ # file name unexpected, tarball extraction will (probably) fail
+ DescriptionReader.LOGGER.error ( "unexpected file name %s.'", filename )
+
+ return dict (
+ filepath = filepath,
+ filename = filename,
+ package_file = package_file,
+ package_name = package_name,
+ #package_origin = ?,
+ package_version = package_version,
+ )
+
+ # --- end of make_fileinfo (...) ---
+
def _parse_read_data ( self, read_data ):
"""Verifies and parses/fixes read data.
@@ -91,44 +148,31 @@ class DescriptionReader:
# check for fields that allow only certain values
- unsuitable_fields = list()
+ unsuitable_fields = dict()
for field in read_data.keys():
- # skip _fileinfo
- if field != '_fileinfo':
- if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
- if not value_in_strlist ( read_data [field],
- const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
- ): unsuitable_fields.append ( field )
+ if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
+ if not value_in_strlist (
+ read_data [field],
+ const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
+ ):
+ unsuitable_fields.append [field] = read_data [field]
- valid = True
-
- if len ( missing_fields ):
- valid = False
-
- logging.write (
- "Verification of mandatory fields failed, the result leading to this was: " +
- str ( missing_fields ) + "\n"
- )
-
- #<raise custom exception>
- raise Exception ("^^^look above")
-
- if len ( unsuitable_fields ):
- valid = False
-
- logging.write (
- "Some fields have values that forbid further parsing, the result leading to this was: " +
- str ( unsuitable_fields ) + "\n"
- )
-
- del missing_fields
del field
+ valid = not bool ( len ( missing_fields ) or len ( unsuitable_fields ) )
+ if not valid:
+ self.logger.info ( "Cannot use R package" ) # name?
+ if len ( missing_fields ):
+ self.logger.debug ( "The following mandatory description fields are missing: %s.", str ( missing_fields ) )
+ if len ( unsuitable_fields ):
+ self.logger.debug ( "The following fields have unsuitable values: %s.", str ( unsuitable_fields ) )
+
return valid
+
# --- end of _parse_read_data (...) ---
- def readfile ( self, filepath ):
+ def run ( self ):
"""Reads a DESCRIPTION file and returns the read data if successful, else None.
arguments:
@@ -145,40 +189,6 @@ class DescriptionReader:
e.g. if OS_TYPE is not unix).
"""
- def get_fileinfo ( filepath ):
- """Returns some info about the given filepath as dict whose contents are
- the file path, the file name ([as package_file with suffix and]
- as filename with tarball suffix removed), the package name
- and the package_version.
-
- arguments:
- * filepath --
- """
-
- package_file = os.path.basename ( filepath )
-
- filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
-
- # todo move that separator to const
- package_name, sepa, package_version = filename.partition ( '_' )
-
- if not sepa:
- # file name unexpected, tarball extraction will (probably) fail
- #raise Exception ("file name unexpected")
- logging.write ( "unexpected file name '" + filename + "'.\n" )
-
- return dict (
- filepath = filepath,
- filename = filename,
- package_file = package_file,
- package_name = package_name,
- #package_origin = ?,
- package_version = package_version,
- )
-
- # --- end of get_fileinfo (...) ---
-
-
def make_values ( value_str, field_context=None ):
"""Extracts relevant data from value_str and returns them as list.
@@ -252,7 +262,7 @@ class DescriptionReader:
file is read (<pkg_name>/DESCRIPTION) or a normal file.
"""
- logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
+ self.logger.debug ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
if not ( isinstance ( filepath, str ) and filepath ):
raise Exception ( "bad usage" )
@@ -338,16 +348,19 @@ class DescriptionReader:
# --- end of find_field (...) ---
+ self.desc_data = None
read_data = dict ()
- fileinfo = get_fileinfo ( filepath )
try:
- desc_lines = get_desc_from_file ( filepath, fileinfo ['package_name'] )
+ desc_lines = get_desc_from_file (
+ self.fileinfo ['filepath'],
+ self.fileinfo ['package_name']
+ )
except IOError as err:
- # <todo>
- raise
+ self.logger.exception ( err )
+ return self.desc_data
field_context = val = line = sline = None
@@ -393,18 +406,15 @@ class DescriptionReader:
else:
# useless line, skip
- logging.write (
- "Skipping a line, first line component (field identifier?) was: '"
- + line_components [0] + "'\n"
- )
+ self.logger.info ( "Skipped a description field: '%s'.", line_components [0] )
else:
# reaching this branch means that
# (a) line has no leading whitespace
# (b) line has no separator (:)
# this should not occur in description files (bad syntax?)
- logging.write ( "***" + line_components [0] + "***\n")
- raise Exception ( "bad file" )
+ self.logger.warning ( "Unexpected line in description file: '%s'.", line_components [0] )
+
del line_components
@@ -412,14 +422,12 @@ class DescriptionReader:
if self._parse_read_data ( read_data ):
- #logging.write ( '## success ##\n' )
- #logging.write ( ( str ( read_data ) ) )
- return dict (
- fileinfo = fileinfo,
- description_data = read_data
- )
- else:
- logging.write ( '## fail ##\n' )
- return None
+ self.logger.debug ( "Successfully read file '%s' with data = %s.",
+ self.fileinfo ['filepath'], str ( read_data )
+ )
+ self.desc_data = read_data
+
+ # get_desc() is preferred, but this method returns the desc data, too
+ return self.desc_data
# --- end of readfile (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-01 15:46 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-01 15:46 UTC (permalink / raw
To: gentoo-commits
commit: ac0b226fd7d16dad7a4b8d30b4293fe401406c1c
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 1 14:56:09 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 1 14:56:09 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ac0b226f
2012-01-06:
* description field definition is now configurable
modified: roverlay/__init__.py
modified: roverlay/config.py
new file: roverlay/const.py
modified: roverlay/descriptionfields.py
renamed: roverlay/fileio.py -> roverlay/descriptionreader.py
modified: roverlay/ebuild.py
modified: roverlay/ebuildjob.py
deleted: roverlay/tmpconst.py
---
roverlay/__init__.py | 5 +
roverlay/config.py | 164 ++++++++++++-
roverlay/const.py | 51 ++++
roverlay/descriptionfields.py | 343 +++++++++++++++++++++++---
roverlay/{fileio.py => descriptionreader.py} | 248 ++++++-------------
roverlay/ebuild.py | 5 +-
roverlay/ebuildjob.py | 15 +-
roverlay/tmpconst.py | 108 --------
8 files changed, 615 insertions(+), 324 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index b1557ef..f50cec9 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -4,6 +4,11 @@
import logging
+
+from roverlay import config
+
+config.access().load_field_definition ( 'description_fields.conf' )
+
logging.basicConfig (
level=logging.DEBUG,
filename='roverlay.log',
diff --git a/roverlay/config.py b/roverlay/config.py
index 248fc22..b0bf7a3 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -3,20 +3,53 @@
# Distributed under the terms of the GNU General Public License v2
import sys
-
-from roverlay import descriptionfields
+import shlex
try:
import configparser
-except ImportError:
+except ImportError as running_python2:
+ # configparser is named ConfigParser in python2
import ConfigParser as configparser
+
+
+
+from roverlay import descriptionfields
+from roverlay import const
+
+
+
+
def access():
+ """Returns the ConfigTree."""
return ConfigTree() if ConfigTree.instance is None else ConfigTree.instance
+# --- end of access (...) ---
+
+
+def get ( key, fallback_value=None ):
+ """Searches for key in the ConfigTree and returns its value if possible,
+ else fallback_value.
+ 'key' is a config path [<section>[.<subsection>*]]<option name>.
+
+ arguments:
+ * key --
+ * fallback_value --
+ """
+ if fallback_value:
+ return access().get ( key, fallback_value )
+ else:
+ return access().get ( key )
+# --- end of get (...) ---
+
class InitialLogger:
def __init__ ( self ):
+ """Initializes an InitialLogger.
+ It implements the debug/info/warning/error/critical/exception methods
+ known from the logging module and its output goes directly to sys.stderr.
+ This can be used until the real logging has been configured.
+ """
self.debug = lambda x : sys.stderr.write ( "DBG " + str ( x ) + "\n" )
self.info = lambda x : sys.stderr.write ( "INFO " + str ( x ) + "\n" )
self.warning = lambda x : sys.stderr.write ( "WARN " + str ( x ) + "\n" )
@@ -24,11 +57,23 @@ class InitialLogger:
self.critical = lambda x : sys.stderr.write ( "CRIT " + str ( x ) + "\n" )
self.exception = lambda x : sys.stderr.write ( "EXC! " + str ( x ) + "\n" )
+ # --- end of __init__ (...) ---
+
class ConfigTree:
# static access to the first created ConfigTree
instance = None
- def __init__ ( self ):
+ def __init__ ( self, import_const=True ):
+ """Initializes an ConfigTree, which is a container for options/config values.
+ values can be stored directly (such as the field_definitions) or in a
+ tree-like { section -> subsection[s] -> option = value } structure.
+ Config keys cannot contain dots because they're used as config path
+ separator.
+
+ arguments:
+ * import_const -- whether to deepcopy constants into the config tree or
+ not. Copying allows faster lookups.
+ """
if ConfigTree.instance is None:
ConfigTree.instance = self
@@ -36,8 +81,52 @@ class ConfigTree:
self.parser = dict()
+ self._config = const.clone() if import_const else None
+ self._const_imported = import_const
+ self._field_definitions = None
+
+ # --- end of __init__ (...) ---
+
+
+ def get ( self, key, fallback_value=None ):
+ """Searches for key in the ConfigTree and returns its value.
+ Searches in const if ConfigTree does not contain the requested key and
+ returns the fallback_value if key not found.
+
+ arguments:
+ * key --
+ * fallback_value --
+ """
+ if self._config:
+ config_path = key.split ( '.' )
+ config_path.reverse ()
+
+ config_position = self._config
+ while len ( config_path ) and config_position:
+ next_key = config_path.pop ()
+ if next_key in config_position:
+ config_position = config_position [next_key]
+ else:
+ config_position = None
+
+ if config_position:
+ return config_position
+
+ if self._const_imported:
+ return fallback_value
+ else:
+ return const.lookup ( key, fallback_value )
+
+ # --- end of get (...) ---
def load_field_definition ( self, def_file, lenient=False ):
+ """Loads a field definition file. Please see the example file for format
+ details.
+
+ arguments:
+ * def_file -- file (str) to read, this can be a list of str if lenient is True
+ * lenient -- if True: do not fail if a file cannot be read; defaults to False
+ """
if not 'field_def' in self.parser:
self.parser ['field_def'] = configparser.SafeConfigParser ( allow_no_value=True )
@@ -57,4 +146,71 @@ class ConfigTree:
self.logger.exception ( mshe )
raise
+ # --- end of load_field_definition (...) ---
+
+
+ def get_field_definition ( self, force_update=False ):
+ """Gets the field definition stored in this ConfigTree.
+
+ arguments:
+ * force_update -- enforces recreation of the field definition data.
+ """
+ if force_update or not self._field_definitions:
+ self._field_definitions = self._make_field_definition ()
+
+ return self._field_definitions
+
+ # --- end of get_field_definition (...) ---
+
+
+ def _make_field_definition ( self ):
+ """Creates and returns field definition data. Please see the example
+ field definition config file for details.
+ """
+
+ def get_list ( value_str ):
+ if value_str is None:
+ return []
+ else:
+ l = value_str.split ( ', ' )
+ return [ e for e in l if e.strip() ]
+
+ if not 'field_def' in self.parser:
+ return None
+
+ fdef = descriptionfields.DescriptionFields ()
+
+ for field_name in self.parser ['field_def'].sections():
+ field = descriptionfields.DescriptionField ( field_name )
+ for option, value in self.parser ['field_def'].items ( field_name, 1 ):
+
+ if option == 'alias' or option == 'alias_withcase':
+ for alias in get_list ( value ):
+ field.add_simple_alias ( alias, True )
+
+ elif option == 'alias_nocase':
+ for alias in get_list ( value ):
+ field.add_simple_alias ( alias, False )
+
+ elif option == 'default_value':
+ field.set_default_value ( value )
+
+ elif option == 'allowed_value':
+ field.add_allowed_value ( value )
+
+ elif option == 'allowed_values':
+ for item in get_list ( value ):
+ field.add_allowed_value ( item )
+
+ elif option == 'flags':
+ for flag in get_list ( value ):
+ field.add_flag ( flag )
+ else:
+ # treat option as flag
+ field.add_flag ( option )
+
+ fdef.add ( field )
+
+ return fdef
+ # --- end of _make_field_definition (...) ---
diff --git a/roverlay/const.py b/roverlay/const.py
new file mode 100644
index 0000000..32630cf
--- /dev/null
+++ b/roverlay/const.py
@@ -0,0 +1,51 @@
+# R Overlay -- constants
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import copy
+import time
+
+_CONSTANTS = dict (
+ DESCRIPTION = dict (
+ field_separator = ':',
+ comment_char = '#',
+ list_split_regex = '\s*[,;]{1}\s*',
+ file_name = 'DESCRIPTION',
+ ),
+ R_PACKAGE = dict (
+ suffix_regex = '[.](tgz|tbz2|tar|(tar[.](gz|bz2)))',
+ name_ver_separator = '_',
+ ),
+ EBUILD = dict (
+ indent = '\t',
+ default_header = [ '# Copyright 1999-' + str ( time.gmtime() [0] ) + ' Gentoo Foundation',
+ '# Distributed under the terms of the GNU General Public License v2',
+ '# $Header: $',
+ '',
+ 'EAPI=4',
+ '',
+ 'inherit R-packages'
+ ],
+ )
+)
+
+def lookup ( key, fallback_value=None ):
+ path = key.split ( '.' )
+ path.reverse ()
+
+ const_position = _CONSTANTS
+
+ while len ( path ) and const_position:
+ next_key = path.pop ()
+ if next_key in const_position:
+ const_position = const_position [next_key]
+ else:
+ const_position = None
+
+ if const_position:
+ return const_position
+ else:
+ return fallback_value
+
+def clone ( ):
+ return copy.deepcopy ( _CONSTANTS )
diff --git a/roverlay/descriptionfields.py b/roverlay/descriptionfields.py
index 9c028c2..72175cb 100644
--- a/roverlay/descriptionfields.py
+++ b/roverlay/descriptionfields.py
@@ -2,39 +2,95 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-
-# split from tmpconst / fileio to make configuration possible, but TODO
-
class DescriptionField:
+ """Configuration for a field in the R package description file."""
def __init__ ( self, name ):
+ """Initializes a DescriptionField with a valid(!) name.
+
+ arguments:
+ * name -- name of the field, has to be True (neither empty nor None)
+
+ raises: Exception if name not valid
+ """
+
if not name:
raise Exception ( "description field name is empty." )
self.name = name
+ # --- end of __init__ (...) ---
def get_name ( self ):
+ """Returns the name of this DescriptionField."""
return self.name
- def add_flag ( self, flag, lowercase=True ):
- if not hasattr ( self, flags ):
+ # --- end of get_name (...) ---
+
+
+ def add_flag ( self, flag ):
+ """Adds a flag to this DescriptionField. Flags are always stored in
+ their lowercase form.
+
+ arguments:
+ * flag -- name of the flag
+ """
+ if not hasattr ( self, 'flags' ):
self.flags = set ()
- self.flags.add ( flag, flag.lower() if lowercase else flag )
+ self.flags.add ( flag.lower() )
return None
+ # --- end of add_flag (...) ---
+
+
+ def add_allowed_value ( self, value ):
+ """Adds an allowed value to this DescriptionField, which creates a
+ value whitelist for it. You can later check if a value is allowed using
+ value_allowed (<value> [, <case insensitive?>]).
+
+ arguments:
+ * value -- allowed value
+ """
+
+ if not hasattr ( self, 'allowed_values' ):
+ self.allowed_values = set ()
+
+ self.allowed_values.add ( value )
+
+ return None
+
+ # --- end of add_allowed_value (...) ---
+
def del_flag ( self, flag ):
- if hasattr ( self, flags ):
- self.flags.discard ( flag )
+ """Removes a flag from this DescriptionField. Does nothing if the flag
+ does not exist.
+ """
+ if hasattr ( self, 'flags' ):
+ self.flags.discard ( flag.lower() )
return None
+ # --- end of del_flag (...) ---
+
def add_alias ( self, alias, alias_type='withcase' ):
- if not hasattr ( self, aliases ):
+ """Adds an alias for this DescriptionField's name. This can also be used
+ to combine different fields ('Description' and 'Title') or to fix
+ typos ('Depend' -> 'Depends').
+
+ arguments:
+ * alias -- alias name
+ * alias_type -- type of the alias; currently this is limited to
+ 'withcase' : alias is case sensitive,
+ 'nocase' : alias is case insensitive
+ any other type leads to an error
+
+ raises: KeyError if alias_type unknown.
+ """
+ if not hasattr ( self, 'aliases' ):
self.aliases = dict ()
to_add = dict (
@@ -50,37 +106,83 @@ class DescriptionField:
return None
+ # --- end of add_alias (...) ---
def add_simple_alias ( self, alias, withcase=True ):
- if withcase:
- return self.add_alias ( alias, alias_type='withcase' )
- else:
- return self.add_alias ( alias, alias_type='nocase' )
+ """Adds an alias to this DescriptionField. Its type is either withcase
+ or nocase. See add_alias (...) for details.
+
+ arguments:
+ alias --
+ withcase -- if True (the default): alias_type is withcase, else nocase
+
+ raises: KeyError (passed from add_alias (...))
+ """
+ return self.add_alias ( alias, ( 'withcase' if withcase else 'nocase' ) )
+ # --- end of add_simple_alias (...) ---
def get_default_value ( self ):
- if hasattr ( self, 'default_value' ):
- return self.default_value
- else:
- return None
+ """Returns the default value for this DescriptionField if it exists,
+ else None.
+ """
+ return self.default_value if hasattr ( self, 'default_value' ) else None
+ # --- end of get_default_value (...) ---
+
+
+ def set_default_value ( self, value ):
+ """Sets the default value for this this DescriptionField.
+
+ arguments:
+ * value -- new default value
+ """
+ self.default_value = value
+
+ # --- end of set_default_value (...) ---
+
+
+ def get_flags ( self ):
+ """Returns the flags of this DescriptionField or an empty list (=no flags)."""
+ return self.flags if hasattr ( self, 'flags' ) else []
+
+ # --- end of get_flags (...) ---
+
+
+ def get_allowed_values ( self ):
+ """Returns the allowed values of this DescriptionField or an empty list,
+ which should be interpreted as 'no value restriction'.
+ """
+ return self.allowed_values if hasattr ( self, 'allowed_values' ) else []
+
+ # --- end of get_allowed_values (...) ---
- def get ( self, key, fallback_value=None ):
- if hasattr ( self, key ):
- return self.key
- else:
- return fallback_value
def matches ( self, field_identifier ):
+ """Returns whether field_identifier equals the name of this DescriptionField.
+
+ arguments:
+ * field_identifier --
+ """
return bool ( self.name == field_identifier ) if field_identifier else False
+ # --- end of matches (...) ---
+
+
def matches_alias ( self, field_identifier ):
+ """Returns whether field_identifier equals any alias of this DescriptionField.
+
+ arguments:
+ * field_identifier --
+ """
if not field_identifier:
+ # bad identifier
return False
- if not hasattr ( self, aliases ):
+ elif not hasattr ( self, aliases ):
+ # no aliases
return False
if 'withcase' in self.aliases:
@@ -92,30 +194,211 @@ class DescriptionField:
if field_id_lower in self.aliases ['nocase']:
return True
- def has_flag ( self, flag, lowercase=True ):
- if not hasattr ( self, flags ):
+ # --- end of matches_alias (...) ---
+
+
+ def has_flag ( self, flag ):
+ """Returns whether this DescriptionField has the given flag.
+
+ arguments:
+ * flag --
+ """
+ if not hasattr ( self, 'flags' ):
return False
- return bool ( (flag.lower() if lowercase else flag) in self.flags )
+ return bool ( flag.lower() in self.flags )
+
+ def value_allowed ( self, value, nocase=True ):
+ """Returns whether value is allowed for this DescriptionField.
+
+ arguments:
+ * value -- value to check
+ * nocase -- if True (the default): be case insensitive
+ """
+ allowed_values = self.get_allowed_values ()
+
+ if not allowed_values:
+ return True
+ elif nocase:
+ lowval = value.lower()
+ for allowed in allowed_values:
+ if allowed.lower() == lowval:
+ return True
+
+ else:
+ return bool ( value in allowed_values )
+
+ return False
+
+ # --- end of has_flag (...) ---
+
+# --- end of DescriptionField ---
+
class DescriptionFields:
+ """DescriptionFields stores several instances of DescriptionField and provides
+ 'search in all' methods such as get_fields_with_flag (<flag>).
+ """
def __init__ ( self ):
- fields = dict ()
+ """Initializes an DescriptionFields object."""
+ self.fields = dict ()
+ # result 'caches'
+ ## flag -> [<fields>]
+ self._fields_by_flag = None
+ ## option -> [<fields>]
+ self._fields_by_option = None
+
+ # --- end of __init__ (...) ---
+
def add ( self, desc_field ):
+ """Adds an DescriptionField. Returns 1 desc_field was a DescriptionField
+ and has been added as obj ref, 2 if a new DescriptionField with
+ name=desc_field has been created and added and 0 if this was not
+ possible.
+
+ arguments:
+ * desc_field -- this can either be a DescriptionField or a name.
+ """
if desc_field:
if isinstance ( desc_field, DescriptionField ):
- fields [desc_field.get_name()] = desc_field
+ self.fields [desc_field.get_name()] = desc_field
return 1
elif isinstance ( desc_field, str ):
- fields [desc_field] = DescriptionField ( desc_field )
+ self.fields [desc_field] = DescriptionField ( desc_field )
return 2
return 0
+ # --- end of add (...) ---
+
+
def get ( self, field_name ):
+ """Returns the DescriptionField to which field_name belongs to.
+ This method does, unlike others in DescriptionFields, return a
+ reference to the matching DescriptionField object, not the field name!
+ Returns None if field_name not found.
+
+ arguments:
+ * field_name --
+ """
+
return self.fields [field_name] if field_name in self.fields else None
- # ... TODO
+ # --- end of get (...) ---
+
+
+ def find_field ( self, field_name ):
+ """Determines the name of the DescriptionField to which field_name belongs
+ to. Returns the name of the matching field or None.
+
+ arguments:
+ * field_name --
+ """
+
+ field = get ( field_name )
+ if field is None:
+ for field in self.fields:
+ if field.matches_alias ( field_name ):
+ return field.get_name ()
+ else:
+ return field.get_name ()
+
+ # --- end of find_field (...) ---
+
+
+ def _field_search ( self ):
+ """Scans all stored DescriptionField(s) and creates fast-accessible
+ data to be used in get_fields_with_<sth> (...).
+ """
+ flagmap = dict ()
+ optionmap = dict (
+ defaults = dict (),
+ allowed_values = set ()
+ )
+
+ for field_name in self.fields.keys():
+
+ d = self.fields [field_name].get_default_value()
+ if not d is None:
+ optionmap ['defaults'] [field_name] = d
+
+ if self.fields [field_name].get_allowed_values():
+ optionmap ['allowed_values'].add ( field_name )
+
+ for flag in self.fields [field_name].get_flags():
+ if not flag in flagmap:
+ flagmap [flag] = set ()
+ flagmap [flag].add ( field_name )
+
+ self._fields_by_flag = flagmap
+ self._fields_by_option = optionmap
+ return None
+
+ # --- end of _field_search (...) ---
+
+
+ def get_fields_with_flag ( self, flag, force_update=False ):
+ """Returns the names of the fields that have the given flag.
+
+ arguments:
+ * flag --
+ * force_update -- force recreation of data
+ """
+ if force_update or self._fields_by_flag is None:
+ self._field_search ()
+
+ flag = flag.lower()
+
+ if flag in self._fields_by_flag:
+ return self._fields_by_flag [flag]
+ else:
+ return []
+
+ # --- end of get_fields_with_flag (...) ---
+
+
+ def get_fields_with_option ( self, option, force_update=False ):
+ """Returns a struct with fields that have the given option. The actual
+ data type depends on the requested option.
+
+ arguments:
+ * option --
+ * force_update -- force recreation of data
+ """
+ if force_update or self._fields_by_option is None:
+ self._field_search ()
+
+ if option in self._fields_by_option:
+ return self._fields_by_option [option]
+ else:
+ return []
+
+ # --- end of get_field_with_option (...) ---
+
+
+ def get_fields_with_default_value ( self, force_update=False ):
+ """Returns a dict { '<field name>' -> '<default value>' } for all
+ fields that have a default value.
+
+ arguments:
+ * force_update -- force recreation of data
+ """
+ return self.get_fields_with_option ( 'defaults', force_update )
+
+ # --- end of get_fields_with_default_value (...) ---
+
+
+ def get_fields_with_allowed_values ( self, force_update=False ):
+ """Returns a set { <field name> } for all fields that allow only
+ certain values.
+
+ arguments:
+ * force_update -- force recreation of data
+ """
+ return self.get_fields_with_option ( 'allowed_values', force_update )
+
+ # --- end of get_fields_with_allowed_values (...) ---
+# --- end of DescriptionFields ---
diff --git a/roverlay/fileio.py b/roverlay/descriptionreader.py
similarity index 54%
rename from roverlay/fileio.py
rename to roverlay/descriptionreader.py
index 5c01527..2af4372 100644
--- a/roverlay/fileio.py
+++ b/roverlay/descriptionreader.py
@@ -1,4 +1,4 @@
-# R Overlay -- file in/out
+# R Overlay -- description reader
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
@@ -7,21 +7,25 @@ import tarfile
import logging
import os.path
-
-# temporary import until config and real constants are implemented
-from roverlay import tmpconst as const
+from roverlay import config
+from roverlay import descriptionfields
class DescriptionReader:
"""Description Reader"""
LOGGER = logging.getLogger ( 'DescriptionReader' )
+
def __init__ ( self, package_file, read_now=False ):
"""Initializes a DESCRIPTION file reader."""
- self.fileinfo = self.make_fileinfo ( package_file )
- self.logger = DescriptionReader.LOGGER.getChild ( self.get_log_name() )
- self.desc_data = None
+ if not config.access().get_field_definition():
+ raise Exception ( "Field definition is missing, cannot initialize DescriptionReader." )
+
+ self.field_definition = config.access().get_field_definition()
+ self.fileinfo = self.make_fileinfo ( package_file )
+ self.logger = DescriptionReader.LOGGER.getChild ( self.get_log_name() )
+ self.desc_data = None
if read_now:
@@ -30,10 +34,13 @@ class DescriptionReader:
# --- end of __init__ (...) ---
def get_log_name ( self ):
+ """Returns a logging name that can be used in other modules."""
try:
return self.fileinfo ['filename']
except Exception as any_exception:
return '__undef__'
+ # --- end of get_log_name (...) ---
+
def get_desc ( self, run_if_unset=True ):
if self.desc_data is None:
@@ -58,10 +65,11 @@ class DescriptionReader:
package_file = os.path.basename ( filepath )
- filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
+ filename = re.sub ( config.get ( 'R_PACKAGE.suffix_regex' ) + '$', '', package_file )
- # todo move that separator to const
- package_name, sepa, package_version = filename.partition ( '_' )
+ package_name, sepa, package_version = filename.partition (
+ config.get ( 'R_PACKAGE.name_ver_separator', '_' )
+ )
if not sepa:
# file name unexpected, tarball extraction will (probably) fail
@@ -78,7 +86,6 @@ class DescriptionReader:
# --- end of make_fileinfo (...) ---
-
def _parse_read_data ( self, read_data ):
"""Verifies and parses/fixes read data.
@@ -86,80 +93,42 @@ class DescriptionReader:
* read_data -- data from file, will be modified
"""
- def get_fields_with_flag ( flag, foce_update=False ):
-
- matching_fields = []
-
- field = None
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if flag is None:
- matching_fields.append ( field )
-
- elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
- if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
- matching_fields.append ( field )
-
- del field
- return matching_fields
-
- # --- end of get_fields_with_flag (...) ---
-
- def value_in_strlist ( _val, _list, case_insensitive=True ):
- """Returns true if value is in the given list."""
- el = None
- if case_insensitive:
- lowval = _val.lower()
- for el in _list:
- if el.lower() == lowval:
- return True
- del lowval
- else:
- for el in _list:
- if el == _val:
- return True
-
- del el
- return False
- # --- end of value_in_strlist (...) ---
-
- field = None
# insert default values
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if not field in read_data and 'default_value' in const.DESCRIPTION_FIELD_MAP [field]:
- read_data [field] = const.DESCRIPTION_FIELD_MAP [field] ['default_value']
+ default_values = self.field_definition.get_fields_with_default_value()
+ for field_name in default_values.keys():
+ if not field_name in read_data:
+ read_data [field_name] = default_values [field_name]
+
# join values to a single string
- for field in get_fields_with_flag ( 'joinValues' ):
- if field in read_data.keys():
- read_data [field] = ' ' . join ( read_data [field] )
+ for field_name in self.field_definition.get_fields_with_flag ( 'joinValues' ):
+ print ( "?, ".join ( [ field_name, 'join', str ( read_data ) ] ) )
+ if field_name in read_data:
+ read_data [field_name] = ' ' . join ( read_data [field_name] )
# ensure that all mandatory fields are set
- missing_fields = list()
+ missing_fields = set ()
- for field in get_fields_with_flag ( 'mandatory' ):
- if field in read_data:
- if not len (read_data [field]):
- missing_fields.append ( field )
+ for field_name in self.field_definition.get_fields_with_flag ( 'mandatory' ):
+ if field_name in read_data:
+ if read_data [field_name] is None or len ( read_data [field_name] ) < 1:
+ missing_fields.add ( field_name )
+ #else: ok
else:
- missing_fields.append ( field )
-
-
+ missing_fields.add ( field_name )
# check for fields that allow only certain values
- unsuitable_fields = dict()
+ unsuitable_fields = set()
- for field in read_data.keys():
- if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
- if not value_in_strlist (
- read_data [field],
- const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
- ):
- unsuitable_fields.append [field] = read_data [field]
-
- del field
+ restricted_fields = self.field_definition.get_fields_with_allowed_values()
+ for field_name in restricted_fields:
+ if field_name in read_data:
+ if not self.field_definition.get ( field_name ).value_allowed ( read_data [field_name] ):
+ unsuitable_fields.add ( field_name )
+ # summarize results
valid = not bool ( len ( missing_fields ) or len ( unsuitable_fields ) )
if not valid:
self.logger.info ( "Cannot use R package" ) # name?
@@ -200,27 +169,6 @@ class DescriptionReader:
multiple values arranged in a list (dep0, dep1 [, depK]*).
"""
- def check_fieldflag ( field, flag_to_check=None ):
- """Checks if the given field has the specified flag and returns a bool.
-
- arguments:
- * field -- name of the field that should be checked
- * flag_to_check -- name of the flag to check; optional, defaults to None
-
- This method acts as 'field has any flags?' if flag_to_check is None (its default value).
- """
-
- if field in const.DESCRIPTION_FIELD_MAP:
- if 'flags' in const.DESCRIPTION_FIELD_MAP [field]:
- if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']:
- return True
- elif flag_to_check is None:
- # 'flags' exist, return true
- return True
-
- return False
- # --- end of check_fieldflag (...) ---
-
svalue_str = value_str.strip()
if not svalue_str:
@@ -231,16 +179,17 @@ class DescriptionReader:
# default return if no context given
return [ svalue_str ]
- elif check_fieldflag ( field_context ):
- # value str is not empty and have flags for field_context, check these
-
- if check_fieldflag ( field_context, 'isList' ):
- # split up this list (that is separated by commata and/or semicolons)
- return re.split (const.DESCRIPTION_LIST_SPLIT_REGEX, svalue_str, 0)
+ elif field_context in self.field_definition.get_fields_with_flag ( 'isList' ):
+ # split up this list (that is separated by commata and/or semicolons)
+ return re.split (
+ config.get ( 'DESCRIPTION.list_split_regex' ),
+ svalue_str,
+ 0
+ )
- elif check_fieldflag ( field_context, 'isWhitespaceList' ):
- # split up this list (that is separated whitespace)
- return re.split ( '\s+', svalue_str, 0 )
+ elif field_context in self.field_definition.get_fields_with_flag ( 'isWhitespaceList' ):
+ # split up this list (that is separated whitespace)
+ return re.split ( '\s+', svalue_str, 0 )
# default return
@@ -275,9 +224,12 @@ class DescriptionReader:
# filepath is a tarball, open tar handle + file handle
th = tarfile.open ( filepath, 'r' )
if pkg_name:
- fh = th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_FILE_NAME ) )
+ fh = th.extractfile ( os.path.join (
+ pkg_name,
+ config.get ( 'DESCRIPTION.file_name' )
+ ) )
else:
- fh = th.extractfile ( const.DESCRIPTION_FILE_NAME )
+ fh = th.extractfile ( config.get ( 'DESCRIPTION.file_name' ) )
# have to decode the lines
read = lambda lines : [ line.decode().rstrip() for line in lines ]
@@ -298,60 +250,9 @@ class DescriptionReader:
# --- end of get_desc_from_file (...) ---
- def find_field ( field_identifier ):
- """Determines the real name of a field.
-
- arguments:
- * field_identifier -- name of the field as it appears in the DESCRIPTION file
-
- At first, it is checked whether field_identifier matches the name of
- a field listed in DESCRIPTION_FIELD_MAP (any match results in immediate return).
- Then, a new iteration over the field map compares field_identifier
- with all aliases until the first case-(in)sensitive match (-> immediate return).
- None will be returned if none of the above searches succeed.
-
- In other words: this method decides whether a field_identifier will be used and if so,
- with which name.
- """
-
- # save some time by prevent searching if field_id is empty
- if not field_identifier:
- return None
-
- # search for real field names first
- for field in const.DESCRIPTION_FIELD_MAP.keys():
- if field_identifier == field:
- return field
-
- field_id_lower = field_identifier.lower()
-
- for field in const.DESCRIPTION_FIELD_MAP.keys():
-
- # does extra information (-> alias(es)) for this field exist?
- if 'alias' in const.DESCRIPTION_FIELD_MAP [field]:
-
- if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
- for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withcase']:
- if field_identifier == alias:
- return field
-
- if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
- for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocase']:
- if field_id_lower == alias.lower():
- return field
-
- #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['alias']:
-
- # returning None if no valid field identifier matches
- return None
-
- # --- end of find_field (...) ---
-
-
self.desc_data = None
read_data = dict ()
-
try:
desc_lines = get_desc_from_file (
self.fileinfo ['filepath'],
@@ -362,14 +263,15 @@ class DescriptionReader:
self.logger.exception ( err )
return self.desc_data
+ field_context = None
- field_context = val = line = sline = None
for line in desc_lines:
+ field_context_ref = None
# using s(tripped)line whenever whitespace doesn't matter
sline = line.lstrip()
- if (not sline) or (line [0] == const.DESCRIPTION_COMMENT_CHAR):
+ if (not sline) or (line [0] == config.get ( 'DESCRIPTION.comment_char' ) ):
# empty line or comment
pass
@@ -389,14 +291,26 @@ class DescriptionReader:
# line introduces a new field context, forget last one
field_context = None
- line_components = sline.partition ( const.DESCRIPTION_FIELD_SEPARATOR )
+ line_components = sline.partition ( config.get ( 'DESCRIPTION.field_separator' ) )
if line_components [1]:
# line contains a field separator, set field context
- field_context = find_field ( line_components [0] )
+ field_context_ref = self.field_definition.get ( line_components [0] )
+
+ if field_context_ref is None:
+ # useless line, skip
+ self.logger.info ( "Skipped a description field: '%s'.", line_components [0] )
+ elif field_context_ref.has_flag ( 'ignore' ):
+ # field ignored
+ self.logger.debug ( "Ignored field '%s'.", field_context )
+
+ else:
+ field_context = field_context_ref.get_name()
+
+ if not field_context:
+ raise Exception ( "Field name is not valid! This should've already been catched in DescriptionField..." )
- if field_context:
- # create a new empty list for field_context
+ # create a new empty list for this field_context
read_data [field_context] = []
# add values to read_data
@@ -404,9 +318,7 @@ class DescriptionReader:
for val in make_values ( line_components [2], field_context ):
read_data [field_context] . append ( val )
- else:
- # useless line, skip
- self.logger.info ( "Skipped a description field: '%s'.", line_components [0] )
+
else:
# reaching this branch means that
@@ -415,11 +327,7 @@ class DescriptionReader:
# this should not occur in description files (bad syntax?)
self.logger.warning ( "Unexpected line in description file: '%s'.", line_components [0] )
-
- del line_components
-
- del sline, line, val, field_context
-
+ # -- end for --
if self._parse_read_data ( read_data ):
self.logger.debug ( "Successfully read file '%s' with data = %s.",
@@ -430,4 +338,4 @@ class DescriptionReader:
# get_desc() is preferred, but this method returns the desc data, too
return self.desc_data
- # --- end of readfile (...) ---
+ # --- end of run (...) ---
diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
index 1634ef3..4493bb7 100644
--- a/roverlay/ebuild.py
+++ b/roverlay/ebuild.py
@@ -2,9 +2,10 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import roverlay.config
+
class Ebuild:
- # could move this to const
- EBUILD_INDENT = "\t"
+ EBUILD_INDENT = roverlay.config.get ( 'EBUILD.indent', '\t' )
ADD_REMAP = {
# pkg vs package
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index 0357e77..b6c9456 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -2,16 +2,18 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import time
import logging
import re
-from roverlay.fileio import DescriptionReader
+from roverlay.descriptionreader import DescriptionReader
from roverlay.ebuild import Ebuild
+from roverlay import config
class EbuildJob:
LOGGER = logging.getLogger ( 'EbuildJob' )
+ DEFAULT_EBUILD_HEADER = config.get ( 'EBUILD.default_header' )
+
# move this to const / config
DEPENDENCY_FIELDS = {
'R_SUGGESTS' : [ 'Suggests' ],
@@ -142,14 +144,7 @@ class EbuildJob:
## default ebuild header, could use some const here (eclass name,..)
ebuild.add ( 'ebuild_header',
- [ '# Copyright 1999-' + str ( time.gmtime() [0] ) + ' Gentoo Foundation',
- '# Distributed under the terms of the GNU General Public License v2',
- '# $Header: $',
- '',
- 'EAPI=4',
- '',
- 'inherit R-packages'
- ],
+ EbuildJob.DEFAULT_EBUILD_HEADER,
False
)
diff --git a/roverlay/tmpconst.py b/roverlay/tmpconst.py
deleted file mode 100644
index 8519aad..0000000
--- a/roverlay/tmpconst.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# R overlay -- constants (temporary file)
-# Copyright 2006-2012 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-# matches .tgz .tbz2 .tar .tar.gz .tar.bz2
-RPACKAGE_SUFFIX_REGEX = '[.](tgz|tbz2|tar|(tar[.](gz|bz2)))'
-
-PACKAGE_CATEGORY = 'sci-R'
-
-DESCRIPTION_FIELD_SEPARATOR = ':'
-
-DESCRIPTION_COMMENT_CHAR = '#'
-
-DESCRIPTION_LIST_SPLIT_REGEX = '\s*[,;]{1}\s*'
-
-DESCRIPTION_FILE_NAME = 'DESCRIPTION'
-
-# moved to <field> -> 'allowed_values'
-##DESCRIPTION_VALID_OS_TYPES = [ "unix" ]
-
-
-# note for 2012-05-25: make this struct more organized, assign real values
-"""The map of used fields in the DESCRIPTION file
-
- stores the real field name as well as field flags and aliases
- that can be case-sensitive (withcase) or not (nocase)
-
- access to these values is
- * for aliases
- DESCRIPTION_FIELD_MAP [<field name>] [alias] [case sensitive ? withcase : nocase] [<index>]
-
- * for flags
- DESCRIPTION_FIELD_MAP [<field name>] [flags] [<index>]
-
- * default values
- DESCRIPTION_FIELD_MAP [<field name>] [default_value]
-
- notable flags:
- * isList : indicates that this field has several values that are
- separated by commata/semicolons =:<DESCRIPTION_LIST_SPLIT_REGEX>
- this disables isWhitespaceList
-
- * isWhitespaceList : indicates that this field has several values separated
- by whitespace
-
- * joinValues : indicates that the values of this field should be concatenated
- after reading them (with a ' ' as separator)
- (this implies that the read values are one string)
-
- * mandatory : cannot proceed if a file does not contain this field (implies ignoring default values)
-
-"""
-
-DESCRIPTION_FIELD_MAP = {
- 'Description' : {
- 'flags' : [ 'joinValues' ],
- },
- 'Title' : {
- 'flags' : [ 'joinValues' ],
- },
- 'Package' : {
- 'flags' : [ 'joinValues' ],
- },
- 'License' : {
- 'flags' : [ 'isList' ],
- },
- 'Version' : {
- 'flags' : [ 'mandatory', 'joinValues' ]
- },
- 'Suggests' : {
- 'alias' : {
- 'nocase' : [ 'Suggests', 'Suggest',
- '%Suggests', 'Suggets', 'Recommends' ]
- },
- },
- 'Depends' : {
- 'alias' : {
- 'nocase' : [ 'Depends', 'Dependencies', 'Dependes',
- '%Depends', 'Depents', 'Require', 'Requires' ],
- },
- 'flags' : [ 'isList' ],
- 'default_value' : '',
- },
- 'Imports' : {
- 'alias' : {
- 'nocase' : [ 'Imports', 'Import' ]
- },
- },
- 'LinkingTo' : {
- 'alias' : {
- 'nocase' : [ 'LinkingTo', 'LinkingdTo' ]
- },
- },
- 'SystemRequirements' : {
- 'alias' : {
- 'nocase' : [ 'SystemRequirements', 'SystemRequirement' ]
- },
- },
- 'OS_Type' : {
- 'alias' : {
- 'nocase' : [ 'OS_TYPE' ]
- },
- 'allowed_values' : [ 'unix' ],
- },
- 'test-default' : {
- 'default_value' : 'some default value'
- }
-}
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-01 16:19 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-01 16:19 UTC (permalink / raw
To: gentoo-commits
commit: d0fa945b8c81fedbcc02dc3f1e3e824a5b7170cc
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 1 16:19:03 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 1 16:19:03 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d0fa945b
config: faster lookup
---
roverlay/config.py | 74 ++++++++++++++++++++++++++++++++++++++++++---------
roverlay/const.py | 15 +++-------
2 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index b0bf7a3..41a98bf 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -4,6 +4,7 @@
import sys
import shlex
+import copy
try:
import configparser
@@ -81,13 +82,36 @@ class ConfigTree:
self.parser = dict()
- self._config = const.clone() if import_const else None
+ self._config = const.clone() if import_const else dict ()
self._const_imported = import_const
self._field_definitions = None
# --- end of __init__ (...) ---
+ def _findpath ( self, path, root=None, create=False ):
+ if path is None:
+ return root
+ elif isinstance ( path, str ):
+ path = path.split ( '.' ) if key else []
+
+ config_position = self._config if root is None else root
+
+ for k in path:
+ if not k in config_position:
+ if create:
+ config_position [k] = dict ()
+
+ else:
+ return None
+
+ config_position = config_position [k]
+
+ return config_position
+
+ # --- end of _findpath (...) ---
+
+
def get ( self, key, fallback_value=None ):
"""Searches for key in the ConfigTree and returns its value.
Searches in const if ConfigTree does not contain the requested key and
@@ -98,19 +122,10 @@ class ConfigTree:
* fallback_value --
"""
if self._config:
- config_path = key.split ( '.' )
- config_path.reverse ()
-
- config_position = self._config
- while len ( config_path ) and config_position:
- next_key = config_path.pop ()
- if next_key in config_position:
- config_position = config_position [next_key]
- else:
- config_position = None
+ config_value = self._findpath ( key )
- if config_position:
- return config_position
+ if config_value:
+ return config_value
if self._const_imported:
return fallback_value
@@ -119,6 +134,39 @@ class ConfigTree:
# --- end of get (...) ---
+ def load_config ( self, config_file, start_section='' ):
+ """Loads a config file and integrates its content into the config tree.
+ Older config entries may be overwritten.
+
+ arguments:
+ config_file -- path to the file that should be read
+ start_section -- relative root in the config tree as str or ref
+ """
+
+ config_root = None
+ if start_section:
+ if isinstance ( start_section, str ):
+ config_root = self._findpath ( start_section, None, True )
+ elif isinstance ( start_section, dict ):
+ config_root = start_section
+ else
+ raise Exception ("bad usage")
+
+ # load file
+
+ try:
+ fh = open ( config_file, 'r' )
+ reader = shlex.shlex ( fh )
+ if fh:
+ fh.close ()
+
+ # <TODO>
+
+ except IOError as ioerr:
+ raise
+
+ # --- end of load_config (...) ---
+
def load_field_definition ( self, def_file, lenient=False ):
"""Loads a field definition file. Please see the example file for format
details.
diff --git a/roverlay/const.py b/roverlay/const.py
index 32630cf..527939b 100644
--- a/roverlay/const.py
+++ b/roverlay/const.py
@@ -31,21 +31,16 @@ _CONSTANTS = dict (
def lookup ( key, fallback_value=None ):
path = key.split ( '.' )
- path.reverse ()
const_position = _CONSTANTS
- while len ( path ) and const_position:
- next_key = path.pop ()
- if next_key in const_position:
- const_position = const_position [next_key]
+ for k in path:
+ if k in const_position:
+ const_position = const_position [k]
else:
- const_position = None
+ return fallback_value
- if const_position:
- return const_position
- else:
- return fallback_value
+ return const_position
def clone ( ):
return copy.deepcopy ( _CONSTANTS )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-01 16:19 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-01 16:19 UTC (permalink / raw
To: gentoo-commits
commit: 6571bf138322945ba7712479147516fd509fb255
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 1 16:18:44 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 1 16:18:44 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6571bf13
remove debug print in descriptionreader
---
roverlay/descriptionreader.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/descriptionreader.py b/roverlay/descriptionreader.py
index 2af4372..762dec0 100644
--- a/roverlay/descriptionreader.py
+++ b/roverlay/descriptionreader.py
@@ -103,7 +103,7 @@ class DescriptionReader:
# join values to a single string
for field_name in self.field_definition.get_fields_with_flag ( 'joinValues' ):
- print ( "?, ".join ( [ field_name, 'join', str ( read_data ) ] ) )
+
if field_name in read_data:
read_data [field_name] = ' ' . join ( read_data [field_name] )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-04 15:43 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-04 15:43 UTC (permalink / raw
To: gentoo-commits
commit: 346f15b80151811fb0813d5f14195ae8d73b4d61
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jun 4 15:42:50 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jun 4 15:42:50 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=346f15b8
roverlay, config: fix typo and add main config reader
modified: config.py
---
roverlay/config.py | 172 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 159 insertions(+), 13 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index 41a98bf..bce721c 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -2,9 +2,11 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import copy
+import os
+import re
import sys
import shlex
-import copy
try:
import configparser
@@ -13,8 +15,6 @@ except ImportError as running_python2:
import ConfigParser as configparser
-
-
from roverlay import descriptionfields
from roverlay import const
@@ -51,8 +51,8 @@ class InitialLogger:
known from the logging module and its output goes directly to sys.stderr.
This can be used until the real logging has been configured.
"""
- self.debug = lambda x : sys.stderr.write ( "DBG " + str ( x ) + "\n" )
- self.info = lambda x : sys.stderr.write ( "INFO " + str ( x ) + "\n" )
+ self.debug = lambda x : sys.stdout.write ( "DBG " + str ( x ) + "\n" )
+ self.info = lambda x : sys.stdout.write ( "INFO " + str ( x ) + "\n" )
self.warning = lambda x : sys.stderr.write ( "WARN " + str ( x ) + "\n" )
self.error = lambda x : sys.stderr.write ( "ERR " + str ( x ) + "\n" )
self.critical = lambda x : sys.stderr.write ( "CRIT " + str ( x ) + "\n" )
@@ -64,6 +64,25 @@ class ConfigTree:
# static access to the first created ConfigTree
instance = None
+ # the list of 'normal' config entries (no special config path) (in lowercase)
+ # the map of config entries
+ CONFIG_ENTRY_MAP = dict (
+ log_level = '',
+ log_console = dict (
+ value_type = 'yesno',
+ ),
+ log_file = dict (
+ value_type = 'fs_file',
+ ),
+ ebuild_header = dict (
+ value_type = 'fs_file',
+ )
+
+ )
+
+ DEFAULT_LIST_REGEX = re.compile ( '\s*[,;]{1}\s*' )
+ WHITESPACE = re.compile ( '\s+' )
+
def __init__ ( self, import_const=True ):
"""Initializes an ConfigTree, which is a container for options/config values.
values can be stored directly (such as the field_definitions) or in a
@@ -89,19 +108,18 @@ class ConfigTree:
# --- end of __init__ (...) ---
- def _findpath ( self, path, root=None, create=False ):
+ def _findpath ( self, path, root=None, create=False, value=None ):
if path is None:
return root
elif isinstance ( path, str ):
- path = path.split ( '.' ) if key else []
+ path = path.split ( '.' ) if path else []
config_position = self._config if root is None else root
for k in path:
if not k in config_position:
if create:
- config_position [k] = dict ()
-
+ config_position [k] = value if k == path [-1] and value else dict ()
else:
return None
@@ -134,22 +152,130 @@ class ConfigTree:
# --- end of get (...) ---
+ def _add_entry ( self, option, value=None, config_root=None ):
+
+ def make_and_verify_value ( value_type, value, entryconfig_ref ):
+
+ def to_int ( val, fallback_value=-1 ):
+ try:
+ ret = int ( val )
+ return ret
+ except ValueError as verr:
+ return fallback_value
+ # --- end of to_int (...) ---
+
+ def yesno ( val ):
+ if not val is None:
+ to_check = str ( val ) . lower ()
+ if to_check in [ 'y', 'yes', '1', 'true', 'enabled', 'on' ]:
+ return 1
+ elif to_check in [ 'n', 'no', '0', 'false', 'disabled', 'off' ]:
+ return 0
+
+ self.logger.warning ( to_check + " is not a valid yesno value." )
+ return -1
+ # --- end of yesno (...) ---
+
+ value = ConfigTree.WHITESPACE.sub ( ' ', value )
+
+ if not value_type:
+ return value
+ elif isinstance ( value_type, list ):
+ vtypes = value_type
+ elif isinstance ( value_type, str ):
+ vtypes = value_type.split ( ':' )
+ else:
+ self.logger.error ( "Unknown data type for value type." )
+ return value
+
+ retval = value
+ is_list = False
+ for vtype in vtypes:
+ if vtype == 'list':
+ retval = ConfigTree.DEFAULT_LIST_REGEX.split ( retval )
+ is_list = True
+ elif vtype == 'slist':
+ retval = ConfigTree.WHITESPACE.split ( retval )
+ is_list = True
+ elif vtype == 'yesno':
+ retval = [ yesno ( x ) for x in retval ] if is_list else yesno ( retval )
+ elif vtype == 'int':
+ retval = [ to_int ( x ) for x in retval ] if is_list else to_int ( retval )
+
+ else:
+ self.logger.warning ( "unknown value type '" + vtype + "'." )
+
+ return retval
+ # --- end of make_and_verify_value (...) ---
+
+
+ real_option = option
+ low_option = option.lower()
+ if option and low_option in ConfigTree.CONFIG_ENTRY_MAP:
+ cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
+
+ if isinstance ( cref, str ) and cref in ConfigTree.CONFIG_ENTRY_MAP:
+ option = low_option = cref
+ cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
+
+ if cref is None:
+ # deftly ignored
+ return True
+
+
+
+ path = None
+ if 'path' in cref:
+ path = cref ['path']
+ else:
+ path = low_option.split ( '_' )
+ for n in range ( len ( path ) - 1 ):
+ path [n] = path [n].upper()
+
+
+ if path:
+
+ if 'value_type' in cref:
+ value = make_and_verify_value ( cref ['value_type'], value, cref )
+
+ if value:
+
+ self.logger.debug (
+ "New config entry " + str ( option ) +
+ " with path " + str ( path ) +
+ " and value " + str ( value ) + "."
+ )
+
+ self._findpath ( path, config_root, True, value )
+
+ return True
+ else:
+ self.logger.error (
+ "Option '" + str ( real_option ) +
+ "' has an unusable value '" + str ( value ) + "'."
+ )
+ # ---
+ # ---
+
+ self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown." )
+ return False
+
+ # --- end of _add_entry (...) ---
+
def load_config ( self, config_file, start_section='' ):
"""Loads a config file and integrates its content into the config tree.
Older config entries may be overwritten.
arguments:
config_file -- path to the file that should be read
- start_section -- relative root in the config tree as str or ref
+ start_section -- relative root in the config tree as str
"""
config_root = None
if start_section:
if isinstance ( start_section, str ):
config_root = self._findpath ( start_section, None, True )
- elif isinstance ( start_section, dict ):
- config_root = start_section
- else
+ else:
raise Exception ("bad usage")
# load file
@@ -157,6 +283,26 @@ class ConfigTree:
try:
fh = open ( config_file, 'r' )
reader = shlex.shlex ( fh )
+ reader.whitespace_split = False
+ reader.wordchars += ' ./$()[]:+-@*~'
+
+ nextline = lambda : ( reader.get_token() for n in range (3) )
+
+ option, equal, value = nextline ()
+
+ while equal == '=' or not ( option == value == reader.eof ):
+ if equal == '=':
+ self._add_entry ( option, value, config_root )
+ else:
+ self.logger.warning (
+ "In '" + config_file + "', cannot parse this line: '" +
+ str ( option ) + str ( equal ) + str ( value ) + "'."
+ )
+
+ option, equal, value = nextline ()
+
+
+
if fh:
fh.close ()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-04 19:07 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-04 19:07 UTC (permalink / raw
To: gentoo-commits
commit: 75c0874ffdaa074891506f759190b133a9490a4f
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jun 4 19:05:45 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jun 4 19:05:45 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=75c0874f
ebuildjob: metadata.xml todo
---
roverlay/ebuildjob.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index b6c9456..be8e5e3 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -100,7 +100,7 @@ class EbuildJob:
"""
# TODO move hardcoded entries to config/const
- # TODO metadata.xml creation
+ # TODO metadata.xml creation (long DESCRIPTION should go into metadata, not the ebuild)
try:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-04 19:07 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-04 19:07 UTC (permalink / raw
To: gentoo-commits
commit: 0070a7fb77e1be78cb49cbd043987b9cc87ba50b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jun 4 19:06:52 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jun 4 19:06:52 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0070a7fb
config.py: config entry value types explained
---
roverlay/config.py | 62 +++++++++++++++++++++++++++++++++++++++------------
1 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index bce721c..ab6dfec 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -3,7 +3,7 @@
# Distributed under the terms of the GNU General Public License v2
import copy
-import os
+import os.path
import re
import sys
import shlex
@@ -64,8 +64,21 @@ class ConfigTree:
# static access to the first created ConfigTree
instance = None
- # the list of 'normal' config entries (no special config path) (in lowercase)
- # the map of config entries
+ # the map of config entries (keep keys in lowercase)
+ # * value_type, you can specify:
+ # ** slist (whitespace-separated list)
+ # ** list (see DEFAULT_LIST_REGEX below)
+ # ** int
+ # ** yesno
+ # ** fs_path (~ will be expanded)
+ # ** fs_file (fs_path + must be a file if it exists)
+ #
+ # multiple types are generally not supported ('this is an int or a str'),
+ # but subtypes are (list of yesno), which can be specified by either
+ # using a list of types ['list', 'yesno'] or by separating the types
+ # with a colon list:yesno, which is parsed in a left-to-right order.
+ # Nested subtypes such as list:slist:int:fs_file:list may lead to errors.
+ #
CONFIG_ENTRY_MAP = dict (
log_level = '',
log_console = dict (
@@ -176,6 +189,19 @@ class ConfigTree:
return -1
# --- end of yesno (...) ---
+ def fs_path ( val ):
+ return os.path.expanduser ( val ) if val else None
+ # --- end of fs_path (...) ---
+
+ def fs_file ( val ):
+ if val:
+ retval = os.path.expanduser ( val )
+ if os.path.isfile ( retval ) or not os.path.exists ( retval ):
+ return retval
+
+ return None
+ # --- end of fs_file (...) ---
+
value = ConfigTree.WHITESPACE.sub ( ' ', value )
if not value_type:
@@ -188,23 +214,29 @@ class ConfigTree:
self.logger.error ( "Unknown data type for value type." )
return value
+ # value_type -> function where function accepts one parameter
+ funcmap = {
+ 'list' : ConfigTree.DEFAULT_LIST_REGEX.split,
+ 'slist' : ConfigTree.WHITESPACE.split,
+ 'yesno' : yesno,
+ 'int' : to_int,
+ 'fs_path' : fs_path,
+ 'fs_file' : fs_file,
+ }
+
+ # dofunc ( function f, <list or str> v) calls f(x) for every str in v
+ dofunc = lambda f, v : [ f(x) for x in v ] if isinstance ( v, list ) else f(v)
+
+
retval = value
- is_list = False
- for vtype in vtypes:
- if vtype == 'list':
- retval = ConfigTree.DEFAULT_LIST_REGEX.split ( retval )
- is_list = True
- elif vtype == 'slist':
- retval = ConfigTree.WHITESPACE.split ( retval )
- is_list = True
- elif vtype == 'yesno':
- retval = [ yesno ( x ) for x in retval ] if is_list else yesno ( retval )
- elif vtype == 'int':
- retval = [ to_int ( x ) for x in retval ] if is_list else to_int ( retval )
+ for vtype in vtypes:
+ if vtype in funcmap:
+ retval = dofunc ( funcmap [vtype], retval )
else:
self.logger.warning ( "unknown value type '" + vtype + "'." )
+
return retval
# --- end of make_and_verify_value (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-05 17:30 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-05 17:30 UTC (permalink / raw
To: gentoo-commits
commit: 85bca473d98e6c1e9217b299d54fa3499b407e3c
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jun 5 17:18:34 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jun 5 17:18:34 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=85bca473
config: comments and config entry map
modified: roverlay/config.py
---
roverlay/config.py | 133 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 116 insertions(+), 17 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index ab6dfec..424e69f 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -2,7 +2,6 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import copy
import os.path
import re
import sys
@@ -89,13 +88,21 @@ class ConfigTree:
),
ebuild_header = dict (
value_type = 'fs_file',
- )
+ ),
+ overlay_dir = dict (
+ value_type = 'fs_dir',
+ ),
+ distfiles_dir = dict (
+ value_type = 'fs_dir',
+ ),
)
+ # often used regexes
DEFAULT_LIST_REGEX = re.compile ( '\s*[,;]{1}\s*' )
WHITESPACE = re.compile ( '\s+' )
+
def __init__ ( self, import_const=True ):
"""Initializes an ConfigTree, which is a container for options/config values.
values can be stored directly (such as the field_definitions) or in a
@@ -122,6 +129,17 @@ class ConfigTree:
def _findpath ( self, path, root=None, create=False, value=None ):
+ """All-in-one method that searches for a config path.
+ It is able to create the path if non-existent and to assign a
+ value to it.
+
+ arguments:
+ * path -- config path as path list ([a,b,c]) or as path str (a.b.c)
+ * root -- config root (dict expected). Uses self._config if None (the default)
+ * create -- create path if nonexistent
+ * value -- assign value to the last path element
+ an empty dict will be created if this is None and create is True
+ """
if path is None:
return root
elif isinstance ( path, str ):
@@ -166,10 +184,36 @@ class ConfigTree:
# --- end of get (...) ---
def _add_entry ( self, option, value=None, config_root=None ):
+ """Adds an option to the config.
+
+ arguments:
+ * option -- name of the option as it appears in the (main) config file
+ * value -- value to assign, defaults to None
+ * config_root -- root of the config (a dict), defaults to None which is
+ later understood as self._config
+ """
def make_and_verify_value ( value_type, value, entryconfig_ref ):
+ """Prepares the value of a config option so that it can be used
+ in the ConfigTree.
+
+ arguments:
+ * value_type -- type of the value, look above for explanation concerning this
+ * value -- value to verify and transform
+ * entryconfig_ref -- reference to the config entry config
+ """
def to_int ( val, fallback_value=-1 ):
+ """Tries to convert val to an int, returning a fallback value
+ on any error.
+
+ arguments:
+ * val --
+ * fallback_value --
+
+ catches: ValueError in case of an unsuccesful int conversion
+ raises: nothing
+ """
try:
ret = int ( val )
return ret
@@ -178,6 +222,13 @@ class ConfigTree:
# --- end of to_int (...) ---
def yesno ( val ):
+ """Tries to canonize an yes or no value to its integer
+ representation. Returns 1 if val means 'yes', 0 if 'no' and
+ -1 otherwise.
+
+ arguments:
+ * val --
+ """
if not val is None:
to_check = str ( val ) . lower ()
if to_check in [ 'y', 'yes', '1', 'true', 'enabled', 'on' ]:
@@ -190,10 +241,21 @@ class ConfigTree:
# --- end of yesno (...) ---
def fs_path ( val ):
+ """val is a filesystem path - returns expanded path (~ -> HOME).
+
+ arguments:
+ * val --
+ """
return os.path.expanduser ( val ) if val else None
# --- end of fs_path (...) ---
def fs_file ( val ):
+ """"val is a file - returns expanded path if it is an existent
+ file or it does not exist.
+
+ arguments:
+ * val --
+ """
if val:
retval = os.path.expanduser ( val )
if os.path.isfile ( retval ) or not os.path.exists ( retval ):
@@ -202,8 +264,25 @@ class ConfigTree:
return None
# --- end of fs_file (...) ---
+ def fs_dir ( val ):
+ """val is a directory -- returns expanded path if it is an existent
+ dir or it does not exist.
+
+ arguments:
+ * val --
+ """
+ if val:
+ retval = os.path.expanduser ( val )
+ if os.path.isdir ( retval ) or not os.path.exists ( retval ):
+ return retval
+
+ return None
+ # --- end of fs_dir (...) ---
+
+ # replace whitespace with a single ' '
value = ConfigTree.WHITESPACE.sub ( ' ', value )
+ # convert value_type into a list of value types
if not value_type:
return value
elif isinstance ( value_type, list ):
@@ -227,7 +306,6 @@ class ConfigTree:
# dofunc ( function f, <list or str> v) calls f(x) for every str in v
dofunc = lambda f, v : [ f(x) for x in v ] if isinstance ( v, list ) else f(v)
-
retval = value
for vtype in vtypes:
@@ -236,26 +314,43 @@ class ConfigTree:
else:
self.logger.warning ( "unknown value type '" + vtype + "'." )
-
return retval
# --- end of make_and_verify_value (...) ---
real_option = option
low_option = option.lower()
+
+ # known option?
if option and low_option in ConfigTree.CONFIG_ENTRY_MAP:
- cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
- if isinstance ( cref, str ) and cref in ConfigTree.CONFIG_ENTRY_MAP:
- option = low_option = cref
- cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
+ original_cref = cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
+ cref_level = 0
+
+ # check if cref is a link to another entry in CONFIG_ENTRY_MAP
+ while isinstance ( cref, str ):
+ if cref == original_cref and cref_level:
+ self.logger.critical ( "CONFIG_ENTRY_MAP is invalid! circular cref detected." )
+ raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
+
+ elif cref in ConfigTree.CONFIG_ENTRY_MAP:
+ option = low_option = cref
+ cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
+ cref_level += 1
+ else:
+ self.logger.critical (
+ "CONFIG_ENTRY_MAP is invalid! last cref = " + option +
+ ", current cref = " + cref + "."
+ )
+ raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
+ # check if config entry is disabled
if cref is None:
# deftly ignored
return True
-
+ # determine the config path
path = None
if 'path' in cref:
path = cref ['path']
@@ -264,12 +359,14 @@ class ConfigTree:
for n in range ( len ( path ) - 1 ):
path [n] = path [n].upper()
-
+ # need a valid path
if path:
+ # verify and convert value if value_type is set
if 'value_type' in cref:
value = make_and_verify_value ( cref ['value_type'], value, cref )
+ # need a valid value
if value:
self.logger.debug (
@@ -278,6 +375,7 @@ class ConfigTree:
" and value " + str ( value ) + "."
)
+ # add option/value to the config
self._findpath ( path, config_root, True, value )
return True
@@ -286,7 +384,11 @@ class ConfigTree:
"Option '" + str ( real_option ) +
"' has an unusable value '" + str ( value ) + "'."
)
+ return False
# ---
+
+ self.logger.error ( "Option '" + str ( real_option ) + "' is unusable..." )
+ return False
# ---
self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown." )
@@ -313,10 +415,11 @@ class ConfigTree:
# load file
try:
- fh = open ( config_file, 'r' )
- reader = shlex.shlex ( fh )
+ reader.wordchars += ' ./$()[]:+-@*~'
+ fh = open ( config_file, 'r' )
+ reader = shlex.shlex ( fh )
reader.whitespace_split = False
- reader.wordchars += ' ./$()[]:+-@*~'
+
nextline = lambda : ( reader.get_token() for n in range (3) )
@@ -333,13 +436,9 @@ class ConfigTree:
option, equal, value = nextline ()
-
-
if fh:
fh.close ()
- # <TODO>
-
except IOError as ioerr:
raise
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-06 19:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-06 19:52 UTC (permalink / raw
To: gentoo-commits
commit: 1f51ac4acac24633cba9d7a531c7165af7acd09d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 6 19:47:58 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 6 19:47:58 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1f51ac4a
descriptionfields.py: reduce function calls
modified: roverlay/descriptionfields.py
---
roverlay/descriptionfields.py | 60 +++++++++++++++++------------------------
1 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/roverlay/descriptionfields.py b/roverlay/descriptionfields.py
index 72175cb..710f0c0 100644
--- a/roverlay/descriptionfields.py
+++ b/roverlay/descriptionfields.py
@@ -19,6 +19,11 @@ class DescriptionField:
self.name = name
+ self.default_value = None
+ self.flags = list ()
+ self.allowed_values = list ()
+ self.aliases = dict ()
+
# --- end of __init__ (...) ---
@@ -36,10 +41,7 @@ class DescriptionField:
arguments:
* flag -- name of the flag
"""
- if not hasattr ( self, 'flags' ):
- self.flags = set ()
-
- self.flags.add ( flag.lower() )
+ self.flags.append ( flag.lower() )
return None
@@ -55,10 +57,7 @@ class DescriptionField:
* value -- allowed value
"""
- if not hasattr ( self, 'allowed_values' ):
- self.allowed_values = set ()
-
- self.allowed_values.add ( value )
+ self.allowed_values.append ( value )
return None
@@ -69,8 +68,7 @@ class DescriptionField:
"""Removes a flag from this DescriptionField. Does nothing if the flag
does not exist.
"""
- if hasattr ( self, 'flags' ):
- self.flags.discard ( flag.lower() )
+ self.flags.discard ( flag.lower() )
return None
# --- end of del_flag (...) ---
@@ -90,8 +88,6 @@ class DescriptionField:
raises: KeyError if alias_type unknown.
"""
- if not hasattr ( self, 'aliases' ):
- self.aliases = dict ()
to_add = dict (
withcase = alias,
@@ -100,9 +96,9 @@ class DescriptionField:
if not alias_type in self.aliases:
- self.aliases [alias_type] = set ()
+ self.aliases [alias_type] = list ()
- self.aliases [alias_type] . add ( to_add )
+ self.aliases [alias_type] . append ( to_add )
return None
@@ -128,7 +124,7 @@ class DescriptionField:
"""Returns the default value for this DescriptionField if it exists,
else None.
"""
- return self.default_value if hasattr ( self, 'default_value' ) else None
+ return self.default_value
# --- end of get_default_value (...) ---
@@ -146,7 +142,7 @@ class DescriptionField:
def get_flags ( self ):
"""Returns the flags of this DescriptionField or an empty list (=no flags)."""
- return self.flags if hasattr ( self, 'flags' ) else []
+ return self.flags
# --- end of get_flags (...) ---
@@ -155,7 +151,7 @@ class DescriptionField:
"""Returns the allowed values of this DescriptionField or an empty list,
which should be interpreted as 'no value restriction'.
"""
- return self.allowed_values if hasattr ( self, 'allowed_values' ) else []
+ return self.allowed_values
# --- end of get_allowed_values (...) ---
@@ -181,9 +177,6 @@ class DescriptionField:
if not field_identifier:
# bad identifier
return False
- elif not hasattr ( self, aliases ):
- # no aliases
- return False
if 'withcase' in self.aliases:
if field_identifier in self.aliases ['withcase']:
@@ -194,6 +187,8 @@ class DescriptionField:
if field_id_lower in self.aliases ['nocase']:
return True
+ return False
+
# --- end of matches_alias (...) ---
@@ -203,9 +198,6 @@ class DescriptionField:
arguments:
* flag --
"""
- if not hasattr ( self, 'flags' ):
- return False
-
return bool ( flag.lower() in self.flags )
def value_allowed ( self, value, nocase=True ):
@@ -215,18 +207,17 @@ class DescriptionField:
* value -- value to check
* nocase -- if True (the default): be case insensitive
"""
- allowed_values = self.get_allowed_values ()
- if not allowed_values:
+ if not self.allowed_values:
return True
elif nocase:
lowval = value.lower()
- for allowed in allowed_values:
+ for allowed in self.allowed_values:
if allowed.lower() == lowval:
return True
else:
- return bool ( value in allowed_values )
+ return bool ( value in self.allowed_values )
return False
@@ -315,22 +306,21 @@ class DescriptionFields:
flagmap = dict ()
optionmap = dict (
defaults = dict (),
- allowed_values = set ()
+ allowed_values = list ()
)
for field_name in self.fields.keys():
-
- d = self.fields [field_name].get_default_value()
+ d = self.fields [field_name].default_value
if not d is None:
optionmap ['defaults'] [field_name] = d
- if self.fields [field_name].get_allowed_values():
- optionmap ['allowed_values'].add ( field_name )
+ if self.fields [field_name].allowed_values:
+ optionmap ['allowed_values'].append ( field_name )
- for flag in self.fields [field_name].get_flags():
+ for flag in self.fields [field_name].flags:
if not flag in flagmap:
- flagmap [flag] = set ()
- flagmap [flag].add ( field_name )
+ flagmap [flag] = list ()
+ flagmap [flag].append ( field_name )
self._fields_by_flag = flagmap
self._fields_by_option = optionmap
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-06 19:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-06 19:52 UTC (permalink / raw
To: gentoo-commits
commit: 30dd2c76ba89169931784493cf326dd691a4a7bc
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 6 19:43:22 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 6 19:43:22 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=30dd2c76
roverlay/config.py: fix _add_entry(...)
---
roverlay/config.py | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index 424e69f..6753d4e 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -328,7 +328,7 @@ class ConfigTree:
cref_level = 0
# check if cref is a link to another entry in CONFIG_ENTRY_MAP
- while isinstance ( cref, str ):
+ while isinstance ( cref, str ) and cref != '':
if cref == original_cref and cref_level:
self.logger.critical ( "CONFIG_ENTRY_MAP is invalid! circular cref detected." )
raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
@@ -415,12 +415,13 @@ class ConfigTree:
# load file
try:
+ fh = open ( config_file, 'r' )
+ reader = shlex.shlex ( fh )
reader.wordchars += ' ./$()[]:+-@*~'
- fh = open ( config_file, 'r' )
- reader = shlex.shlex ( fh )
reader.whitespace_split = False
+
nextline = lambda : ( reader.get_token() for n in range (3) )
option, equal, value = nextline ()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-06 19:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-06 19:52 UTC (permalink / raw
To: gentoo-commits
commit: f0a5ee703f0d23a4968963f57817336486806451
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 6 19:47:12 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 6 19:47:12 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f0a5ee70
add dependency resolution to ebuild creation
modified: roverlay/ebuildcreator.py
modified: roverlay/ebuildjob.py
---
roverlay/ebuildcreator.py | 11 +++--
roverlay/ebuildjob.py | 111 ++++++++++++++++++++++++++++-----------------
2 files changed, 75 insertions(+), 47 deletions(-)
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index bc74490..3713c3b 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -3,6 +3,8 @@
# Distributed under the terms of the GNU General Public License v2
from roverlay.ebuildjob import EbuildJob
+from roverlay.depres import depresolver
+from roverlay.depres.communication import EbuildJobChannel
class EbuildCreator:
@@ -12,7 +14,7 @@ class EbuildCreator:
every R package added.
"""
self.ebuild_headers = dict ()
- self.depresolve_main = None # TODO
+ self.depresolve_main = depresolver.DependencyResolver ()
self.ebuild_jobs = []
# --- end of init (...) ---
@@ -26,7 +28,7 @@ class EbuildCreator:
* package_file -- path R package file
"""
- new_job = EbuildJob ( package_file, self.get_resolver ( False ) )
+ new_job = EbuildJob ( package_file, self.get_resolver_channel )
self.ebuild_jobs.append ( new_job )
@@ -34,15 +36,14 @@ class EbuildCreator:
# --- end of add_package (...) ---
- def get_resolver ( self, readonly=True ):
+ def get_resolver_channel ( self, name=None ):
"""Returns a communication channel to the dependency resolver.
arguments:
readonly -- whether the channel is listen-only (no write methods) or not
defaults to True
"""
- # <TODO>
- return None
+ return self.depresolve_main.register_channel ( EbuildJobChannel ( name=name ) )
#return self.depresolve_main.get_channel()
# --- end of get_resolver (...) ---
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index be8e5e3..fa13a48 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -36,7 +36,7 @@ class EbuildJob:
FAIL = [],
)
- def __init__ ( self, package_file, dep_resolver=None ):
+ def __init__ ( self, package_file, depres_channel_spawner=None ):
"""Initializes an EbuildJob, which creates an ebuild for an R package.
arguments:
@@ -49,8 +49,6 @@ class EbuildJob:
dep resolver 'communication channel', status codes etc.
"""
- #self.package_file = package_file
- self.dep_resolver = dep_resolver
# get description reader from args?
self.description_reader = DescriptionReader ( package_file )
@@ -58,10 +56,26 @@ class EbuildJob:
self.ebuild = None
+ # only allow a function (at least callable) for self.get_resolver
+ if hasattr ( depres_channel_spawner, '__call__' ):
+ self.request_resolver = depres_channel_spawner
+ # _depres contains (almost) dependency resolution data/.., including
+ # communication channels and should only be modified in run()
+ self._depres = dict ()
+ else:
+ self.request_resolver = None
+
self.status = 'INIT'
# --- end of __init__ (...) ---
+ def get_resolver ( self, dependency_type ):
+ if not dependency_type in self._depres:
+ self._depres [dependency_type] = self.request_resolver ()
+
+ return self._depres [dependency_type]
+
+
def get_ebuild ( self ):
"""Returns the Ebuild that is created by this object. Note that you should
check the status with status ( $TODO::EBUILD_READY ) before trying to use
@@ -148,73 +162,86 @@ class EbuildJob:
False
)
- if self.dep_resolver and self.dep_resolver.enabled():
+ if not self.request_resolver is None:
+
+ dep_type = desc_field = None
- # collect depdencies from desc and add them to the resolver
- raw_depends = dict ()
- dep_type = field = None
+ for dep_type in EbuildJob.DEPENDENCY_FIELDS:
- for dep_type in EbuildJob.DEPENDENCY_FIELDS.keys():
+ resolver = None
- raw_depends [dep_type] = []
+ for desc_field in EbuildJob.DEPENDENCY_FIELDS [dep_type]:
- for field in EbuildJob.DEPENDENCY_FIELDS [dep_type]:
+ if desc_field in desc:
+ if not resolver:
+ resolver = self.get_resolver ( dep_type )
- if field in desc:
- if isinstance ( desc [field], list ):
- raw_depends.extend ( desc [field] )
- self.dep_resolver.add_dependencies ( desc [field] )
+ if isinstance ( desc [desc_field], list ):
+ resolver.add_dependencies ( desc [desc_field] )
else:
- raw_depends.append ( desc [field] )
- self.dep_resolver.add_depency ( desc [field] )
+ resolver.add_depency ( desc [desc_field] )
- del field, dep_type
+ del resolver
- while not self.dep_resolver.done():
+ # wait
+ resolver_list = self._depres.values()
+ wait_resolve = True
+ while wait_resolve:
+ wait_resolve = False
if not self._set_status ( 'WAIT_RESOLVE' ): return
+ self.logger.debug ( "WAITING" )
+
# tell the resolver to run (again)
- self.dep_resolver.run()
+ for r in resolver_list : r.trigger_run ()
if not self._set_status ( 'BUSY' ): return
- if self.dep_resolver.satisfy_request():
+ for r in resolver_list :
+ if not r.done ():
+ wait_resolve = True
+ break
- dep_type = dep_str = dep = None
+ # check if all deps resolved
+ deps_resolved = True
+ for r in resolver_list:
+ if not r.satisfy_request():
+ deps_resolved = False
+ break
+
+ if deps_resolved:
# dependencies resolved, add them to the ebuild
- for dep_type in raw_depends.keys():
-
- for dep_str in raw_depends [dep_type]:
- # lookup (str) should return a str here
- dep = self.dep_resolver.lookup ( dep_str )
- if dep is None:
- raise Exception (
- "dep_resolver is broken: lookup() returns None but satisfy_request() says ok."
- )
- else:
- # add depencies in append mode
- dep = self.dep_resolver.lookup ( dep_str )
- ebuild.add ( dep_type,
- self.dep_resolver.lookup ( dep_str ),
- True
- )
+ for dep_type, resolver in self._depres.items():
+
+ deplist = resolver.collect_dependencies ()
- del dep, dep_str, dep_type
+ if deplist is None or not isinstance ( deplist, list ):
+ ## false positive: "empty" channel
+ raise Exception (
+ "dep_resolver is broken: lookup() returns None but satisfy_request() says ok."
+ )
+ else:
+ # add dependencies in no_append/override mode
+ ebuild.add ( dep_type, deplist, False )
- # tell the dep resolver that we're done here
- self.dep_resolver.close()
+ # tell the dep resolver channels that we're done
+ for r in resolver_list: r.close ()
else:
- # ebuild is not creatable, set status to FAIL and close dep resolver
+ # ebuild is not creatable, set status to FAIL and close dep resolvers
+ self.logger.info ( "Failed to resolve dependencies for this package." )
+ for r in resolver_list: r.close ()
self._set_status ( 'FAIL' )
- self.dep_resolver.close()
return
+ # --- end dep resolution
+
+
## finalize self.ebuild: forced text creation + make it readonly
if ebuild.prepare ( True, True ):
self.ebuild = ebuild
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-12 17:17 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-12 17:17 UTC (permalink / raw
To: gentoo-commits
commit: 4ceeb302c882e6cb9e18c4cda2896078eff91783
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jun 12 17:13:14 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jun 12 17:13:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4ceeb302
roverlay
* moved get_packageinfo to util.py 'cause it'll be used for metadata creation
* misc fixes
* added value_type regex to config.py
* use depres changes, cancel ebuild creation earlier when deps are unresolved
modified: roverlay/__init__.py
modified: roverlay/config.py
modified: roverlay/const.py
modified: roverlay/descriptionreader.py
modified: roverlay/ebuildcreator.py
modified: roverlay/ebuildjob.py
new file: roverlay/util.py
---
roverlay/__init__.py | 2 +-
roverlay/config.py | 110 +++++++++++++++++++++++++----------------
roverlay/const.py | 17 +++---
roverlay/descriptionreader.py | 63 +++--------------------
roverlay/ebuildcreator.py | 23 +++++----
roverlay/ebuildjob.py | 87 ++++++++++++++++++--------------
roverlay/util.py | 48 ++++++++++++++++++
7 files changed, 196 insertions(+), 154 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 2dab8ad..9ff69f7 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -4,7 +4,6 @@
import logging
-
from roverlay import config
config.access().load_config ( 'R-overlay.conf' )
@@ -18,6 +17,7 @@ logging.basicConfig (
datefmt='%F %H:%M:%S'
)
+
# add console output to the logger
ch = logging.StreamHandler()
ch.setLevel ( logging.INFO )
diff --git a/roverlay/config.py b/roverlay/config.py
index 8cd99e3..6e5c433 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -82,6 +82,7 @@ class ConfigTree ( object ):
# ** fs_path -- ~ will be expanded
# ** fs_dir -- fs_path and value must be a dir if it exists
# ** fs_file -- fs_path and value must be a file if it exists
+ # ** regex -- value is a regex and will be compiled (re.compile(..))
#
# multiple types are generally not supported ('this is an int or a str'),
# but subtypes are (list of yesno), which can be specified by either
@@ -114,7 +115,6 @@ class ConfigTree ( object ):
distfiles_dir = dict (
value_type = 'fs_dir',
),
-
)
# often used regexes
@@ -123,9 +123,9 @@ class ConfigTree ( object ):
def __init__ ( self, import_const=True ):
- """Initializes an ConfigTree, which is a container for options/config values.
- values can be stored directly (such as the field_definitions) or in a
- tree-like { section -> subsection[s] -> option = value } structure.
+ """Initializes an ConfigTree, which is a container for options/values.
+ Values can be stored directly (such as the field_definitions) or
+ in a tree-like { section -> subsection[s] -> option = value } structure.
Config keys cannot contain dots because they're used as config path
separator.
@@ -153,11 +153,13 @@ class ConfigTree ( object ):
value to it.
arguments:
- * path -- config path as path list ([a,b,c]) or as path str (a.b.c)
- * root -- config root (dict expected). Uses self._config if None (the default)
+ * path -- config path as path list ([a,b,c]) or as path str (a.b.c)
+ * root -- config root (dict expected).
+ Uses self._config if None (the default)
* create -- create path if nonexistent
- * value -- assign value to the last path element
- an empty dict will be created if this is None and create is True
+ * value -- assign value to the last path element
+ an empty dict will be created if this is None and
+ create is True
"""
if path is None:
return root
@@ -169,7 +171,10 @@ class ConfigTree ( object ):
for k in path:
if not k in config_position:
if create:
- config_position [k] = value if k == path [-1] and value else dict ()
+ if k == path [-1] and not value is None:
+ config_position [k] = value
+ else:
+ config_position [k] = dict()
else:
return None
@@ -206,8 +211,8 @@ class ConfigTree ( object ):
"""Adds an option to the config.
arguments:
- * option -- name of the option as it appears in the (main) config file
- * value -- value to assign, defaults to None
+ * option -- name of the option as it appears in the config file
+ * value -- value to assign, defaults to None
* config_root -- root of the config (a dict), defaults to None which is
later understood as self._config
"""
@@ -217,8 +222,9 @@ class ConfigTree ( object ):
in the ConfigTree.
arguments:
- * value_type -- type of the value, look above for explanation concerning this
- * value -- value to verify and transform
+ * value_type -- type of the value,
+ look above for explanation concerning this
+ * value -- value to verify and transform
* entryconfig_ref -- reference to the config entry config
"""
@@ -269,8 +275,8 @@ class ConfigTree ( object ):
# --- end of fs_path (...) ---
def fs_file ( val ):
- """"val is a file - returns expanded path if it is an existent
- file or it does not exist.
+ """"val is a file - returns expanded path if it is
+ an existent file or it does not exist.
arguments:
* val --
@@ -284,8 +290,8 @@ class ConfigTree ( object ):
# --- end of fs_file (...) ---
def fs_dir ( val ):
- """val is a directory -- returns expanded path if it is an existent
- dir or it does not exist.
+ """val is a directory -- returns expanded path if it is
+ an existent dir or it does not exist.
arguments:
* val --
@@ -298,6 +304,15 @@ class ConfigTree ( object ):
return None
# --- end of fs_dir (...) ---
+ def _regex ( val ):
+ """val is a regex -- compile it if possible
+
+ arguments:
+ * val --
+ """
+ return re.compile ( val ) if not val is None else None
+ # --- end of _regex (...) ---
+
# replace whitespace with a single ' '
value = ConfigTree.WHITESPACE.sub ( ' ', value )
@@ -320,10 +335,12 @@ class ConfigTree ( object ):
'int' : to_int,
'fs_path' : fs_path,
'fs_file' : fs_file,
+ 'regex' : _regex,
}
# dofunc ( function f, <list or str> v) calls f(x) for every str in v
- dofunc = lambda f, v : [ f(x) for x in v ] if isinstance ( v, list ) else f(v)
+ dofunc = lambda f, v : [ f(x) for x in v ] \
+ if isinstance ( v, list ) else f(v)
retval = value
@@ -349,7 +366,9 @@ class ConfigTree ( object ):
# check if cref is a link to another entry in CONFIG_ENTRY_MAP
while isinstance ( cref, str ) and cref != '':
if cref == original_cref and cref_level:
- self.logger.critical ( "CONFIG_ENTRY_MAP is invalid! circular cref detected." )
+ self.logger.critical (
+ "CONFIG_ENTRY_MAP is invalid! circular cref detected."
+ )
raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
elif cref in ConfigTree.CONFIG_ENTRY_MAP:
@@ -357,10 +376,9 @@ class ConfigTree ( object ):
cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
cref_level += 1
else:
- # TODO %s
self.logger.critical (
- "CONFIG_ENTRY_MAP is invalid! last cref = " + option +
- ", current cref = " + cref + "."
+ 'CONFIG_ENTRY_MAP is invalid! '
+ 'last cref = %s, current cref = %s.' % ( option, cref )
)
raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
@@ -384,15 +402,16 @@ class ConfigTree ( object ):
# verify and convert value if value_type is set
if 'value_type' in cref:
- value = make_and_verify_value ( cref ['value_type'], value, cref )
+ value = make_and_verify_value (
+ cref ['value_type'], value, cref
+ )
# need a valid value
if value:
self.logger.debug (
- "New config entry " + str ( option ) +
- " with path " + str ( path ) +
- " and value " + str ( value ) + "."
+ "New config entry %s with path %s and value %s." %
+ ( option, path, value )
)
# add option/value to the config
@@ -401,17 +420,17 @@ class ConfigTree ( object ):
return True
else:
self.logger.error (
- "Option '" + str ( real_option ) +
- "' has an unusable value '" + str ( value ) + "'."
+ "Option '%s' has an unusable value '%s'." %
+ ( real_option, value )
)
return False
# ---
- self.logger.error ( "Option '" + str ( real_option ) + "' is unusable..." )
+ self.logger.error ( "Option '%s' is unusable..." % real_option )
return False
# ---
- self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown." )
+ self.logger.warning ( "Option '%s' is unknown." % real_option )
return False
# --- end of _add_entry (...) ---
@@ -450,9 +469,10 @@ class ConfigTree ( object ):
if equal == '=':
self._add_entry ( option, value, config_root )
else:
+
self.logger.warning (
- "In '" + config_file + "', cannot parse this line: '" +
- str ( option ) + str ( equal ) + str ( value ) + "'."
+ "In '%s', cannot parse this line: '%s%s%s'." %
+ ( config_file, option, equal, value )
)
option, equal, value = nextline ()
@@ -466,25 +486,30 @@ class ConfigTree ( object ):
# --- end of load_config (...) ---
def load_field_definition ( self, def_file, lenient=False ):
- """Loads a field definition file. Please see the example file for format
- details.
+ """Loads a field definition file.
+ Please see the example file for format details.
arguments:
- * def_file -- file (str) to read, this can be a list of str if lenient is True
- * lenient -- if True: do not fail if a file cannot be read; defaults to False
+ * def_file -- file (str) to read,
+ this can be a list of str if lenient is True
+ * lenient -- if True: do not fail if a file cannot be read;
+ defaults to False
"""
if not 'field_def' in self.parser:
- self.parser ['field_def'] = configparser.SafeConfigParser ( allow_no_value=True )
+ self.parser ['field_def'] = \
+ configparser.SafeConfigParser ( allow_no_value=True )
try:
- self.logger.debug ( "Reading description field definition file " + def_file + "." )
+ self.logger.debug (
+ "Reading description field definition file %s." % def_file
+ )
if lenient:
self.parser ['field_def'] . read ( def_file )
else:
fh = open ( def_file, 'r' )
self.parser ['field_def'] . readfp ( fh )
- if fh:
- fh.close()
+
+ if fh: fh.close()
except IOError as err:
self.logger.exception ( err )
raise
@@ -521,14 +546,13 @@ class ConfigTree ( object ):
l = value_str.split ( ', ' )
return [ e for e in l if e.strip() ]
- if not 'field_def' in self.parser:
- return None
+ if not 'field_def' in self.parser: return None
fdef = descriptionfields.DescriptionFields ()
for field_name in self.parser ['field_def'].sections():
field = descriptionfields.DescriptionField ( field_name )
- for option, value in self.parser ['field_def'].items ( field_name, 1 ):
+ for option, value in self.parser ['field_def'].items( field_name, 1 ):
if option == 'alias' or option == 'alias_withcase':
for alias in get_list ( value ):
diff --git a/roverlay/const.py b/roverlay/const.py
index 32a7e89..7ab1891 100644
--- a/roverlay/const.py
+++ b/roverlay/const.py
@@ -18,14 +18,15 @@ _CONSTANTS = dict (
),
EBUILD = dict (
indent = '\t',
- default_header = [ '# Copyright 1999-' + str ( time.gmtime() [0] ) + ' Gentoo Foundation',
- '# Distributed under the terms of the GNU General Public License v2',
- '# $Header: $',
- '',
- 'EAPI=4',
- '',
- 'inherit R-packages'
- ],
+ default_header = [
+ '# Copyright 1999-%i Gentoo Foundation' % ( time.gmtime() [0] ),
+ '# Distributed under the terms of the GNU General Public License v2',
+ '# $Header: $',
+ '',
+ 'EAPI=4',
+ '',
+ 'inherit R-packages'
+ ],
)
)
diff --git a/roverlay/descriptionreader.py b/roverlay/descriptionreader.py
index ad70239..01eb92a 100644
--- a/roverlay/descriptionreader.py
+++ b/roverlay/descriptionreader.py
@@ -13,18 +13,20 @@ from roverlay import descriptionfields
class DescriptionReader ( object ):
"""Description Reader"""
- LOGGER = logging.getLogger ( 'DescriptionReader' )
+ #LOGGER = logging.getLogger ( 'DescriptionReader' )
- def __init__ ( self, package_file, read_now=False ):
+ def __init__ ( self, package_info, logger, read_now=False ):
"""Initializes a DESCRIPTION file reader."""
if not config.access().get_field_definition():
- raise Exception ( "Field definition is missing, cannot initialize DescriptionReader." )
+ raise Exception (
+ "Field definition is missing, cannot initialize DescriptionReader."
+ )
self.field_definition = config.access().get_field_definition()
- self.fileinfo = self.make_fileinfo ( package_file )
- self.logger = DescriptionReader.LOGGER.getChild ( self.get_log_name() )
+ self.fileinfo = package_info
+ self.logger = logger.getChild ( 'desc_reader' )
self.desc_data = None
@@ -33,15 +35,6 @@ class DescriptionReader ( object ):
# --- end of __init__ (...) ---
- def get_log_name ( self ):
- """Returns a logging name that can be used in other modules."""
- try:
- return self.fileinfo ['filename']
- except Exception as any_exception:
- return '__undef__'
- # --- end of get_log_name (...) ---
-
-
def get_desc ( self, run_if_unset=True ):
if self.desc_data is None:
self.run ()
@@ -49,43 +42,6 @@ class DescriptionReader ( object ):
return self.desc_data
# --- end of get_desc (...) ---
- def get_fileinfo ( self ):
- return self.fileinfo
- # --- end of get_fileinfo (...) ---
-
- def make_fileinfo ( self, filepath ):
- """Returns some info about the given filepath as dict whose contents are
- the file path, the file name ([as package_file with suffix and]
- as filename with tarball suffix removed), the package name
- and the package_version.
-
- arguments:
- * filepath --
- """
-
- package_file = os.path.basename ( filepath )
-
- filename = re.sub ( config.get ( 'R_PACKAGE.suffix_regex' ) + '$', '', package_file )
-
- package_name, sepa, package_version = filename.partition (
- config.get ( 'R_PACKAGE.name_ver_separator', '_' )
- )
-
- if not sepa:
- # file name unexpected, tarball extraction will (probably) fail
- DescriptionReader.LOGGER.error ( "unexpected file name %s.'", filename )
-
- return dict (
- filepath = filepath,
- filename = filename,
- package_file = package_file,
- package_name = package_name,
- #package_origin = ?,
- package_version = package_version,
- )
-
- # --- end of make_fileinfo (...) ---
-
def _parse_read_data ( self, read_data ):
"""Verifies and parses/fixes read data.
@@ -93,7 +49,6 @@ class DescriptionReader ( object ):
* read_data -- data from file, will be modified
"""
-
# insert default values
default_values = self.field_definition.get_fields_with_default_value()
for field_name in default_values.keys():
@@ -153,8 +108,8 @@ class DescriptionReader ( object ):
-> split field values
-> filter out unwanted/useless fields
- The return value is a dict { fileinfo , description_data } or None if
- the read data are "useless" (not suited to create an ebuild for it,
+ The return value is a description_data dict or None if the read data
+ are "useless" (not suited to create an ebuild for it,
e.g. if OS_TYPE is not unix).
"""
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
index 4ece851..6daf471 100644
--- a/roverlay/ebuildcreator.py
+++ b/roverlay/ebuildcreator.py
@@ -2,8 +2,8 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import threading
import logging
+import threading
try:
import queue
@@ -11,6 +11,7 @@ except ImportError:
# python2
import Queue as queue
+
from roverlay import config
from roverlay.ebuildjob import EbuildJob
from roverlay.depres import depresolver
@@ -34,7 +35,7 @@ class EbuildCreator ( object ):
self.runlock = threading.Lock()
self._threads = None
- self.logger = logging.getLogger ( 'EbuildCreator' )
+ self.logger = logging.getLogger ( 'EbuildCreator' )
# --- end of init (...) ---
@@ -46,7 +47,6 @@ class EbuildCreator ( object ):
arguments:
* package_file -- path R package file
"""
-
new_job = EbuildJob ( package_file, self.get_resolver_channel )
self.ebuild_jobs.put ( new_job )
@@ -55,14 +55,16 @@ class EbuildCreator ( object ):
# --- end of add_package (...) ---
- def get_resolver_channel ( self, name=None ):
+ def get_resolver_channel ( self, name=None, logger=None ):
"""Returns a communication channel to the dependency resolver.
arguments:
readonly -- whether the channel is listen-only (no write methods) or not
defaults to True
"""
- return self.depresolve_main.register_channel ( EbuildJobChannel ( name=name ) )
+ return self.depresolve_main.register_channel (
+ EbuildJobChannel ( name=name, logger=logger )
+ )
# --- end of get_resolver_channel (...) ---
@@ -84,7 +86,7 @@ class EbuildCreator ( object ):
# --- end of _thread_run (...) ---
- def run ( self ):
+ def start ( self ):
"""Tells all EbuildJobs to run."""
if not self.runlock.acquire ( False ):
@@ -95,10 +97,9 @@ class EbuildCreator ( object ):
jobcount = EbuildCreator.NUMTHREADS
if jobcount < 1:
- if jobcount < 0:
- self.logger.warning ( "Running in sequential mode." )
- else:
- self.logger.debug ( "Running in sequential mode." )
+ ( self.logger.warning if jobcount < 0 else self.logger.debug ) (
+ "Running in sequential mode."
+ )
self._thread_run()
else:
self.logger.warning (
@@ -118,7 +119,7 @@ class EbuildCreator ( object ):
self.runlock.release()
- # --- end of run (...) ---
+ # --- end of start (...) ---
def collect_ebuilds ( self ):
"""Returns all ebuilds. (They may not be ready / TODO)"""
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
index ccd2f2a..8b13e67 100644
--- a/roverlay/ebuildjob.py
+++ b/roverlay/ebuildjob.py
@@ -5,9 +5,11 @@
import logging
import re
+from roverlay import config, util
+from roverlay.ebuild import Ebuild
from roverlay.descriptionreader import DescriptionReader
-from roverlay.ebuild import Ebuild
-from roverlay import config
+
+
class EbuildJob ( object ):
LOGGER = logging.getLogger ( 'EbuildJob' )
@@ -37,7 +39,7 @@ class EbuildJob ( object ):
"""Initializes an EbuildJob, which creates an ebuild for an R package.
arguments:
- * package_file -- path to the R package file
+ * package_info -- R package file info
* dep_resolver -- dependency resolver
"""
@@ -46,10 +48,18 @@ class EbuildJob ( object ):
dep resolver 'communication channel', status codes etc.
"""
- # get description reader from args?
- self.description_reader = DescriptionReader ( package_file )
+ self.package_info = util.get_packageinfo ( package_file )
+
+ try:
+ self.logger = EbuildJob.LOGGER.getChild (
+ self.package_info ['filename']
+ )
+ except KeyError:
+ self.logger = EbuildJob.LOGGER.getChild ( '__undef__' )
- self.logger = EbuildJob.LOGGER.getChild ( self.description_reader.get_log_name () )
+ self.description_reader = DescriptionReader (
+ self.package_info, logger=self.logger
+ )
self.ebuild = None
@@ -67,17 +77,19 @@ class EbuildJob ( object ):
# --- end of __init__ (...) ---
def get_resolver ( self, dependency_type ):
+ # comment TODO
if not dependency_type in self._depres:
- self._depres [dependency_type] = self.request_resolver ( dependency_type )
+ self._depres [dependency_type] = \
+ self.request_resolver ( dependency_type, self.logger )
return self._depres [dependency_type]
-
+ # --- end of get_resolver (...) ---
def get_ebuild ( self ):
"""Returns the Ebuild that is created by this object. Note that you should
check the status with status ( $TODO::EBUILD_READY ) before trying to use
the Ebuild.
- ##fixme: it is guaranteed that self.ebuild is None unless the Ebuild is successfully created##
+ ##fixme: it is (should be?) guaranteed that self.ebuild is None unless the Ebuild is successfully created##
"""
return self.ebuild
@@ -103,7 +115,6 @@ class EbuildJob ( object ):
# --- end of done_success (...) ---
-
def run ( self ):
"""Tells this EbuildJob to run. This means that it reads the package file,
resolves dependencies using its resolver (TODO) and creates
@@ -124,7 +135,7 @@ class EbuildJob ( object ):
self.logger.info ( 'Cannot create an ebuild for this package.' )
- fileinfo = self.description_reader.get_fileinfo ()
+ fileinfo = self.package_info
ebuild = Ebuild ( self.logger.getChild ( "Ebuild" ) )
@@ -180,35 +191,43 @@ class EbuildJob ( object ):
else:
resolver.add_depency ( desc [desc_field] )
- del resolver
+ # lazy depres: wait until done and stop if any resolver channel
+ # returns None (which implies failure)
+ # wait for depres and store results
+ resolved = True
- resolver_list = self._depres.values()
-
- # trigger depres...
- for r in resolver_list: r.trigger_run()
-
- # and wait
if not self._set_status ( 'WAIT_RESOLVE' ): return
- for r in resolver_list: r.join()
+
+ for resolver in self._depres.values():
+ if resolver.satisfy_request() is None:
+ resolved = False
+ break
if not self._set_status ( 'BUSY' ): return
- # check if all deps resolved, which means that all channels have
- # to return True
- if not False in ( r.satisfy_request() for r in resolver_list ):
+ if not resolved:
+ # ebuild is not creatable, set status to FAIL and close dep resolvers
+ self.logger.info (
+ "Failed to resolve dependencies for this package."
+ )
+ for r in self._depres.values(): r.close ()
+ self._set_status ( 'FAIL' )
+ return
+ else:
# add deps to the ebuild
for dep_type, resolver in self._depres.items():
-
# python3 requires list ( filter ( ... ) )
- deplist = list ( filter ( None, resolver.collect_dependencies () ) )
+ deplist = list (
+ filter ( None, resolver.collect_dependencies () )
+ )
if deplist is None:
- ## false positive: "empty" channel
- raise Exception (
- 'dep_resolver is broken: '
- 'lookup() returns None but satisfy_request() says ok.'
- )
+ ## FIXME: false positive: "empty" channel
+ raise Exception (
+ 'dep_resolver is broken: '
+ 'lookup() returns None but satisfy_request() says ok.'
+ )
elif isinstance ( deplist, ( list, set ) ):
# add dependencies in no_append/override mode
self.logger.debug ( "adding %s to %s", str (deplist), dep_type )
@@ -220,15 +239,9 @@ class EbuildJob ( object ):
)
# --- end for
- # tell the dep resolver channels that we're done
- for r in resolver_list: r.close ()
- else:
- # ebuild is not creatable, set status to FAIL and close dep resolvers
- self.logger.info ( "Failed to resolve dependencies for this package." )
- for r in resolver_list: r.close ()
- self._set_status ( 'FAIL' )
- return
+ # tell the dep resolver channels that we're done
+ for r in self._depres.values(): r.close ()
# --- end dep resolution
diff --git a/roverlay/util.py b/roverlay/util.py
new file mode 100644
index 0000000..5e9690d
--- /dev/null
+++ b/roverlay/util.py
@@ -0,0 +1,48 @@
+# R Overlay -- helper functions etc.
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import re
+import os.path
+import logging
+
+from roverlay import config
+
+LOGGER = logging.getLogger ( 'util' )
+
+
+def get_packageinfo ( filepath ):
+ """Returns some info about the given filepath as dict whose contents are
+ the file path, the file name ([as package_file with suffix and]
+ as filename with tarball suffix removed), the package name
+ and the package_version.
+
+ arguments:
+ * filepath --
+ """
+
+ package_file = os.path.basename ( filepath )
+
+ # remove .tar.gz .tar.bz2 etc.
+ filename = re.sub (
+ config.get ( 'R_PACKAGE.suffix_regex' ) + '$', '', package_file
+ )
+
+ package_name, sepa, package_version = filename.partition (
+ config.get ( 'R_PACKAGE.name_ver_separator', '_' )
+ )
+
+ if not sepa:
+ # file name unexpected, tarball extraction will (probably) fail
+ LOGGER.error ( "unexpected file name '%s'." % filename )
+
+ return dict (
+ filepath = filepath,
+ filename = filename,
+ package_file = package_file,
+ package_name = package_name,
+ #package_origin = ?,
+ package_version = package_version,
+ )
+
+# --- end of get_packageinfo (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: c335d96105c50c6f988ffac378a9d17ada050874
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 14 18:50:35 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 14 18:50:35 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c335d961
config
* fix get()/_findpath()
* add key/value injection
modified: roverlay/config.py
---
roverlay/config.py | 74 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 57 insertions(+), 17 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index 3f6707b..abef63f 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -18,7 +18,7 @@ from roverlay import const
from roverlay.rpackage import descriptionfields
-
+CONFIG_INJECTION_IS_BAD = True
def access():
"""Returns the ConfigTree."""
@@ -26,7 +26,7 @@ def access():
# --- end of access (...) ---
-def get ( key, fallback_value=None ):
+def get ( key, fallback_value=None, fail_if_unset=False ):
"""Searches for key in the ConfigTree and returns its value if possible,
else fallback_value.
'key' is a config path [<section>[.<subsection>*]]<option name>.
@@ -36,11 +36,14 @@ def get ( key, fallback_value=None ):
* fallback_value --
"""
if not fallback_value is None:
- return access().get ( key, fallback_value )
+ return access().get ( key, fallback_value, fail_if_unset )
else:
- return access().get ( key )
+ return access().get ( key, fail_if_unset )
# --- end of get (...) ---
+def get_or_fail ( key ):
+ return access().get ( key, fail_if_unset=True )
+# --- end of get_or_fail (...) ---
class InitialLogger:
@@ -82,6 +85,7 @@ class ConfigTree ( object ):
# ** fs_path -- ~ will be expanded
# ** fs_dir -- fs_path and value must be a dir if it exists
# ** fs_file -- fs_path and value must be a file if it exists
+ # TODO** fs_prog -- fs_file (and fs_path) and value must be executable (TODO)
# ** regex -- value is a regex and will be compiled (re.compile(..))
#
# multiple types are generally not supported ('this is an int or a str'),
@@ -115,6 +119,11 @@ class ConfigTree ( object ):
distfiles_dir = dict (
value_type = 'fs_dir',
),
+ ebuild_prog = dict (
+ path = [ 'TOOLS', 'ebuild_prog' ],
+ value_type = 'fs_path',
+ ),
+
)
# often used regexes
@@ -168,12 +177,14 @@ class ConfigTree ( object ):
config_position = self._config if root is None else root
+ if config_position is None: return None
+
for k in path:
- if not k in config_position:
+ if k == path [-1] and not value is None:
+ # overwrite entry
+ config_position [k] = value
+ elif not k in config_position:
if create:
- if k == path [-1] and not value is None:
- config_position [k] = value
- else:
config_position [k] = dict()
else:
return None
@@ -184,8 +195,32 @@ class ConfigTree ( object ):
# --- end of _findpath (...) ---
+ def inject ( self, key, value, suppress_log=False ):
+ """This method offer direct write access to the ConfigTree. No checks
+ will be performed, so make sure you know what you're doing.
+
+ arguments:
+ * key -- config path of the entry to-be-created/overwritten
+ the whole path will be created, this operation does not fail
+ if a path component is missing ('<root>.<new>.<entry> creates
+ root, new and entry if required)
+ * value -- value to be assigned
+
+ returns: None (implicit)
+ """
+ if not suppress_log:
+ msg = 'config injection: value %s will '\
+ 'be assigned to config key %s ...' % ( value, key )
+
+ if CONFIG_INJECTION_IS_BAD:
+ self.logger.warning ( msg )
+ else:
+ self.logger.debug ( msg )
+
+ self._findpath ( key, create=True, value=value )
+ # --- end of inject (...) ---
- def get ( self, key, fallback_value=None ):
+ def get ( self, key, fallback_value=None, fail_if_unset=False ):
"""Searches for key in the ConfigTree and returns its value.
Searches in const if ConfigTree does not contain the requested key and
returns the fallback_value if key not found.
@@ -193,17 +228,22 @@ class ConfigTree ( object ):
arguments:
* key --
* fallback_value --
+ * fail_if_unset -- fail if key is neither in config nor const
"""
- if self._config:
- config_value = self._findpath ( key )
- if config_value:
- return config_value
+ config_value = self._findpath ( key )
+
+ if config_value is None:
+ fallback = None if fail_if_unset else fallback_value
+ if not self._const_imported:
+ config_value = const.lookup ( key, fallback )
+ else:
+ config_value = fallback
+
+ if config_value is None and fail_if_unset:
+ raise Exception ( "config key '%s' not found but required." % key )
- if self._const_imported:
- return fallback_value
- else:
- return const.lookup ( key, fallback_value )
+ return config_value
# --- end of get (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: e5daa9e9b0f12ba38b98c806d3029a429c02b3e4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 14 18:51:51 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 14 18:51:51 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=e5daa9e9
add OVERLAY.dir to const
---
roverlay/const.py | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/roverlay/const.py b/roverlay/const.py
index 7ab1891..0ab36f9 100644
--- a/roverlay/const.py
+++ b/roverlay/const.py
@@ -27,7 +27,10 @@ _CONSTANTS = dict (
'',
'inherit R-packages'
],
- )
+ ),
+ OVERLAY = dict (
+ category = 'sci-R',
+ ),
)
def lookup ( key, fallback_value=None ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: 50ba18a562ef365ffbd2c7ba49a9027ba101234b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 14 18:52:32 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 14 18:52:32 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=50ba18a5
extend roverlay.util
* added keepenv that selectively imports os.environ
* added misc functions
modified: roverlay/util.py
---
roverlay/util.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index 5e9690d..6547906 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -6,6 +6,8 @@ import re
import os.path
import logging
+import os
+
from roverlay import config
LOGGER = logging.getLogger ( 'util' )
@@ -46,3 +48,56 @@ def get_packageinfo ( filepath ):
)
# --- end of get_packageinfo (...) ---
+
+def get_extra_packageinfo ( package_info, name ):
+ return dict (
+ PKG_DISTDIR = os.path.dirname ( package_info ['package_file'] ),
+ EBUILD_FILE = os.path.join (
+ config.get_or_fail ( [ 'OVERLAY', 'dir' ] ),
+ config.get_or_fail ( [ 'OVERLAY', 'category' ] ),
+ package_info [ 'ebuild_filename'].partition ( '-' ) [0],
+ package_info [ 'ebuild_filename'] + ".ebuild"
+ )
+ ) [name]
+# --- end of get_extra_packageinfo (...) ---
+
+def pipe_lines ( _pipe, use_filter=False, filter_func=None ):
+ lines = _pipe.decode().split ('\n')
+ if use_filter:
+ return filter ( filter_func, lines )
+ else:
+ return lines
+# --- end of pipe_lines (...) ---
+
+
+def keepenv ( *to_keep, local_env=None ):
+ if local_env is None:
+ myenv = dict()
+ else:
+ myenv = local_env
+
+ for item in to_keep:
+ if isinstance ( item, tuple ) and len ( item ) == 2:
+
+ var = item [0]
+ fallback = item [1]
+ else:
+ var = item
+ fallback = None
+
+ if isinstance ( var, str ):
+ if var in os.environ:
+ myenv [var] = os.environ [var]
+ elif not fallback is None:
+ myenv [var] = fallback
+ else:
+ varlist = var
+ for var in varlist:
+ if var in os.environ:
+ myenv [var] = os.environ [var]
+ elif not fallback is None:
+ myenv [var] = fallback
+
+ # -- for
+ return myenv if local_env is None else None
+# --- end of keepenv (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: f21c2a9af227ff9916cd12e1b5f976ddcd350ceb
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 15 09:50:52 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 15 09:50:52 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f21c2a9a
fix config
---
roverlay/config.py | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index abef63f..b1710f9 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -36,9 +36,13 @@ def get ( key, fallback_value=None, fail_if_unset=False ):
* fallback_value --
"""
if not fallback_value is None:
- return access().get ( key, fallback_value, fail_if_unset )
+ return access().get (
+ key, fallback_value=fallback_value, fail_if_unset=fail_if_unset
+ )
else:
- return access().get ( key, fail_if_unset )
+ return access().get (
+ key, fallback_value=None, fail_if_unset=fail_if_unset
+ )
# --- end of get (...) ---
def get_or_fail ( key ):
@@ -180,6 +184,8 @@ class ConfigTree ( object ):
if config_position is None: return None
for k in path:
+ if len (k) == 0:
+ continue
if k == path [-1] and not value is None:
# overwrite entry
config_position [k] = value
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: 6bd75daf93e1efbe1372dc908cd998a2a96299d3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 15 09:51:28 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 15 09:51:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6bd75daf
add get_distdir() to util
---
roverlay/util.py | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index 6547906..12561f7 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -50,15 +50,21 @@ def get_packageinfo ( filepath ):
# --- end of get_packageinfo (...) ---
def get_extra_packageinfo ( package_info, name ):
- return dict (
- PKG_DISTDIR = os.path.dirname ( package_info ['package_file'] ),
- EBUILD_FILE = os.path.join (
+ #name = name.upper()
+ ret = None
+ if name == 'PKG_DISTDIR':
+ ret = PKG_DISTDIR = os.path.dirname ( package_info ['package_file'] )
+ elif name == 'EBUILD_FILE':
+ ret = os.path.join (
config.get_or_fail ( [ 'OVERLAY', 'dir' ] ),
config.get_or_fail ( [ 'OVERLAY', 'category' ] ),
package_info [ 'ebuild_filename'].partition ( '-' ) [0],
package_info [ 'ebuild_filename'] + ".ebuild"
)
- ) [name]
+ else:
+ raise Exception ( "unknown package info requested." )
+
+ return ret
# --- end of get_extra_packageinfo (...) ---
def pipe_lines ( _pipe, use_filter=False, filter_func=None ):
@@ -69,6 +75,15 @@ def pipe_lines ( _pipe, use_filter=False, filter_func=None ):
return lines
# --- end of pipe_lines (...) ---
+def get_distdir ( repo_name='' ):
+ distdir = config.get ( [ 'DISTFILES', 'REPO', repo_name ], fallback_value=None )
+ if distdir is None:
+ distdir = config.get_or_fail ( [ 'DISTFILES', 'root' ] )
+ if len ( repo_name ) > 0:
+ distdir = os.path.join ( distdir, repo_name )
+
+ return distdir
+
def keepenv ( *to_keep, local_env=None ):
if local_env is None:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-15 20:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-15 20:34 UTC (permalink / raw
To: gentoo-commits
commit: b556769cc6a68d3dfc77e66d1ee5cf498177e56a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 15 20:16:11 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 15 20:16:11 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b556769c
config: fixes/enhancements
* config_path simpler now
* added ConfigTree.visualize() which can be used
to print/output the config tree
* added fs_abs
modified: roverlay/config.py
---
roverlay/config.py | 108 +++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 90 insertions(+), 18 deletions(-)
diff --git a/roverlay/config.py b/roverlay/config.py
index b1710f9..dbcdfe7 100644
--- a/roverlay/config.py
+++ b/roverlay/config.py
@@ -25,6 +25,15 @@ def access():
return ConfigTree() if ConfigTree.instance is None else ConfigTree.instance
# --- end of access (...) ---
+def get_config_path ( key ):
+ """Creates a config path for key."""
+ _path = key.split ( '.' ) if isinstance ( key, str ) else key
+ if isinstance ( _path, ( list, tuple ) ):
+ # config paths are [ CAPSLOCK, CAPSLOCK,.... , lowercase item ]
+ return [ x.lower() if x == _path [-1] else x.upper() for x in _path ]
+ else:
+ return _path
+# --- end of get_config_path (...) ---
def get ( key, fallback_value=None, fail_if_unset=False ):
"""Searches for key in the ConfigTree and returns its value if possible,
@@ -87,15 +96,17 @@ class ConfigTree ( object ):
# ** int -- integer
# ** yesno -- value must evaluate to 'yes' or 'no' (on,off,y,n,1,0...)
# ** fs_path -- ~ will be expanded
- # ** fs_dir -- fs_path and value must be a dir if it exists
- # ** fs_file -- fs_path and value must be a file if it exists
+ # ** fs_abs -- fs_path and path will be converted into an absolute one
+ # (pwd + path)
+ # ** fs_dir -- fs_abs and value must be a dir if it exists
+ # ** fs_file -- fs_abs and value must be a file if it exists
# TODO** fs_prog -- fs_file (and fs_path) and value must be executable (TODO)
# ** regex -- value is a regex and will be compiled (re.compile(..))
#
# multiple types are generally not supported ('this is an int or a str'),
- # but subtypes are (list of yesno), which can be specified by either
+ # but subtypes are ('list of yesno'), which can be specified by either
# using a list of types ['list', 'yesno'] or by separating the types
- # with a colon list:yesno, which is parsed in a left-to-right order.
+ # with a colon 'list:yesno', which is parsed in a left-to-right order.
# Nested subtypes such as list:slist:int:fs_file:list may lead to errors.
#
CONFIG_ENTRY_MAP = dict (
@@ -105,7 +116,7 @@ class ConfigTree ( object ):
),
log_file = dict (
# setting path to LOG.FILE.main to avoid collision with LOG.FILE.*
- path = [ 'LOG', 'FILE', 'main' ],
+ path = [ 'LOG', 'FILE', 'Main' ],
value_type = 'fs_file',
),
log_file_resolved = dict (
@@ -160,7 +171,9 @@ class ConfigTree ( object ):
# --- end of __init__ (...) ---
- def _findpath ( self, path, root=None, create=False, value=None ):
+ def _findpath ( self, path,
+ root=None, create=False, value=None, forcepath=False, forceval=False
+ ):
"""All-in-one method that searches for a config path.
It is able to create the path if non-existent and to assign a
value to it.
@@ -173,11 +186,16 @@ class ConfigTree ( object ):
* value -- assign value to the last path element
an empty dict will be created if this is None and
create is True
+ * forcepath -- if set and True: do not 'normalize' path if path is a list
+ * forceval -- if set and True: accept None as value
"""
if path is None:
return root
- elif isinstance ( path, str ):
- path = path.split ( '.' ) if path else []
+ elif isinstance ( path, ( list, tuple ) ) and forcepath:
+ pass
+ else:
+ path = get_config_path ( path )
+
config_position = self._config if root is None else root
@@ -186,7 +204,7 @@ class ConfigTree ( object ):
for k in path:
if len (k) == 0:
continue
- if k == path [-1] and not value is None:
+ if k == path [-1] and ( forceval or not value is None ):
# overwrite entry
config_position [k] = value
elif not k in config_position:
@@ -201,7 +219,7 @@ class ConfigTree ( object ):
# --- end of _findpath (...) ---
- def inject ( self, key, value, suppress_log=False ):
+ def inject ( self, key, value, suppress_log=False, **kw_extra ):
"""This method offer direct write access to the ConfigTree. No checks
will be performed, so make sure you know what you're doing.
@@ -211,6 +229,7 @@ class ConfigTree ( object ):
if a path component is missing ('<root>.<new>.<entry> creates
root, new and entry if required)
* value -- value to be assigned
+ * **kw_extra -- extra keywords for _findpath, e.g. forceval=True
returns: None (implicit)
"""
@@ -223,7 +242,7 @@ class ConfigTree ( object ):
else:
self.logger.debug ( msg )
- self._findpath ( key, create=True, value=value )
+ self._findpath ( key, create=True, value=value, **kw_extra )
# --- end of inject (...) ---
def get ( self, key, fallback_value=None, fail_if_unset=False ):
@@ -320,6 +339,14 @@ class ConfigTree ( object ):
return os.path.expanduser ( val ) if val else None
# --- end of fs_path (...) ---
+ def fs_abs ( val ):
+ """val is a filesystem path - returns absolute + expanded path."""
+ if val:
+ return os.path.abspath ( os.path.expanduser ( val ) )
+ else:
+ return None
+
+
def fs_file ( val ):
""""val is a file - returns expanded path if it is
an existent file or it does not exist.
@@ -327,8 +354,8 @@ class ConfigTree ( object ):
arguments:
* val --
"""
- if val:
- retval = os.path.expanduser ( val )
+ retval = fs_abs ( val )
+ if retval:
if os.path.isfile ( retval ) or not os.path.exists ( retval ):
return retval
@@ -342,8 +369,8 @@ class ConfigTree ( object ):
arguments:
* val --
"""
- if val:
- retval = os.path.expanduser ( val )
+ retval = fs_abs ( val )
+ if retval:
if os.path.isdir ( retval ) or not os.path.exists ( retval ):
return retval
@@ -439,9 +466,9 @@ class ConfigTree ( object ):
if 'path' in cref:
path = cref ['path']
else:
- path = low_option.split ( '_' )
- for n in range ( len ( path ) - 1 ):
- path [n] = path [n].upper()
+ path = option.split ( '_' )
+
+ path = get_config_path ( path )
# need a valid path
if path:
@@ -630,3 +657,48 @@ class ConfigTree ( object ):
return fdef
# --- end of _make_field_definition (...) ---
+
+
+ def _tree_to_str ( self, root, name, level=0 ):
+ """Returns string representation of a config tree rooted at root.
+ Uses recursion (DFS).
+
+ arguments:
+ * root -- config 'root', is a value (config 'leaf') or a dict ('tree')
+ * name --
+ * level --
+
+ returns: string representation of the given root
+ """
+
+ indent = level * ' '
+ var_indent = indent + '* '
+ if root is None:
+ return "%s%s is unset\n" % ( var_indent, name )
+ elif len ( root ) == 0:
+ return "%s%s is empty\n" % ( var_indent, name )
+ elif isinstance ( root, dict ):
+ extra = ''.join ( [
+ self._tree_to_str ( n, r, level+1 ) for r, n in root.items()
+ ] )
+ return "%s%s {\n%s%s}\n" % ( indent, name, extra, indent )
+ else:
+ return "%s%s = '%s'\n" % ( var_indent, name, root )
+ # --- end of _tree_to_str (...) ---
+
+ def visualize ( self, into=None ):
+ """Visualizes the ConfigTree,
+ either into a file-like object or as return value.
+
+ arguments:
+ * into -- if not None: write into file
+
+ returns: string if into is None, else None (implicit)
+ """
+ _vis = self._tree_to_str ( self._config, 'ConfigTree', level=0 )
+ if into is None:
+ return _vis
+ else:
+ into.write ( _vis )
+ # --- end of visualize (...) ---
+
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-18 16:27 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-18 16:27 UTC (permalink / raw
To: gentoo-commits
commit: e0aa9e6aabfb7f705ded47d789051e1c75e9c670
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jun 18 16:20:14 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jun 18 16:20:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=e0aa9e6a
roverlay/util: dodir
modified: roverlay/util.py
---
roverlay/util.py | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index cb4f6bb..bf47aa7 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -125,3 +125,9 @@ def sysnop ( nop_returns_success=True, format_str=None ):
return None
# --- end of sysnop (...) ---
+
+def dodir ( *directories ):
+ for d in directories:
+ if not os.path.isdir ( d ):
+ os.mkdir ( d )
+# --- end of dodir (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-20 19:03 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-20 19:03 UTC (permalink / raw
To: gentoo-commits
commit: ad124d77c6201deb37e4e49e140805cdfa7f78f4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 20 10:39:14 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 20 10:39:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ad124d77
utily.py fix + code removed
* removed get_distdir(), replaced by PackageInfo ['DISTDIR']
* fixed sysnop()
modified: roverlay/util.py
---
roverlay/util.py | 26 +-------------------------
1 files changed, 1 insertions(+), 25 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index bf47aa7..c697521 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -52,30 +52,6 @@ def pipe_lines ( _pipe, use_filter=False, filter_func=None ):
return lines
# --- end of pipe_lines (...) ---
-def get_distdir ( repo_name='' ):
- """
- Returns the DISTDIR for repo_name or the DISTDIR root if repo_name is empty.
-
- arguments:
- * repo_name --
- """
-
- if len ( repo_name ) > 0:
- distdir = config.get (
- [ 'DISTFILES', 'REPO', repo_name ],
- fallback_value=None
- )
- if distdir is None:
- distdir = os.path.join (
- config.get_or_fail ( [ 'DISTFILES', 'root' ] ),
- repo_name
- )
- else:
- distdir = config.get_or_fail ( [ 'DISTFILES', 'root' ] )
-
- return distdir
-
-
def keepenv ( *to_keep ):
"""Selectively imports os.environ.
@@ -111,7 +87,7 @@ def keepenv ( *to_keep ):
# --- end of keepenv (...) ---
def sysnop ( nop_returns_success=True, format_str=None ):
- if returns_success:
+ if nop_returns_success:
candidates = ( '/bin/true', '/bin/echo' )
else:
candidates = ( '/bin/false' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-20 19:03 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-20 19:03 UTC (permalink / raw
To: gentoo-commits
commit: b284ff8e4424dac8315bccd94319d0298ddfa2bc
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 20 18:56:42 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 20 18:56:42 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b284ff8e
temporarily increasing console log level
---
roverlay/__init__.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 9ff69f7..b0478ec 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -20,7 +20,7 @@ logging.basicConfig (
# add console output to the logger
ch = logging.StreamHandler()
-ch.setLevel ( logging.INFO )
+ch.setLevel ( logging.DEBUG )
ch.setFormatter (
logging.Formatter ( '%(levelname)-8s %(name)-14s -- %(message)s' )
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-21 16:55 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-21 16:55 UTC (permalink / raw
To: gentoo-commits
commit: 13bd52f447bf3884e12c97790a0f656fa786f254
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 21 16:50:28 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 21 16:50:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=13bd52f4
use os.path.abspath in PackageInfo.update()
modified: roverlay/packageinfo.py
---
roverlay/packageinfo.py | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index fd89a60..712b5a6 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -243,13 +243,15 @@ class PackageInfo ( object ):
self._update_lock.release()
# --- end of update (**kw) ---
- def _use_filepath ( self, filepath ):
+ def _use_filepath ( self, _filepath ):
"""auxiliary method for update(**kw)
arguments:
- * filepath --
+ * _filepath --
"""
+ filepath = os.path.abspath ( _filepath )
+
filename_with_ext = os.path.basename ( filepath )
# remove .tar.gz .tar.bz2 etc.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-25 18:19 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-25 18:19 UTC (permalink / raw
To: gentoo-commits
commit: edd8719acc718698e597ff4cebe52aa520237d17
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jun 25 18:12:07 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jun 25 18:12:07 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=edd8719a
extend PackageInfo
---
roverlay/packageinfo.py | 80 +++++++++++++++++++++++++++++++---------------
1 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 712b5a6..fdce322 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -136,19 +136,22 @@ class PackageInfo ( object ):
return self._info [key_low]
# 'virtual' keys - calculate result
- elif key_low == 'distdir':
- if 'package_dir' in self._info:
- return self._info ['package_dir']
-
- elif 'package_file' in self._info:
- return os.path.dirname ( self._info ['package_file'] )
+ elif key_low == 'name':
+ # no special name, using package_name
+ return self._info ['package_name']
+
+ elif key_low == 'package_file':
+ # assuming that origin is in self._info
+ return os.path.join (
+ self._info ['origin'].distdir,
+ self._info ['package_filename']
+ )
- #elif 'origin' in self._info:
+ elif key_low == 'distdir':
+ if 'origin' in self._info:
+ return self._info ['origin'].distdir
else:
- return os.path.join (
- config.get_or_fail ( ['DISTFILES', 'root' ] ),
- self._info ['origin']
- )
+ return os.path.dirname ( self._info ['package_file'] )
elif key_low == 'has_suggests':
if 'has_suggests' in self._info:
@@ -164,9 +167,17 @@ class PackageInfo ( object ):
# comment from ebuild:
## calculate SRC_URI using self._data ['origin'],
## either here or in eclass
- return "http://TODO!!!/" + self._info ['package_filename']
+
#return "**packageinfo needs information from sync module!"
+ if 'origin' in self._info:
+ return self._info ['origin'].get_src_uri (
+ self._info ['package_filename']
+ )
+ else:
+ return "http://localhost/R-packages/" + \
+ self._info ['package_filename']
+
# fallback
if do_fallback:
@@ -228,6 +239,9 @@ class PackageInfo ( object ):
elif key == 'filepath':
self._use_filepath ( value )
+ elif key == 'filename':
+ self._use_filename ( value )
+
elif key == 'origin':
self ['origin'] = value
@@ -243,16 +257,13 @@ class PackageInfo ( object ):
self._update_lock.release()
# --- end of update (**kw) ---
- def _use_filepath ( self, _filepath ):
+ def _use_filename ( self, _filename ):
"""auxiliary method for update(**kw)
arguments:
- * _filepath --
+ * _filename --
"""
-
- filepath = os.path.abspath ( _filepath )
-
- filename_with_ext = os.path.basename ( filepath )
+ filename_with_ext = _filename
# remove .tar.gz .tar.bz2 etc.
filename = PackageInfo.PKGSUFFIX_REGEX.sub ( '', filename_with_ext )
@@ -281,25 +292,42 @@ class PackageInfo ( object ):
)
raise
-
-
# using package name as name (unless modified later),
# using pkg_version for the ebuild version
self ['name'] = package_name
self ['ebuild_verstr'] = version_str
-
# for DescriptionReader
- self ['package_file'] = filepath
self ['package_name'] = package_name
self ['package_filename'] = filename_with_ext
+ # --- end of _use_filename (...) ---
- # keys never used (FIXME remove or use)
- #self ['filename'] = filename
- #self ['filepath'] = filepath
- #self ['package_version'] = package_version
+ def _use_filepath ( self, _filepath ):
+ """auxiliary method for update(**kw)
+
+ arguments:
+ * _filepath --
+ """
+ LOGGER.info (
+ 'Please note that _use_filepath is only meant for testing.'
+ )
+ filepath = os.path.abspath ( _filepath )
+ self ['package_file'] = filepath
+ self._use_filename ( os.path.basename ( filepath ) )
# --- end of _use_filepath (...) ---
def _use_depres_result ( self, result ):
+ """auxiliary method for update(**kw)
+
+ arguments:
+ * result --
+ """
self ['has_suggests'] = result [2]
+ # --- end of _use_depres_result (...) ---
+
+ def __str__ ( self ):
+ return "<PackageInfo for %s>" % self.get (
+ 'package_file', fallback_value='[unknown file]', do_fallback=True
+ )
+ # --- end of __str__ (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-26 15:42 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-26 15:42 UTC (permalink / raw
To: gentoo-commits
commit: 10cd6f63877dd53d3e19c371ea246de9f2fd1238
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jun 26 15:40:41 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jun 26 15:40:41 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=10cd6f63
extend PackageInfo
* distdir can now be stored in _info
modified: roverlay/packageinfo.py
---
roverlay/packageinfo.py | 41 ++++++++++++++++++++---------------------
1 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index fdce322..8f59439 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -143,12 +143,14 @@ class PackageInfo ( object ):
elif key_low == 'package_file':
# assuming that origin is in self._info
return os.path.join (
- self._info ['origin'].distdir,
+ self.get ( 'distdir' ),
self._info ['package_filename']
)
elif key_low == 'distdir':
if 'origin' in self._info:
+ # this doesn't work if the package is in a sub directory
+ # of the repo's distdir
return self._info ['origin'].distdir
else:
return os.path.dirname ( self._info ['package_file'] )
@@ -209,6 +211,7 @@ class PackageInfo ( object ):
# --- end of __setitem__ (...) ---
def update_now ( self, **info ):
+ if len ( info ) == 0: return
with self._update_lock:
self.set_writeable()
self.update ( **info )
@@ -223,33 +226,38 @@ class PackageInfo ( object ):
raises: Exception when readonly
"""
- if len ( info ) == 0 :
+ if len ( info ) == 0:
# nothing to do
return
self._writelock_acquire()
for key, value in info.items():
- if key == 'desc' or key == 'desc_data':
- self ['desc_data'] = value
-
- elif key == 'ebuild':
- self ['ebuild'] = value
- elif key == 'filepath':
- self._use_filepath ( value )
-
- elif key == 'filename':
+ if key == 'filename':
self._use_filename ( value )
+ elif key in ( 'package_dir', 'dirpath', 'distdir' ):
+ if value is not None:
+ self ['distdir'] = value
+
elif key == 'origin':
self ['origin'] = value
+ elif key == 'desc' or key == 'desc_data':
+ self ['desc_data'] = value
+
+ elif key == 'ebuild':
+ self ['ebuild'] = value
+
elif key == 'suggests':
self ['has_suggests'] = value
elif key == 'depres_results' or key == 'depres_result':
- self._use_depres_result ( value )
+ self ['has_suggests'] = value [2]
+
+ elif key == 'filepath':
+ self._use_filepath ( value )
else:
LOGGER.warning ( "unknown info key %s!" % key )
@@ -317,15 +325,6 @@ class PackageInfo ( object ):
self._use_filename ( os.path.basename ( filepath ) )
# --- end of _use_filepath (...) ---
- def _use_depres_result ( self, result ):
- """auxiliary method for update(**kw)
-
- arguments:
- * result --
- """
- self ['has_suggests'] = result [2]
- # --- end of _use_depres_result (...) ---
-
def __str__ ( self ):
return "<PackageInfo for %s>" % self.get (
'package_file', fallback_value='[unknown file]', do_fallback=True
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-06-28 13:29 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-06-28 13:29 UTC (permalink / raw
To: gentoo-commits
commit: d1789f1570486f0ac5f52804801de7f078d0991f
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 28 13:28:59 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 28 13:28:59 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d1789f15
PackageInfo: fix illegal ebuild names
modified: roverlay/packageinfo.py
---
roverlay/packageinfo.py | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 8f59439..cc09a6b 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -41,6 +41,10 @@ class PackageInfo ( object ):
config.get_or_fail ( 'R_PACKAGE.suffix_regex' ) + '$'
)
+ ILLEGAL_NAME_CHARS = re.compile ( "[.:]{1,}" )
+ ILLEGAL_NAME_CHARS_REPLACE_BY = '_'
+
+
def __init__ ( self, **initial_info ):
"""Initializes a PackageInfo.
@@ -296,13 +300,20 @@ class PackageInfo ( object ):
# TODO: discard or continue with bad version?
logging.error (
"Cannot parse version string '%s' for '%s'"
- % ( filepath, version_str )
+ % ( _filename, version_str )
)
raise
# using package name as name (unless modified later),
# using pkg_version for the ebuild version
- self ['name'] = package_name
+
+ # removing illegal chars from the package_name
+ ebuild_name = PackageInfo.ILLEGAL_NAME_CHARS.sub (
+ PackageInfo.ILLEGAL_NAME_CHARS_REPLACE_BY, package_name
+ )
+ if ebuild_name != package_name:
+ self ['name'] = ebuild_name
+
self ['ebuild_verstr'] = version_str
# for DescriptionReader
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-03 17:48 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-03 17:48 UTC (permalink / raw
To: gentoo-commits
commit: 6485e56521930bb59e4fdcdddc015286aa6c874b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 3 17:45:55 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 3 17:45:55 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6485e565
roverlay/argutil (using argparse)
this sets up an ArgParser suitable for roverlay scripts
new file: roverlay/argutil.py
---
roverlay/argutil.py | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 211 insertions(+), 0 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
new file mode 100644
index 0000000..d1640ac
--- /dev/null
+++ b/roverlay/argutil.py
@@ -0,0 +1,211 @@
+
+import os.path
+import argparse
+import roverlay
+
+def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
+
+ def is_fs_file ( value ):
+ f = os.path.abspath ( value )
+ if not os.path.isfile ( f ):
+ raise argparse.ArgumentTypeError (
+ "%r is not a file." % value
+ )
+ return f
+
+ def is_fs_dir ( value ):
+ d = os.path.abspath ( value )
+ if not os.path.isdir ( d ):
+ raise argparse.ArgumentTypeError (
+ "%r is not a directory." % value
+ )
+ return d
+
+ def couldbe_fs_dir ( value ):
+ d = os.path.abspath ( value )
+ if os.path.exists ( d ) and not os.path.isdir ( d ):
+ raise argparse.ArgumentTypeError (
+ "%r cannot be a directory." % value
+ )
+ return d
+
+ parser = argparse.ArgumentParser (
+ description='\n'.join ((
+ roverlay.description_str, roverlay.license_str,
+ )),
+ epilog = 'Known commands:\n' + '\n'.join (
+ ( ( '* ' + c ).ljust(17) + ' - ' + d for (c,d) in CMD_DESC.items() )
+ ),
+ add_help=True,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ arg = parser.add_argument
+ opt_in = dict ( default=False, action='store_true' )
+ opt_out = dict ( default=True, action='store_false' )
+
+ fs_file = dict ( type=is_fs_file, metavar="<file>" )
+
+ # adding args starts here
+
+ arg (
+ '-V', '--version', action='version', version=roverlay.version_str
+ )
+
+ arg (
+ 'commands',
+ # fixme: CMD_DESC is "unknown", but default is set to a specific command
+ default='create',
+ help="action to perform. choices are " + ', '.join (CMD_DESC.keys()) + \
+ ". defaults to %(default)s.",
+ nargs="*",
+ choices=CMD_DESC.keys(),
+ metavar="command"
+ )
+
+ arg (
+ '-c', '--config',
+ default=DEFAULT_CONFIG,
+ help="config file",
+ **fs_file
+ )
+ arg (
+ '-F', '--field-definition', '--fdef', default=argparse.SUPPRESS,
+ help="field definition file",
+ **fs_file
+ )
+
+ arg (
+ '-R', '--repo-config', default=argparse.SUPPRESS,
+ action='append',
+ help="repo config file.",
+ **fs_file
+ )
+
+ arg (
+ '-D', '--deprule-file', default=argparse.SUPPRESS,
+ action='append',
+ help="simple rule file. can be specified more than once.",
+ **fs_file
+ )
+
+
+ arg (
+ '--distdir', '--from', default=argparse.SUPPRESS,
+ action='append',
+ help='''
+ use packages from %(metavar)s for ebuild creation (ignore all repos).
+ only useful for testing 'cause SRC_URI will be invalid in the created
+ ebuilds.
+ ''',
+ metavar="<DISTDIR>",
+ type=is_fs_dir
+ )
+
+ arg (
+ '--distroot', default=argparse.SUPPRESS,
+ help='''
+ use %(metavar)s as distdir root for repos
+ that don't define their own package dir.
+ ''',
+ metavar="<DISTROOT>",
+ type=couldbe_fs_dir
+ )
+
+ arg (
+ '--show',
+ help="print ebuilds and metadata to console",
+ **opt_in
+ )
+
+ arg (
+ '--write',
+ help="write overlay to filesystem",
+ # !! change to opt_out (FIXME)
+ **opt_in
+ )
+
+
+ arg (
+ '--nosync', '--no-sync',
+ help="disable syncing with remotes (offline mode). TODO",
+ **opt_in
+ )
+ arg (
+ '--force-distroot',
+ help="always use <DISTROOT>/<repo name> as repo distdir. TODO.",
+ **opt_in
+ )
+
+ arg (
+ '--debug',
+ help='''
+ Turn on debugging. This produces a lot of messages.
+ (TODO: always on).
+ ''',
+ **opt_out
+ )
+
+ return parser
+# --- end of get_parser (...) ---
+
+def parse_argv ( *args, **kw ):
+ """Parses sys.argv and returns the result as tuple
+ (<commands to run>, <config file>,
+ <dict for config>, <extra options as dict>).
+
+ All args/keywords are passed to get_parser().
+ Passes all exceptions.
+ """
+ def doconf ( value, path ):
+ pos = conf
+ if isinstance ( path, str ):
+ path = path.split ( '.' )
+ last = len ( path ) - 1
+ for i, k in enumerate ( path ):
+ if i == last:
+ pos [k.lower()] = value
+ else:
+ k = k.upper()
+ if not k in pos:
+ pos [k] = dict()
+
+ pos = pos [k]
+
+
+ p = get_parser ( *args, **kw ).parse_args()
+
+ given = lambda kw : hasattr ( p, kw )
+
+
+ conf = dict()
+ extra = dict (
+ nosync = p.nosync,
+ show = p.show,
+ write = p.write,
+ debug = p.debug,
+ force_distroot = p.force_distroot,
+ )
+
+ if given ( 'field_definition' ):
+ doconf ( p.field_definition, 'DESCRIPTION.field_definition_file' )
+
+ if given ( 'repo_config' ):
+ doconf ( p.repo_config, 'REPO.config_files' )
+
+ if given ( 'distroot' ):
+ doconf ( p.distroot, 'distfiles.root' )
+
+ if given ( 'distdir' ):
+ doconf ( (), 'REPO.config_files' )
+ extra ['distdir'] = p.distdir
+
+ if given ( 'deprule_file' ):
+ doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )
+
+
+ return (
+ ( p.commands, ) if isinstance ( p.commands, str ) else p.commands,
+ p.config, conf, extra
+ )
+# --- end of parse_argv (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-04 18:21 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-04 18:21 UTC (permalink / raw
To: gentoo-commits
commit: f10e073c8d8e10ccd5c165a2cdc03a36da0b4470
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jul 4 18:11:28 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jul 4 18:11:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f10e073c
util: remove easylock decorator
modified: roverlay/util.py
---
roverlay/util.py | 24 ------------------------
1 files changed, 0 insertions(+), 24 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index cf6c018..f66532a 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -11,30 +11,6 @@ from roverlay import config
LOGGER = logging.getLogger ( 'util' )
-def easylock ( _lock=threading.Lock() ):
- """This decorator locks the function while in use
- with either the given Lock or an anonymous threading.Lock.
-
- arguments:
- * _lock -- lock to use, defaults to threading.Lock()
-
- returns: wrapped function
- """
- def wrapper ( f ):
- """Wraps the function."""
- def _locked ( *args, **kw ):
- """Actual wrapper.
- Locks _lock, calls the function and releases _lock in any case."""
- try:
- _lock.acquire()
- f ( *args, **kw )
- finally:
- _lock.release()
- return _locked
-
- return wrapper
-# --- end of @easylock (<lock>) ---
-
def shorten_str ( s, maxlen, replace_end=None ):
if not replace_end is None:
rlen = maxlen - len ( replace_end )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-04 18:21 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-04 18:21 UTC (permalink / raw
To: gentoo-commits
commit: 2f210f30d60427f636e477890bd0091444fafe18
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jul 4 18:11:10 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jul 4 18:11:10 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2f210f30
argutil: --stats, --no-stats
---
roverlay/argutil.py | 40 +++++++++++++++++++++++++++++-----------
1 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index d1640ac..8e37694 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -89,7 +89,6 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
**fs_file
)
-
arg (
'--distdir', '--from', default=argparse.SUPPRESS,
action='append',
@@ -99,6 +98,7 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
ebuilds.
''',
metavar="<DISTDIR>",
+ dest='distdirs',
type=is_fs_dir
)
@@ -113,37 +113,52 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
)
arg (
- '--show',
+ '--show-overlay', '--show',
help="print ebuilds and metadata to console",
**opt_in
)
arg (
- '--write',
+ '--write-overlay', '--write',
help="write overlay to filesystem",
- # !! change to opt_out (FIXME)
+ # !! change to opt_out in future (FIXME)
**opt_in
)
+ # FIXME: swap --stats with --no-stats? (=> print stats by default)
+ arg (
+ '--stats',
+ help="print some stats",
+ **opt_in
+ )
+
+ arg (
+ '--no-stats',
+ help="don't print stats",
+ dest="stats",
+ **opt_out
+ )
arg (
'--nosync', '--no-sync',
- help="disable syncing with remotes (offline mode). TODO",
+ help="disable syncing with remotes (offline mode).",
**opt_in
)
+
arg (
'--force-distroot',
- help="always use <DISTROOT>/<repo name> as repo distdir. TODO.",
+ help="always use <DISTROOT>/<repo name> as repo distdir.",
**opt_in
)
+ # TODO
arg (
'--debug',
help='''
Turn on debugging. This produces a lot of messages.
(TODO: always on).
''',
- **opt_out
+ **opt_in
)
return parser
@@ -181,9 +196,10 @@ def parse_argv ( *args, **kw ):
conf = dict()
extra = dict (
nosync = p.nosync,
- show = p.show,
- write = p.write,
debug = p.debug,
+ show_overlay = p.show_overlay,
+ write_overlay = p.write_overlay,
+ print_stats = p.stats,
force_distroot = p.force_distroot,
)
@@ -196,9 +212,11 @@ def parse_argv ( *args, **kw ):
if given ( 'distroot' ):
doconf ( p.distroot, 'distfiles.root' )
- if given ( 'distdir' ):
+ if given ( 'distdirs' ):
doconf ( (), 'REPO.config_files' )
- extra ['distdir'] = p.distdir
+ extra ['distdirs'] = frozenset ( p.distdirs )
+ # FIXME:
+ # distdir implies --nosync, but LocalRepo doesn't care about that ( sync() is nosync() )
if given ( 'deprule_file' ):
doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-09 17:19 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-09 17:19 UTC (permalink / raw
To: gentoo-commits
commit: 9fd58ecaad91eb2d0bce5234c5eadc61b7904c36
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 9 16:27:40 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 9 16:27:40 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9fd58eca
argutil: --overlay-name and some logic
--from / --distdir now implies --nosync and create
modified: roverlay/argutil.py
---
roverlay/argutil.py | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 4750d15..6249644 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -119,6 +119,12 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
type=couldbe_fs_dir
)
+ arg (
+ '--overlay-name', '-N', default=argparse.SUPPRESS,
+ help="overlay name",
+ metavar="<name>",
+ dest="overlay_name"
+ )
arg (
'--show-overlay', '--show',
@@ -215,7 +221,7 @@ def parse_argv ( *args, **kw ):
given = lambda kw : hasattr ( p, kw )
-
+ commands = ( p.commands, ) if isinstance ( p.commands, str ) else p.commands
conf = dict()
extra = dict (
nosync = p.nosync,
@@ -232,6 +238,9 @@ def parse_argv ( *args, **kw ):
doconf ( p.overlay, 'OVERLAY.dir' )
extra ['write_overlay'] = True
+ if given ( 'overlay_name' ):
+ doconf ( p.overlay_name, 'OVERLAY.name' )
+
if given ( 'field_definition' ):
doconf ( p.field_definition, 'DESCRIPTION.field_definition_file' )
@@ -244,6 +253,9 @@ def parse_argv ( *args, **kw ):
if given ( 'distdirs' ):
doconf ( (), 'REPO.config_files' )
extra ['distdirs'] = frozenset ( p.distdirs )
+ extra ['nosync'] = True
+ # FIXME: COMMANDS are unknown here (theoretically)
+ commands.append ( "create" )
# FIXME:
# distdir implies --nosync, but LocalRepo doesn't care about that ( sync() is nosync() )
@@ -251,8 +263,5 @@ def parse_argv ( *args, **kw ):
doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )
- return (
- ( p.commands, ) if isinstance ( p.commands, str ) else p.commands,
- p.config, conf, extra
- )
+ return ( commands, p.config, conf, extra )
# --- end of parse_argv (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-10 17:43 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-10 17:43 UTC (permalink / raw
To: gentoo-commits
commit: 0c9efb4ddce50c2c9e94100eb77812238650d7eb
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 10 17:43:08 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 10 17:43:08 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0c9efb4d
try to run without a config file
---
roverlay/__init__.py | 3 ++-
roverlay/argutil.py | 8 +++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 1399df0..3d1ecfa 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -27,7 +27,8 @@ def load_config_file ( cfile, extraconf=None ):
* extraconf -- a dict with additional config entries that will override
entries read from cfile
"""
- roverlay.config.loader().load_config ( cfile )
+ if cfile:
+ roverlay.config.loader().load_config ( cfile )
if extraconf is not None:
roverlay.config.access().merge_with ( extraconf )
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 6249644..98a0406 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -29,6 +29,12 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
)
return d
+ def is_fs_file_or_void ( value ):
+ if value:
+ return is_fs_file ( value )
+ else:
+ return ''
+
parser = argparse.ArgumentParser (
description='\n'.join ((
roverlay.description_str, roverlay.license_str,
@@ -67,7 +73,7 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
'-c', '--config',
default=DEFAULT_CONFIG,
help="config file",
- **fs_file
+ type=is_fs_file_or_void, metavar="<file>"
)
arg (
'-F', '--field-definition', '--fdef', default=argparse.SUPPRESS,
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-16 16:15 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-16 16:15 UTC (permalink / raw
To: gentoo-commits
commit: 5e67a62f326f96b813e8fdd19a50d236874a41bd
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 13 10:36:53 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 13 10:36:53 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5e67a62f
remove NopErrorQueue
---
roverlay/errorqueue.py | 29 ++++-------------------------
1 files changed, 4 insertions(+), 25 deletions(-)
diff --git a/roverlay/errorqueue.py b/roverlay/errorqueue.py
index d0aa042..2b5135a 100644
--- a/roverlay/errorqueue.py
+++ b/roverlay/errorqueue.py
@@ -1,33 +1,11 @@
-import sys
import threading
-class _EQueue ( object ) : pass
-
-class NopErrorQueue ( _EQueue ):
- """This can be used as error queue in single-threaded execution."""
- def __init__ ( self ):
- self.empty = True
-
- def push ( self, context, error ):
- self.empty = False
- sys.stderr.write ( "Exception from {!r}:\n".format ( context ) )
- raise error
-
- def really_empty ( self ): return self.empty
- def attach_queue ( self, q, unblock_item ): pass
- def remove_queue ( self, q ): pass
- def unblock_queues ( self ): pass
- def peek ( self ): return ( None, None )
- def get_all ( self ): return ( ( None, None ), )
- def get_exceptions ( self ): return ()
-
-
-#class ErrorQueue ( NopErrorQueue ):
-class ErrorQueue ( _EQueue ):
+class ErrorQueue ( object ):
"""This is the error queue for threaded execution."""
# (it's not a queue)
- def __init__ ( self ):
+ def __init__ ( self, using_threads=True ):
+ self.using_threads = using_threads
self.empty = True
self._exceptions = list()
# this error queue is able to unblock waiting queues (in future; TODO)
@@ -65,6 +43,7 @@ class ErrorQueue ( _EQueue ):
self.empty = False
self._unblock_queues()
+ if not self.using_threads: raise error
def unblock_queues ( self ):
"""Unblocks all attached queues."""
with self._lock:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-16 16:15 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-16 16:15 UTC (permalink / raw
To: gentoo-commits
commit: 35073605819b2238010a284da4678d31509ab191
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 16 16:03:47 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 16 16:03:47 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=35073605
util: function to remove non-ascii chars
---
roverlay/util.py | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index d658b15..2df4845 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -21,6 +21,11 @@ def fix_ebuild_name ( name ):
)
# --- end of fix_ebuild_name (...) ---
+def ascii_filter ( _str ):
+ """Removes all non-ascii chars from a string and returns the result."""
+ return ''.join ( c for c in _str if ord ( c ) < 128 )
+# --- end of ascii_filter (...) ---
+
def shorten_str ( s, maxlen, replace_end=None ):
if not replace_end is None:
rlen = maxlen - len ( replace_end )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2012-07-16 16:15 [gentoo-commits] proj/R_overlay:depres_wip " André Erdmann
@ 2012-07-16 16:15 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-16 16:15 UTC (permalink / raw
To: gentoo-commits
commit: f5e0ea775cc86046fc424a2c63e9709670a4fe6d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 16 11:17:20 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 16 11:17:20 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f5e0ea77
move fix_ebuild_name to util
---
roverlay/packageinfo.py | 9 ++-------
roverlay/util.py | 10 ++++++++++
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index cc09a6b..052fad7 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -41,10 +41,6 @@ class PackageInfo ( object ):
config.get_or_fail ( 'R_PACKAGE.suffix_regex' ) + '$'
)
- ILLEGAL_NAME_CHARS = re.compile ( "[.:]{1,}" )
- ILLEGAL_NAME_CHARS_REPLACE_BY = '_'
-
-
def __init__ ( self, **initial_info ):
"""Initializes a PackageInfo.
@@ -308,9 +304,8 @@ class PackageInfo ( object ):
# using pkg_version for the ebuild version
# removing illegal chars from the package_name
- ebuild_name = PackageInfo.ILLEGAL_NAME_CHARS.sub (
- PackageInfo.ILLEGAL_NAME_CHARS_REPLACE_BY, package_name
- )
+ ebuild_name = util.fix_ebuild_name ( package_name )
+
if ebuild_name != package_name:
self ['name'] = ebuild_name
diff --git a/roverlay/util.py b/roverlay/util.py
index f66532a..d658b15 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -11,6 +11,16 @@ from roverlay import config
LOGGER = logging.getLogger ( 'util' )
+_EBUILD_NAME_ILLEGAL_CHARS = re.compile ( "[.:]{1,}" )
+_EBUILD_NAME_ILLEGAL_CHARS_REPLACE_BY = '_'
+
+def fix_ebuild_name ( name ):
+ return _EBUILD_NAME_ILLEGAL_CHARS.sub (
+ _EBUILD_NAME_ILLEGAL_CHARS_REPLACE_BY,
+ name
+ )
+# --- end of fix_ebuild_name (...) ---
+
def shorten_str ( s, maxlen, replace_end=None ):
if not replace_end is None:
rlen = maxlen - len ( replace_end )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2012-07-18 16:49 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
@ 2012-07-30 8:52 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: 5cd02da17ef13323aff48dae2d5527396d298211
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jul 18 16:45:30 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jul 18 16:45:30 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5cd02da1
util, dodir: catch OSError if dir exists
---
roverlay/util.py | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index 2df4845..3f32646 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -94,11 +94,16 @@ def sysnop ( nop_returns_success=True, format_str=None ):
# --- end of sysnop (...) ---
def dodir ( directory, mkdir_p=False, **makedirs_kw ):
- if not os.path.isdir ( directory ):
+ if os.path.isdir ( directory ): return True
+ try:
if mkdir_p:
os.makedirs ( directory, **makedirs_kw )
else:
os.mkdir ( directory )
- return True
+ return True
+ except Exception as e:
+ LOGGER.exception ( e )
+ return os.path.isdir ( directory )
+
# --- end of dodir (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-30 8:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: 2c8f26987ba0e1fe111b45cd2d9566abb69372b9
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul 19 16:52:16 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul 19 16:52:16 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2c8f2698
packageinfo: compare_version, has_key
---
roverlay/packageinfo.py | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index a2910c5..f9d26d1 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -114,6 +114,38 @@ class PackageInfo ( object ):
return True
# --- end of _writelock_acquire (...) ---
+ def has_key ( self, *keys ):
+ for k in keys:
+ if k not in self._info:
+ # try harder - use get() with fallback value to see if value
+ # can be calculated
+ if self.get ( k, do_fallback=True ) is None:
+ return False
+ return True
+ # --- end of has_key (...) ---
+
+ has = has_key
+
+ def compare_version ( self, other_package ):
+ """Compares the version of two PackageInfo objects.
+ Returns 1 if self's version is higher, -1 if lower and 0 if equal.
+
+ arguments:
+ * other_package --
+ """
+ if other_package is None: return 1
+
+ my_ver = self.get ( 'version', fallback_value=0 )
+ other_ver = other_package.get ( 'version', fallback_value=0 )
+
+ if my_ver > other_ver:
+ return 1
+ elif my_ver == other_ver:
+ return 0
+ else:
+ return -1
+ # --- end of compare_version (...) ---
+
def get ( self, key, fallback_value=None, do_fallback=False ):
"""Returns the value specified by key.
The value is either calculated or taken from dict self._info.
@@ -172,7 +204,7 @@ class PackageInfo ( object ):
# fallback
- if do_fallback:
+ if do_fallback or fallback_value is not None:
return fallback_value
elif key_low in self.__class__.ALWAYS_FALLBACK:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2012-07-24 16:59 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
@ 2012-07-30 8:52 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: 6593a3562703348b5008847d92e820a75efaf921
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 24 16:56:54 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 24 16:56:54 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6593a356
PackageInfo: _remove_auto:ebuild_written, fix get
geändert: roverlay/packageinfo.py
---
roverlay/packageinfo.py | 31 +++++++++++++++++++++++++++++--
1 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 829b798..07b2e77 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -183,8 +183,9 @@ class PackageInfo ( object ):
# this doesn't work if the package is in a sub directory
# of the repo's distdir
return self._info ['origin'].distdir
- else:
+ elif 'package_file' in self._info:
return os.path.dirname ( self._info ['package_file'] )
+ # else fallback/KeyError
elif key_low == 'has_suggests':
# 'has_suggests' not in self._info -> assume False
@@ -234,6 +235,12 @@ class PackageInfo ( object ):
# --- end of __setitem__ (...) ---
def update_now ( self, **info ):
+ """Updates the package info data with temporarily enabling write access.
+ Data will be readonly after calling this method.
+
+ arguments:
+ * **info --
+ """
if len ( info ) == 0: return
with self._update_lock:
self.set_writeable()
@@ -374,7 +381,27 @@ class PackageInfo ( object ):
after entering status 'ebuild_status' (like ebuild in overlay and
written -> don't need the ebuild string etc.)
"""
- print ( "PackageInfo._remove_auto: method stub, request ignored." )
+ with self._update_lock:
+
+ if ebuild_status == 'ebuild_written':
+ # selectively copying required keys to a new info dict
+
+ to_keep = ( 'distdir', 'desc_data', 'ebuild_file', 'version' )
+
+ # needs python >= 2.7
+ info_new = { k : self.get ( k ) for k in to_keep }
+
+ # also add an ebuild stub to the new dict (workaround, FIXME)
+ info_new ['ebuild'] = True
+
+ if 'physical_only' in self._info:
+ info_new ['physical_only'] = self._info ['physical_only']
+
+ info_old = self._info
+ self._info = info_new
+ del info_old
+ # -- if
+ # -- lock
# --- end of _remove_auto (...) ---
def _use_filepath ( self, _filepath ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-30 8:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: 370d65c3ceef9ad482e13b4e9fbd98fe2a752b1a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 30 08:40:36 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 30 08:40:36 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=370d65c3
fix <str>.format() in packageinfo
---
roverlay/packageinfo.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 07b2e77..731b62c 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -345,7 +345,7 @@ class PackageInfo ( object ):
# TODO: discard or continue with bad version?
logging.error (
"Cannot parse version string {!r} for {!r}".format (
- ( _filename, version_str )
+ _filename, version_str
)
)
raise
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-07-31 17:51 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-07-31 17:51 UTC (permalink / raw
To: gentoo-commits
commit: 847956c1d54647d0cfdbd9de2adc21d8404b82ff
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 31 13:57:35 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 31 13:57:35 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=847956c1
PackageInfo.update: reduce if-checks
use a simple_keys iterable to determine which key,value pairs can directly be
used (self._info [key] = value) instead of an if-check per key.
The logger message for unknown keys is a bit more accurate now.
---
roverlay/packageinfo.py | 31 ++++++++++++++-----------------
1 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 731b62c..4514d4f 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -260,32 +260,29 @@ class PackageInfo ( object ):
# nothing to do
return
+ simple_keys = frozenset ((
+ 'origin',
+ 'desc_data',
+ 'ebuild',
+ 'ebuild_file',
+ 'physical_only',
+ 'src_uri'
+ ))
+
self._writelock_acquire()
for key, value in info.items():
- if key == 'filename':
+ if key in simple_keys:
+ self [key] = value
+
+ elif key == 'filename':
self._use_filename ( value )
elif key == 'distdir':
if value is not None:
self ['distdir'] = value
- elif key == 'origin':
- self ['origin'] = value
-
- elif key == 'desc_data':
- self ['desc_data'] = value
-
- elif key == 'ebuild':
- self ['ebuild'] = value
-
- elif key == 'ebuild_file':
- self ['ebuild_file'] = value
-
- elif key == 'physical_only':
- self ['physical_only'] = value
-
elif key == 'pvr':
self._use_pvr ( value )
@@ -309,7 +306,7 @@ class PackageInfo ( object ):
self._remove_auto ( value )
else:
- LOGGER.error ( "unknown info key {}!".format ( key ) )
+ LOGGER.error ( "in update(): unknown info key {}!".format ( key ) )
self._update_lock.release()
# --- end of update (**kw) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-01 7:25 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-01 7:25 UTC (permalink / raw
To: gentoo-commits
commit: 057e5f51ae4cd402a9a80105aa1dcd8993055a77
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 1 07:25:51 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 1 07:25:51 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=057e5f51
digest.py
---
roverlay/digest.py | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/roverlay/digest.py b/roverlay/digest.py
new file mode 100644
index 0000000..4ccbca2
--- /dev/null
+++ b/roverlay/digest.py
@@ -0,0 +1,35 @@
+import hashlib
+
+def md5sum_file ( fh, binary_digest=False ):
+ """Returns the md5 sum for an already opened file."""
+ md5 = hashlib.md5()
+ blocksize = 16384
+
+ block = fh.read ( blocksize )
+ while block:
+ md5.update ( block )
+ block = fh.read ( blocksize )
+
+ return md5.digest() if binary_digest else md5.hexdigest()
+# --- end of md5sum_file (...) ---
+
+
+_DIGEST_MAP = dict (
+ md5 = md5sum_file,
+)
+
+def digest_supported ( digest_type ):
+ """Returns True if the given digest type is supported, else False."""
+ return digest_type in _DIGEST_MAP
+# --- digest_supported (...) ---
+
+def dodigest_file ( _file, digest_type, binary_digest=False ):
+ ret = None
+ with open ( _file, mode='rb' ) as fh:
+ ret = _DIGEST_MAP [digest_type] ( fh, binary_digest=binary_digest )
+ return ret
+# --- end of dodigest_file (...) ---
+
+def digest_compare ( _file, digest, digest_type, binary_digest=False ):
+ return digest == dodigest_file ( _file, digest_type, binary_digest )
+# --- end of digest_compare (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-02 15:14 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-02 15:14 UTC (permalink / raw
To: gentoo-commits
commit: 1a0b951c506d40584bb2df25a975a17a832cb7e0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 2 15:09:32 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 2 15:09:32 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1a0b951c
errorqueue: remove done TODO
---
roverlay/errorqueue.py | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/roverlay/errorqueue.py b/roverlay/errorqueue.py
index 2b5135a..ba14fab 100644
--- a/roverlay/errorqueue.py
+++ b/roverlay/errorqueue.py
@@ -8,8 +8,7 @@ class ErrorQueue ( object ):
self.using_threads = using_threads
self.empty = True
self._exceptions = list()
- # this error queue is able to unblock waiting queues (in future; TODO)
- # id -> queue [, unblocking_item:=None]
+ # id -> queue, unblocking_item
self._queues_to_unblock = dict()
self._lock = threading.Lock()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-07 8:50 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-07 8:50 UTC (permalink / raw
To: gentoo-commits
commit: d0ed3e90f77542f1ba23d717f87ca850c585ec81
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 7 08:48:55 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 7 08:48:55 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d0ed3e90
strutil: bytes_try_decode()
---
roverlay/strutil.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index 3228df6..4bf3584 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -6,13 +6,15 @@
"""provides utility functions for string manipulation"""
-__all__ = [ 'ascii_filter', 'fix_ebuild_name',
+__all__ = [ 'ascii_filter', 'bytes_try_decode', 'fix_ebuild_name',
'pipe_lines', 'shorten_str', 'unquote'
]
import re
-_EBUILD_NAME_ILLEGAL_CHARS = re.compile ( "[.:]{1,}" )
+_DEFAULT_ENCODINGS = ( 'utf-8', 'ascii', 'iso8859_15', 'utf-16', 'latin_1' )
+
+_EBUILD_NAME_ILLEGAL_CHARS = re.compile ( "[.:]{1,}" )
_EBUILD_NAME_ILLEGAL_CHARS_REPLACE_BY = '_'
def fix_ebuild_name ( name ):
@@ -88,3 +90,46 @@ def unquote ( _str, keep_going=False):
return _str
# --- end of unquote (...) ---
+
+def bytes_try_decode (
+ byte_str,
+ encodings=_DEFAULT_ENCODINGS,
+ charwise_only=False,
+ force_decode=False
+):
+ """Tries to decode a bytes object to str whose encoding is unknown
+ but predictable (with charwise conversion as last resort).
+ Returns byte_str if byte_str is already a str and force_decode is False,
+ else a decoded str.
+
+ arguments:
+ * byte_str -- bytes object to decode
+ * encodings -- encodings to try (None, str or list/iterable of str)
+ * charwise_only -- do charwise conversion only
+ * force_decode -- decode byte_str even if it's already a str
+ """
+ if not isinstance ( byte_str, str ):
+ if not charwise_only and encodings:
+ ret = None
+ if not isinstance ( encodings, str ):
+ try_enc = encodings
+ else:
+ try_enc = ( encodings, )
+
+ for enc in try_enc:
+ try:
+ ret = byte_str.decode ( enc )
+ break
+ except:
+ ret = None
+
+ if ret is not None:
+ return ret
+
+ ret = ""
+ for c in byte_str:
+ ret += chr ( c )
+ return ret
+ else:
+ return byte_str
+# --- end of bytes_try_decode() ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-08 23:46 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-08 23:46 UTC (permalink / raw
To: gentoo-commits
commit: 127d47e6aba69a528e7f2c9172f105c970bf8239
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 8 23:47:01 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 8 23:47:01 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=127d47e6
PackageInfo: accept src_uri_base key
---
roverlay/packageinfo.py | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 5caa9ee..22e87f5 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -314,7 +314,8 @@ class PackageInfo ( object ):
'ebuild',
'ebuild_file',
'physical_only',
- 'src_uri'
+ 'src_uri_base',
+ 'src_uri',
))
self._writelock_acquire()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-08 23:46 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-08 23:46 UTC (permalink / raw
To: gentoo-commits
commit: b763fa4258340fc8081c311c7d299c944cf7484a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 8 23:46:17 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 8 23:46:17 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b763fa42
PackageInfo: use src_uri_base for src_uri if available
---
roverlay/packageinfo.py | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 3262fba..5caa9ee 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -224,7 +224,12 @@ class PackageInfo ( object ):
return False
elif key_low == 'src_uri':
- if 'origin' in self._info:
+ if 'src_uri_base' in self._info:
+ return \
+ self._info ['src_uri_base'] + '/' + \
+ self._info ['package_filename']
+
+ elif 'origin' in self._info:
return self._info ['origin'].get_src_uri (
self._info ['package_filename']
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-09 9:26 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-09 9:26 UTC (permalink / raw
To: gentoo-commits
commit: 5f9961f0b8039807353dc6ec01317213360c5bdc
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 9 08:32:38 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 9 08:32:38 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5f9961f0
argutil: --no-write, --no-incremental
* --write-overlay/--write is now enabled by default
* --no-incremental disables scanning of an existing overlay (thus allows
to overwrite existing ebuilds)
* --deprule-file/-D accepts a directory value now
* --overlay/-O no longer implies --write
---
roverlay/argutil.py | 59 +++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index db41204..e4afe4a 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -37,6 +37,15 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
return d
+ def is_fs_file_or_dir ( value ):
+ f = os.path.abspath ( value )
+ if os.path.isdir ( f ) or os.path.isfile ( f ):
+ return f
+ else:
+ raise argparse.ArgumentTypeError (
+ "{!r} is neither a file nor a directory.".format ( value )
+ )
+
def couldbe_fs_dir ( value ):
d = os.path.abspath ( value )
if os.path.exists ( d ) and not os.path.isdir ( d ):
@@ -113,7 +122,8 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
'-D', '--deprule-file', default=argparse.SUPPRESS,
action='append',
help="simple rule file. can be specified more than once.",
- **fs_file
+ type=is_fs_file_or_dir,
+ metavar='<file|dir>',
)
arg (
@@ -156,28 +166,46 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
arg (
'--show-overlay', '--show',
help="print ebuilds and metadata to console",
- **opt_in
+ dest="show_overlay",
+ default=False,
+ action="store_true",
+ )
+
+ arg (
+ '--no-show-overlay', '--no-show',
+ help="don't print ebuilds and metadata to console (default)",
+ dest="show_overlay",
+ action="store_false",
)
arg (
'--write-overlay', '--write',
- help="write overlay to filesystem",
- # !! change to opt_out in future (FIXME)
- **opt_in
+ help="write the overlay to filesystem",
+ dest="write_overlay",
+ default=True,
+ action="store_true",
+ )
+
+ arg (
+ '--no-write-overlay', '--no-write',
+ help="don't write the overlay",
+ dest="write_overlay",
+ action="store_false",
)
- # FIXME: swap --stats with --no-stats? (=> print stats by default)
arg (
'--stats',
help="print some stats",
- **opt_in
+ dest="stats",
+ default=True,
+ action="store_true",
)
arg (
'--no-stats',
help="don't print stats",
dest="stats",
- **opt_out
+ action="store_false",
)
arg (
@@ -213,6 +241,18 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
**opt_in
)
+ # FIXME: description of --no-incremental is not correct,
+ # --no-incremental currently means that an existing overlay won't be
+ # scanned for ebuilds (which means that ebuilds will be recreated),
+ # but old ebuilds won't be explicitly removed
+ arg (
+ '--no-incremental',
+ help="start overlay creation from scratch (ignore an existing overlay)",
+ dest='incremental',
+ default=True,
+ action='store_false',
+ )
+
# TODO
arg (
'--debug',
@@ -266,11 +306,12 @@ def parse_argv ( command_map, **kw ):
list_config = p.list_config_entries,
force_distroot = p.force_distroot,
skip_manifest = p.no_manifest,
+ incremental = p.incremental,
)
if given ( 'overlay' ):
doconf ( p.overlay, 'OVERLAY.dir' )
- extra ['write_overlay'] = True
+ #extra ['write_overlay'] = True
if given ( 'overlay_name' ):
doconf ( p.overlay_name, 'OVERLAY.name' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-13 18:07 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-13 18:07 UTC (permalink / raw
To: gentoo-commits
commit: aaddf097909078f6af1ca68ed53f1fe40c67bec0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 13 18:01:14 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 13 18:01:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=aaddf097
PackageInfo, update: filter keys with value = None
Added a set simple_keys_filter_none that matches keys
that will be only be added if their value is not None.
This is required to fix an issue caused by the remote module's
package_nofail functions that unconditionally forward keywords
like src_uri_base.
---
roverlay/packageinfo.py | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 22e87f5..244dbb7 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -314,10 +314,14 @@ class PackageInfo ( object ):
'ebuild',
'ebuild_file',
'physical_only',
- 'src_uri_base',
'src_uri',
))
+ simple_keys_filter_none = frozenset ((
+ 'src_uri_base',
+ 'distdir',
+ ))
+
self._writelock_acquire()
for key, value in info.items():
@@ -325,13 +329,13 @@ class PackageInfo ( object ):
if key in simple_keys:
self [key] = value
+ elif key in simple_keys_filter_none:
+ if value is not None:
+ self [key] = value
+
elif key == 'filename':
self._use_filename ( value )
- elif key == 'distdir':
- if value is not None:
- self ['distdir'] = value
-
elif key == 'pvr':
self._use_pvr ( value )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-08-20 11:16 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-08-20 11:16 UTC (permalink / raw
To: gentoo-commits
commit: 2610152acb3fcc3b73289bdd8617d6f8a3681238
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 20 11:12:17 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 20 11:12:17 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2610152a
argutil: remove --debug arg (has no effect)
---
roverlay/argutil.py | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index d3c498a..a990b25 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -262,15 +262,15 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
action='store_false',
)
- # TODO
- arg (
- '--debug',
- help='''
- Turn on debugging. This produces a lot of messages.
- (TODO: has no effect).
- ''',
- **opt_in
- )
+# # TODO
+# arg (
+# '--debug',
+# help='''
+# Turn on debugging. This produces a lot of messages.
+# (TODO: has no effect).
+# ''',
+# **opt_in
+# )
return parser
# --- end of get_parser (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2012-10-02 10:04 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2012-10-02 10:04 UTC (permalink / raw
To: gentoo-commits
commit: 8d7244bbf9dab106350e25d93cbc4efa6b4025c5
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Oct 2 10:03:40 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Oct 2 10:03:40 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=8d7244bb
actually remove --debug arg
This fixes commit 2610152acb3fcc3b73289bdd8617d6f8a3681238.
modified: roverlay/argutil.py
---
roverlay/argutil.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index a990b25..20c5025 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -307,7 +307,7 @@ def parse_argv ( command_map, **kw ):
conf = dict()
extra = dict (
nosync = p.nosync,
- debug = p.debug,
+# debug = p.debug,
show_overlay = p.show_overlay,
write_overlay = p.write_overlay,
print_stats = p.stats,
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-01-28 23:54 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-01-28 23:54 UTC (permalink / raw
To: gentoo-commits
commit: 1853a1c2a3f7371c9920f0c744992aac4d501944
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jan 28 21:19:12 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jan 28 23:37:04 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1853a1c2
roverlay/packageinfo: ebuild_filename, remove_auto
* new key: ebuild_filename
* update(): call _remove_auto() after processing all other keywords
---
roverlay/packageinfo.py | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index fb1a570..f4b7c9e 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -60,6 +60,10 @@ class PackageInfo ( object ):
no keys have been stored)
* _UPDATE_KEYS_FILTER_NONE -- like _UPDATE_KEYS_SIMPLE, but stores
key's value only if it is not None
+ * _REMOVE_KEYS_KEEP_EBUILD -- a set of keys that will be kept when
+ _remove_auto ( 'ebuild_written' ) is
+ called.
+ These keys must exist at this point!
"""
EBUILDVER_REGEX = re.compile ( '[-]{1,}' )
@@ -83,6 +87,11 @@ class PackageInfo ( object ):
'distdir',
))
+ _REMOVE_KEYS_KEEP_EBUILD = frozenset ((
+ 'distdir', 'desc_data', 'ebuild_file', 'version',
+ 'ebuild_filename', 'package_name', 'package_filename',
+ ))
+
def __init__ ( self, **initial_info ):
"""Initializes a PackageInfo.
@@ -281,6 +290,11 @@ class PackageInfo ( object ):
if ebuild_file is not None:
return os.path.dirname ( ebuild_file )
+ elif key_low == 'ebuild_filename':
+ ebuild_file = self._info ['ebuild_file']
+ if ebuild_file is not None:
+ return os.path.basename ( ebuild_file )
+
# end if <key matches ...>
@@ -357,6 +371,9 @@ class PackageInfo ( object ):
initial = len ( self._info ) == 0
+ # remove_auto has to be the last action (keyword order is not "stable")
+ remove_auto = info.pop ( 'remove_auto', None )
+
self._writelock_acquire()
for key, value in info.items():
@@ -393,9 +410,6 @@ class PackageInfo ( object ):
except KeyError:
pass
- elif key == 'remove_auto':
- self._remove_auto ( value )
-
elif key == 'make_desc_data':
if value:
self.get_desc_data()
@@ -404,6 +418,10 @@ class PackageInfo ( object ):
self.logger.error (
"in update(): unknown info key {}!".format ( key )
)
+ # -- end for;
+
+ if remove_auto:
+ self._remove_auto ( remove_auto )
self._update_lock.release()
# --- end of update (**kw) ---
@@ -481,7 +499,7 @@ class PackageInfo ( object ):
if ebuild_status == 'ebuild_written':
# selectively copying required keys to a new info dict
- to_keep = ( 'distdir', 'desc_data', 'ebuild_file', 'version' )
+ to_keep = self.__class__._REMOVE_KEYS_KEEP_EBUILD
# needs python >= 2.7
info_new = { k : self.get ( k ) for k in to_keep }
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-01-28 23:54 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-01-28 23:54 UTC (permalink / raw
To: gentoo-commits
commit: 354e0fc4600dfc235eda6d26fda48c4cc75e9905
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jan 28 21:17:57 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jan 28 23:37:04 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=354e0fc4
roverlay/strutil.py: split_whitespace() function
---
roverlay/strutil.py | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index 4bf3584..4a5ef5d 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -7,7 +7,7 @@
"""provides utility functions for string manipulation"""
__all__ = [ 'ascii_filter', 'bytes_try_decode', 'fix_ebuild_name',
- 'pipe_lines', 'shorten_str', 'unquote'
+ 'pipe_lines', 'shorten_str', 'unquote', 'split_whitespace',
]
import re
@@ -17,6 +17,12 @@ _DEFAULT_ENCODINGS = ( 'utf-8', 'ascii', 'iso8859_15', 'utf-16', 'latin_1' )
_EBUILD_NAME_ILLEGAL_CHARS = re.compile ( "[.:]{1,}" )
_EBUILD_NAME_ILLEGAL_CHARS_REPLACE_BY = '_'
+_WHITESPACE = re.compile ( '\s+' )
+
+def split_whitespace ( _str, **kwargs ):
+ return _WHITESPACE.split ( _str, **kwargs )
+# --- end of split_whitespace (...) ---
+
def fix_ebuild_name ( name ):
"""Removes illegal chars from an ebuild name by replacing them with an
underscore char '_'.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-01-28 23:54 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-01-28 23:54 UTC (permalink / raw
To: gentoo-commits
commit: dc620de71cceab25dad17b7d44c4c5a5167b4956
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jan 28 22:56:05 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jan 28 23:37:04 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=dc620de7
roverlay/argutil: --manifest-implementation
Choose Manifest implementation via command line arg.
Meant for testing the portagemanifest impl.
---
roverlay/argutil.py | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 20c5025..ceb8baa 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -250,6 +250,13 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
**opt_in
)
+ arg (
+ '--manifest-implementation', '-M', default=argparse.SUPPRESS,
+ help="choose how Manifest files are written (ebuild(1) or portage libs)",
+ metavar="<impl>",
+ choices=frozenset (( 'ebuild', 'e', 'portage', 'p' )),
+ )
+
# FIXME: description of --no-incremental is not correct,
# --no-incremental currently means that an existing overlay won't be
# scanned for ebuilds (which means that ebuilds will be recreated),
@@ -348,6 +355,8 @@ def parse_argv ( command_map, **kw ):
if given ( 'deprule_file' ):
doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )
+ if given ( 'manifest_implementation' ):
+ doconf ( p.manifest_implementation, 'OVERLAY.manifest_implementation' )
return ( commands, p.config, conf, extra )
# --- end of parse_argv (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-01-30 20:16 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-01-30 20:16 UTC (permalink / raw
To: gentoo-commits
commit: 78675495ed708852d5771ebd98aec38d0c2ed6ab
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jan 30 19:57:42 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jan 30 20:00:33 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=78675495
packageinfo: update_unsafe(), add ebuild variables
new function update_unsafe() that simply adds information to a PackageInfo
instance without locking or checking for writability.
added EVAR* key that can be used to add per-package ebuild variables (evar)
---
roverlay/packageinfo.py | 45 ++++++++++++++++++++++++++++++++++++---------
1 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index f4b7c9e..438433c 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -357,6 +357,17 @@ class PackageInfo ( object ):
self.set_readonly()
# --- end of update_now (...) ---
+ def update_unsafe ( self, **info ):
+ """Updates the package info data without retrieving any locks or
+ checking writability.
+ Meant for usage with "package actions" (packagerules module).
+
+ arguments:
+ * **info --
+ """
+ self._update ( info )
+ # --- end of update_unsafe (...) ---
+
def update ( self, **info ):
"""Uses **info to update the package info data.
@@ -369,13 +380,27 @@ class PackageInfo ( object ):
# nothing to do
return
- initial = len ( self._info ) == 0
-
# remove_auto has to be the last action (keyword order is not "stable")
remove_auto = info.pop ( 'remove_auto', None )
self._writelock_acquire()
+ self._update ( info )
+
+ if remove_auto:
+ self._remove_auto ( remove_auto )
+
+ self._update_lock.release()
+ # --- end of update (**kw) ---
+
+ def _update ( self, info ):
+ """Updates self._info using the given info dict.
+
+ arguments:
+ * info --
+ """
+ initial = len ( self._info ) == 0
+
for key, value in info.items():
if key in self.__class__._UPDATE_KEYS_SIMPLE:
@@ -384,6 +409,13 @@ class PackageInfo ( object ):
elif initial and key in self.__class__._UPDATE_KEYS_SIMPLE_INITIAL:
self [key] = value
+ elif key[:4] == 'EVAR':
+ if 'EVAR' in self._info:
+ self._info ['EVAR'].add ( value )
+ else:
+ # set or dict?
+ self._info ['EVAR'] = set ( ( value, ) )
+
elif key in self.__class__._UPDATE_KEYS_FILTER_NONE:
if value is not None:
self [key] = value
@@ -416,15 +448,10 @@ class PackageInfo ( object ):
else:
self.logger.error (
- "in update(): unknown info key {}!".format ( key )
+ "in _update(): unknown info key {}!".format ( key )
)
# -- end for;
-
- if remove_auto:
- self._remove_auto ( remove_auto )
-
- self._update_lock.release()
- # --- end of update (**kw) ---
+ # --- end of _update (...) ---
def _use_filename ( self, _filename ):
"""auxiliary method for update(**kw)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-01-30 20:16 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-01-30 20:16 UTC (permalink / raw
To: gentoo-commits
commit: 9a715ef8a5c0553b85184b423f977cced4648adb
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jan 30 20:05:51 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jan 30 20:05:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9a715ef8
util: priosort()
Sorts the items of an iterable by priority.
---
roverlay/util.py | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index be2cd33..8f737c1 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -6,13 +6,32 @@
"""provides utility functions commonly used"""
-__all__= [ 'dodir', 'keepenv', 'sysnop', ]
+__all__= [ 'dodir', 'keepenv', 'sysnop', 'get_dict_hash', 'priosort', ]
import os
import logging
LOGGER = logging.getLogger ( 'util' )
+def priosort ( iterable ):
+ """Sorts the items of an iterable by priority (lower value means higher
+ priority).
+
+ arguments:
+ * iterable
+ """
+ def priokey ( item ):
+ """Returns the priority of an item.
+
+ arguments:
+ * item --
+ """
+ return item.priority
+ # --- end of priokey (...) ---
+
+ return sorted ( iterable, key=priokey )
+# --- end of priosort (...) ---
+
def keepenv ( *to_keep ):
"""Selectively imports os.environ.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-02-05 17:48 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-02-05 17:48 UTC (permalink / raw
To: gentoo-commits
commit: 24e73a658d50c29d4acc60f91722706a73719386
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Feb 5 17:25:53 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Feb 5 17:25:53 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=24e73a65
roverlay/strutil: wildcard_to_regex()
---
roverlay/strutil.py | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index 4a5ef5d..f5ab8fd 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -23,6 +23,20 @@ def split_whitespace ( _str, **kwargs ):
return _WHITESPACE.split ( _str, **kwargs )
# --- end of split_whitespace (...) ---
+def wildcard_to_regex ( _str, unsafe ):
+ # TODO: find a function that is more efficient
+ if unsafe:
+ return _str.replace ( '?', '.' ).replace ( '*', '.*?' )
+ else:
+ return '[*]'.join (
+ (
+ '[?]'.join (
+ i.replace ( '?', '.' ) for i in a.split ( '\\?' )
+ ).replace ( '*', '.*?' )
+ ) for a in _str.split ( '\\*' )
+ )
+# --- end of wildcard_to_regex (...) ---
+
def fix_ebuild_name ( name ):
"""Removes illegal chars from an ebuild name by replacing them with an
underscore char '_'.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-02-05 17:48 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-02-05 17:48 UTC (permalink / raw
To: gentoo-commits
commit: 1b78546536ddad0c80eaa6c98d4e073f0c7c3357
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Feb 5 17:26:31 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Feb 5 17:26:31 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1b785465
roverlay/util: for_all_files(), get_dict_hash()
for_all_files(): accepts a list of "files or dirs" and calls a function
for each file (dirs will be recursively expanded)
get_dict_hash(): a (slow) function that creates a hash for a dict
by hashing a frozenset of (key,value)-tuples
---
roverlay/util.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/roverlay/util.py b/roverlay/util.py
index 8f737c1..4712b63 100644
--- a/roverlay/util.py
+++ b/roverlay/util.py
@@ -6,13 +6,56 @@
"""provides utility functions commonly used"""
-__all__= [ 'dodir', 'keepenv', 'sysnop', 'get_dict_hash', 'priosort', ]
+__all__= [
+ 'dodir', 'keepenv', 'sysnop', 'get_dict_hash', 'priosort',
+ 'for_all_files'
+]
import os
import logging
LOGGER = logging.getLogger ( 'util' )
+def for_all_files (
+ files_or_dirs, func,
+ args=(), kwargs={}, file_filter=None, ignore_missing=False
+):
+ """
+ Runs "func ( <file>, *args, **kwargs )" for each <file> in files_or_dirs.
+ Dirs will be recursively "expanded" (= for all files/dirs in dir...).
+
+ arguments:
+ * files_or_dirs -- an iterable with files or dirs
+ * func -- function that will be called for each file
+ * args -- args that will be passed to each func call
+ Defaults to () (empty tuple)
+ * kwargs -- keyword args that will be passed to each func call
+ Defaults to {} (empty dict)
+ * file_filter -- if not None: func will only be called if this function
+ returns True for <file>
+ Defaults to None
+ * ignore_missing -- if True: do not raise an exception if a file/dir is
+ missing
+ Defaults to False
+ """
+ # alternative: os.walk()
+ def recursive_do ( fpath ):
+ if os.path.isfile ( fpath ):
+ if file_filter is None or file_filter ( fpath ):
+ func ( fpath, *args, **kwargs )
+ elif os.path.isdir ( fpath ):
+ for fname in os.listdir ( fpath ):
+ recursive_do ( fpath + os.sep + fname )
+ elif os.access ( fpath, os.F_OK ):
+ raise Exception ( "{}: neither a file nor a dir.".format ( fpath ) )
+ elif not ignore_missing:
+ raise Exception ( "{!r} does not exist!".format ( fpath ) )
+ # --- end of recursive_do (...) ---
+
+ for f in files_or_dirs:
+ recursive_do ( f )
+# --- end of for_all_files (...) ---
+
def priosort ( iterable ):
"""Sorts the items of an iterable by priority (lower value means higher
priority).
@@ -32,6 +75,17 @@ def priosort ( iterable ):
return sorted ( iterable, key=priokey )
# --- end of priosort (...) ---
+def get_dict_hash ( kwargs ):
+ # dict is not hashable, instead hash a frozenset of (key,value) tuples
+ # !!! this operations costs (time)
+ return hash (
+ frozenset (
+ ( k, v ) for k, v in kwargs.items()
+ )
+ )
+# --- end of get_dict_hash (...) ---
+
+
def keepenv ( *to_keep ):
"""Selectively imports os.environ.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-02-09 20:45 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-02-09 20:45 UTC (permalink / raw
To: gentoo-commits
commit: dd748310b8ed1b939b9da9d1efad0babfdacd2e0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Feb 9 19:11:55 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Feb 9 20:08:14 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=dd748310
packageinfo: _remove_auto(), fix has_key*()
_remove_auto() deletes keys that are no longer required now instead of
creating a new dict() (behavior changed from a "whitelist"- to a "blacklist"
approach)
has_key()/has_key_or(): catch KeyError and log it as error since
<package>.get( key, do_fallback=True ) should not raise it.
---
roverlay/packageinfo.py | 65 ++++++++++++++++++++++++----------------------
1 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 438433c..05c6feb 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -60,10 +60,9 @@ class PackageInfo ( object ):
no keys have been stored)
* _UPDATE_KEYS_FILTER_NONE -- like _UPDATE_KEYS_SIMPLE, but stores
key's value only if it is not None
- * _REMOVE_KEYS_KEEP_EBUILD -- a set of keys that will be kept when
+ * _REMOVE_KEYS_EBUILD -- a set of keys that will be removed when
_remove_auto ( 'ebuild_written' ) is
called.
- These keys must exist at this point!
"""
EBUILDVER_REGEX = re.compile ( '[-]{1,}' )
@@ -87,9 +86,8 @@ class PackageInfo ( object ):
'distdir',
))
- _REMOVE_KEYS_KEEP_EBUILD = frozenset ((
- 'distdir', 'desc_data', 'ebuild_file', 'version',
- 'ebuild_filename', 'package_name', 'package_filename',
+ _REMOVE_KEYS_EBUILD = frozenset ((
+ 'ebuild'
))
def __init__ ( self, **initial_info ):
@@ -169,6 +167,14 @@ class PackageInfo ( object ):
return True
# --- end of _writelock_acquire (...) ---
+ def _has_log_keyerror_unexpected ( self, key, error ):
+ self.logger.error (
+ 'FIXME: PackageInfo.get( {!r}, do_fallback=True ) '
+ 'raised KeyError'.format ( key )
+ )
+ self.logger.exception ( error )
+ # --- end of _has_log_keyerror_unexpected (...) ---
+
def has_key ( self, *keys ):
"""Returns False if at least one key out of keys is not accessible,
i.e. its data cannot be retrieved using get()/__getitem__().
@@ -180,7 +186,11 @@ class PackageInfo ( object ):
if k not in self._info:
# try harder - use get() with fallback value to see if value
# can be calculated
- if self.get ( k, do_fallback=True ) is None:
+ try:
+ if self.get ( k, do_fallback=True ) is None:
+ return False
+ except KeyError as kerr:
+ self._has_log_keyerror_unexpected ( k, kerr )
return False
return True
# --- end of has_key (...) ---
@@ -194,10 +204,13 @@ class PackageInfo ( object ):
* *keys -- keys to check
"""
for k in keys:
- if k in self._info:
- return True
- elif self.get ( k, do_fallback=True ) is not None:
- return True
+ try:
+ if k in self._info:
+ return True
+ elif self.get ( k, do_fallback=True ) is not None:
+ return True
+ except KeyError as kerr:
+ self._has_log_keyerror_unexpected ( k, kerr )
return False
# --- end of has_key_or (...) ---
@@ -248,11 +261,11 @@ class PackageInfo ( object ):
return self._info ['package_name']
elif key_low == 'package_file':
- # assuming that origin is in self._info
- return os.path.join (
- self.get ( 'distdir' ),
- self._info ['package_filename']
- )
+ distdir = self.get ( 'distdir', do_fallback=True )
+ if distdir:
+ fname = self._info.get ( 'package_filename', None )
+ if fname:
+ return distdir + os.path.sep + fname
elif key_low == 'distdir':
if 'origin' in self._info:
@@ -524,24 +537,14 @@ class PackageInfo ( object ):
with self._update_lock:
if ebuild_status == 'ebuild_written':
- # selectively copying required keys to a new info dict
-
- to_keep = self.__class__._REMOVE_KEYS_KEEP_EBUILD
-
- # needs python >= 2.7
- info_new = { k : self.get ( k ) for k in to_keep }
- # also add an ebuild stub to the new dict to indicate
- # that this PackageInfo instance has been created from been
- # created from an R package in this script run
- info_new ['ebuild'] = True
+ # selectively deleting entries that are no longer required
- if 'physical_only' in self._info:
- info_new ['physical_only'] = self._info ['physical_only']
-
- info_old = self._info
- self._info = info_new
- del info_old
+ for key in self.__class__._REMOVE_KEYS_EBUILD:
+ try:
+ del self._info [key]
+ except KeyError:
+ pass
# -- if
# -- lock
# --- end of _remove_auto (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-03-05 11:27 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-03-05 11:27 UTC (permalink / raw
To: gentoo-commits
commit: f7b72377d6de31460a846ef265949bb87327b7f0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Mar 5 11:19:02 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Mar 5 11:19:02 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f7b72377
argutil: rename --distdir to --local-distdir
The meaning of "distdir" has changed as it is also used for
Manifest file creation and as package mirror directory while
'--distdir' means "create ebuilds for packages from a local directory".
---
roverlay/argutil.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index d7d8444..23804b6 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -135,7 +135,7 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
- '--distdir', '--from', default=argparse.SUPPRESS,
+ '--local-distdir', '--from', default=argparse.SUPPRESS,
action='append',
help='''
use packages from %(metavar)s for ebuild creation (ignore all repos).
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-04-25 16:44 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-04-25 16:44 UTC (permalink / raw
To: gentoo-commits
commit: 4f5260ef21e696548fbf04a54bc67df21ff86aa7
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sun Mar 17 11:54:34 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sun Mar 17 16:06:22 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4f5260ef
strutil: add additional_filter to ascii_filter()
The additional_filter arg should be None or a function Char -> Bool
that can be used to filter out unwanted ascii chars without the need
of an extra string iteration.
---
roverlay/strutil.py | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index f5ab8fd..f0d60df 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -52,9 +52,22 @@ def fix_ebuild_name ( name ):
)
# --- end of fix_ebuild_name (...) ---
-def ascii_filter ( _str ):
- """Removes all non-ascii chars from a string and returns the result."""
- return ''.join ( c for c in _str if ord ( c ) < 128 )
+def ascii_filter ( _str, additional_filter=None ):
+ """Removes all non-ascii chars from a string and returns the result.
+
+ arguments:
+ * _str -- string to be filtered
+ * additional_filter -- a function that is called for each ascii char
+ and returns true if the char is allowed (i.e.,
+ should be kept in the resulting string), else False.
+ Defaults to None, which means "keep all".
+ """
+ if additional_filter is None:
+ return ''.join ( c for c in _str if ord ( c ) < 128 )
+ else:
+ return ''.join (
+ c for c in _str if ord ( c ) < 128 and additional_filter ( c )
+ )
# --- end of ascii_filter (...) ---
def shorten_str ( s, maxlen, replace_end=None ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-04-25 16:44 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-04-25 16:44 UTC (permalink / raw
To: gentoo-commits
commit: 311ac182bba51393153f1c4de4b2580461023608
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Apr 23 00:56:13 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Apr 23 00:56:13 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=311ac182
roverlay/main: apply_rules command
This command applies the package rules to all packages and prints the result
(package filtered out, package modifed: evar...) to stdout (or to --dump-file).
---
roverlay/argutil.py | 26 ++++++++++++++
roverlay/main.py | 92 +++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 100 insertions(+), 18 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 23804b6..7237eba 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -29,6 +29,19 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
return f
+ def couldbe_fs_file ( value ):
+ if value:
+ f = os.path.abspath ( value )
+ if not os.path.exists ( f ) or os.path.isfile ( f ):
+ return f
+
+ raise argparse.ArgumentTypeError (
+ "{!r} is not a file.".format ( value )
+ )
+
+ def couldbe_stdout_or_file ( value ):
+ return value if value == "-" else couldbe_fs_file ( value )
+
def is_fs_dir ( value ):
d = os.path.abspath ( value )
if not os.path.isdir ( d ):
@@ -283,6 +296,18 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
action='store_false',
)
+ arg (
+ '--dump-file',
+ help='''
+ standard file or stdout target for dumping information
+ (defaults to '-'). Used by the 'apply_rules' action.
+ ''',
+ dest="dump_file",
+ default="-",
+ metavar="<file>",
+ type=couldbe_stdout_or_file,
+ )
+
# # TODO
# arg (
# '--debug',
@@ -339,6 +364,7 @@ def parse_argv ( command_map, **kw ):
skip_manifest = p.no_manifest,
incremental = p.incremental,
immediate_ebuild_writes = p.immediate_ebuild_writes,
+ dump_file = p.dump_file,
)
if given ( 'overlay' ):
diff --git a/roverlay/main.py b/roverlay/main.py
index b525ffe..7090689 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -119,6 +119,56 @@ def main (
raise
# --- end of run_sync() ---
+ def run_apply_package_rules():
+ if "apply_rules" in actions_done: return
+
+ dump_file = OPTION ( "dump_file" )
+ FH = None
+
+ prules = PackageRules.get_configured()
+
+ # track package rules
+ prules.add_trace_actions()
+
+
+ BEGIN_RECEIVE_PACKAGE = ( 8 * '-' ) + " {header} " + ( 8 * '-' ) + '\n'
+ END_RECEIVE_PACKAGE = ( 31 * '-' ) + '\n\n'
+
+ get_header = lambda p : BEGIN_RECEIVE_PACKAGE.format (
+ header = ( p ['name'] + ' ' + p ['ebuild_verstr'] )
+ )
+
+ def receive_package ( P ):
+ if prules.apply_actions ( P ):
+ if hasattr ( P, 'modified_by_package_rules' ):
+ # ^ that check is sufficient here
+ #if P.modified_by_package_rules
+
+ FH.write ( get_header ( P ) )
+
+ evars = P.get_evars()
+ if evars:
+ FH.write ( "evars applied:\n" )
+ for evar in evars:
+ FH.write ( "* {}\n".format ( evar ) )
+
+ FH.write ( END_RECEIVE_PACKAGE )
+ else:
+ FH.write ( get_header ( P ) )
+ FH.write ( "filtered out!\n" )
+ FH.write ( END_RECEIVE_PACKAGE )
+
+ # --- end of receive_package (...) ---
+
+ if dump_file == "-":
+ FH = sys.stdout
+ repo_list.add_packages ( receive_package )
+ else:
+ with open ( dump_file, 'wt' ) as FH:
+ repo_list.add_packages ( receive_package )
+
+ # --- end of run_apply_package_rules (...) ---
+
def run_overlay_create():
if "create" in actions_done: return
#run_sync()
@@ -182,6 +232,7 @@ def main (
'run an interactive depres console (highly experimental)',
'depres' : 'this is an alias to \'depres_console\'',
'nop' : 'does nothing',
+ 'apply_rules' : 'apply package rules verbosely and exit afterwards',
}
@@ -217,6 +268,8 @@ def main (
# imports roverlay.remote, roverlay.overlay.creator
actions = set ( filter ( lambda x : x != 'nop', commands ) )
+ actions_done = set()
+ set_action_done = actions_done.add
if 'sync' in actions and OPTION ( 'nosync' ):
die ( "sync command blocked by --nosync opt.", DIE.ARG )
@@ -282,11 +335,13 @@ def main (
import roverlay.packagerules.rules
+ package_rules = (
+ roverlay.packagerules.rules.PackageRules.get_configured()
+ )
+
HLINE = "".rjust ( 79, '-' )
print ( HLINE )
- print (
- str ( roverlay.packagerules.rules.PackageRules.get_configured() )
- )
+ print ( str ( package_rules ) )
print ( HLINE )
EXIT_AFTER_CONFIG = True
@@ -294,8 +349,7 @@ def main (
# -- end of EXIT_AFTER_CONFIG entries
if 'EXIT_AFTER_CONFIG' in locals() and EXIT_AFTER_CONFIG:
- pass
- #sys.exit ( os.EX_OK )
+ sys.exit ( os.EX_OK )
# switch to depres console
elif 'depres_console' in actions or 'depres' in actions:
@@ -306,7 +360,7 @@ def main (
from roverlay.depres.simpledeprule.console import DepResConsole
con = DepResConsole()
con.run()
- sys.exit ( os.EX_OK )
+ set_action_done ( "depres_console" )
except ImportError:
if HIDE_EXCEPTIONS:
die ( "Cannot import depres console!", DIE.IMPORT )
@@ -332,25 +386,27 @@ def main (
raise
# -- run methods (and some vars)
- # imports: nothing
+ # imports: package rules
#repo_list = None
#overlay_creator = None
- actions_done = set()
- set_action_done = actions_done.add
-
# -- run
- # always run sync 'cause commands = {create,sync}
- # and create implies (no)sync
+ # always run sync 'cause commands = {create,sync,apply_rules}
+ # and create,apply_rules implies (no)sync
run_sync()
- if 'create' in actions: run_overlay_create()
+ if "apply_rules" in actions:
+ from roverlay.packagerules.rules import PackageRules
+ run_apply_package_rules()
+ elif 'create' in actions:
+ run_overlay_create()
- if len ( actions ) > len ( actions_done ):
- die (
- "Some actions (out of {!r}) could not be performed!".format (
- actions ), DIE.CMD_LEFTOVER
- )
+
+ if len ( actions ) > len ( actions_done ):
+ die (
+ "Some actions (out of {!r}) could not be performed!".format (
+ actions ), DIE.CMD_LEFTOVER
+ )
# --- end of main (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-04 21:06 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-04 21:06 UTC (permalink / raw
To: gentoo-commits
commit: a3647944a790117bd668c48f578b3d3fcfe2d5d3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon May 13 18:48:28 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon May 13 18:48:28 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a3647944
'apply_rules' command: count modified packages
---
roverlay/main.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 68 insertions(+), 6 deletions(-)
diff --git a/roverlay/main.py b/roverlay/main.py
index 7090689..c3f919b 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -130,6 +130,8 @@ def main (
# track package rules
prules.add_trace_actions()
+ NUM_MODIFIED = 0
+
BEGIN_RECEIVE_PACKAGE = ( 8 * '-' ) + " {header} " + ( 8 * '-' ) + '\n'
END_RECEIVE_PACKAGE = ( 31 * '-' ) + '\n\n'
@@ -138,6 +140,28 @@ def main (
header = ( p ['name'] + ' ' + p ['ebuild_verstr'] )
)
+ def bool_counter ( f ):
+ """Wrapper that returns a 2-tuple (result_list, function f').
+ f' which increases result_list first or second element depending
+ on the return value of function f.
+
+ arguments:
+ * f -- function to wrap
+ """
+ result_list = [ 0, 0 ]
+
+ def wrapped ( *args, **kwargs ):
+ result = f ( *args, **kwargs )
+ if result:
+ result_list [0] += 1
+ else:
+ result_list [1] += 1
+ return result
+ # --- end of wrapped (...) ---
+
+ return result_list, wrapped
+ # --- end of bool_counter (...) ---
+
def receive_package ( P ):
if prules.apply_actions ( P ):
if hasattr ( P, 'modified_by_package_rules' ):
@@ -152,20 +176,58 @@ def main (
for evar in evars:
FH.write ( "* {}\n".format ( evar ) )
+
+ if P.modified_by_package_rules is not True:
+ # ^ check needs to be changed when adding more trace actions
+ FH.write ( "trace marks:\n" )
+ for s in P.modified_by_package_rules:
+ if s is not True:
+ FH.write ( "* {}\n".format ( s ) )
+
FH.write ( END_RECEIVE_PACKAGE )
+ else:
+ # not modified
+ return False
else:
FH.write ( get_header ( P ) )
FH.write ( "filtered out!\n" )
FH.write ( END_RECEIVE_PACKAGE )
+ # modifed
+ return True
# --- end of receive_package (...) ---
- if dump_file == "-":
- FH = sys.stdout
- repo_list.add_packages ( receive_package )
- else:
- with open ( dump_file, 'wt' ) as FH:
- repo_list.add_packages ( receive_package )
+ modify_counter, receive_package_counting = bool_counter ( receive_package )
+
+ try:
+ if dump_file == "-":
+ FH_SHARED = True
+ FH = sys.stdout
+ else:
+ FH_SHARED = False
+ FH = open ( dump_file, 'wt' )
+
+ time_start = time.time()
+ repo_list.add_packages ( receive_package_counting )
+ time_add_packages = time.time() - time_start
+
+ if modify_counter [0] > 0:
+ FH.write ( "\n" )
+
+ #FH.write (
+ sys.stdout.write (
+ 'done after {t} seconds\n'
+ '{p} packages processed in total, out of which '
+ '{m} have been modified or filtered out\n'.format (
+ t = round ( time_add_packages, 1 ),
+ p = ( modify_counter [0] + modify_counter [1] ),
+ m = modify_counter [0]
+ )
+ )
+
+ finally:
+ if 'FH' in locals() and not FH_SHARED:
+ FH.close()
# --- end of run_apply_package_rules (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-13 16:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: 621d7b95dedf09850097304d1a3a4a9d87796591
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jun 4 20:32:14 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jun 4 20:32:14 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=621d7b95
packageinfo: doc, method stubs, set_direct_unsafe
* doc: PackageInfo key list
methods for new package rule actions (not committed yet):
* method stubs: attach_lazy_action()/apply_lazy_actions()
* set_direct_unsafe(): direct ("unsafe"!) write access to the info dict
---
roverlay/packageinfo.py | 69 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 56 insertions(+), 13 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index da3e5f1..c7c71eb 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -21,20 +21,34 @@ import threading
from roverlay import config, strutil
from roverlay.rpackage import descriptionreader
+# PackageInfo info keys know to be used in roverlay's modules:
+# *** some keys are not listed here (FIXME) ***
#
-# PackageInfo keys known to be used (read) in the roverlay modules:
+# * desc_data -- dict containing DESCRIPTION data (created by
+# rpackage.descriptionreader.DescriptionReader)
+# * distdir -- fs path to the directory containing the pkg (file)
+# * ebuild -- object representing the ebuild (printable via str())
+# * ebuild_file -- fs path to the ebuild file (str)
+# * ebuild_verstr -- version string as it's used in the ebuild
+# * has_suggests -- bool that indicates whether a package has optional
+# dependencies
+# * name -- (ebuild) name of a package (no "special" chars etc.)
+# * orig_name -- original (ebuild) name (before "name" has been
+# modified by package rules)
+# * origin -- a package's origin (repository object)
+# * package_file -- full fs path to the package file
+# * package_filename -- file name (including file extension)
+# * package_name -- package name (file name without version, f-ext)
+# * physical_only -- bool that indicates whether a package exists as
+# ebuild file only (True) or has additional
+# runtime data (False)
+# * src_uri -- SRC_URI for a package
+# * version -- tuple containing a package's version
#
-# * desc_data in ebuild/creation, metadata/__init__
-# * distdir in manifest/helpers
-# * ebuild in overlay/package
-# * ebuild_file in manifest/helpers, overlay/package
-# * ebuild_verstr in overlay/package
-# * name in ebuild/creation, overlay/category
-# * package_file in rpackage/descriptionreader
-# * package_name in rpackage/descriptionreader
-# * package_url in ebuild/creation
-# * physical_only in overlay/pacakge
-# * version in ebuild/package (as tuple)
+
+#
+# FIXME/TOOD: don't overwrite name (package rules are applied _before_ reading
+# desc data)
#
LOGGER = logging.getLogger ( 'PackageInfo' )
@@ -97,15 +111,33 @@ class PackageInfo ( object ):
* **initial_info -- passed to update ( **kw )
"""
self._info = dict()
- #self._evars = dict()
self.readonly = False
self._update_lock = threading.RLock()
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)
self.update ( **initial_info )
# --- end of __init__ (...) ---
+ def attach_lazy_action ( self, lazy_action ):
+ """Attaches a lazy action.
+ Unsafe operation (no locks will be acquired etc.).
+
+ arguments:
+ * lazy_action --
+ """
+ raise NotImplementedError ( "method stub" )
+ # --- end of attach_lazy_action (...) ---
+
+ def apply_lazy_actions ( self ):
+ """Tries to apply all attached (lazy) actions.
+ Removes actions that have been applied."""
+ raise NotImplementedError ( "method stub" )
+ # --- end of apply_lazy_actions (...) ---
+
def set_readonly ( self, immediate=False, final=False ):
"""Makes the package info readonly.
@@ -357,6 +389,17 @@ class PackageInfo ( object ):
self._update_lock.release()
# --- end of __setitem__ (...) ---
+ def set_direct_unsafe ( self, key, value ):
+ """Sets an item. This operation is unsafe (no locks will be acquired,
+ write-accessibility won't be checked, data won't be validated).
+
+ arguments:
+ * key --
+ * value --
+ """
+ self._info [key] = value
+ # --- end of set_direct_unsafe (...) ---
+
def update_now ( self, **info ):
"""Updates the package info data with temporarily enabling write access.
Data will be readonly after calling this method.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-06-05 18:08 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-06-13 16:34 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: 6614a65b9d90716e1648529900cc2241981d5dab
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 5 17:58:41 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 5 17:58:41 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6614a65b
packageinfo: add support for lazy actions
This feature is disabled because it's not used and would therefore only add
overhead.
---
roverlay/packageinfo.py | 41 +++++++++++++++++++++++++++++++++++------
1 file changed, 35 insertions(+), 6 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index c7c71eb..5962867 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -45,10 +45,19 @@ from roverlay.rpackage import descriptionreader
# * src_uri -- SRC_URI for a package
# * version -- tuple containing a package's version
#
-
#
-# FIXME/TOOD: don't overwrite name (package rules are applied _before_ reading
-# desc data)
+# Info (keys) that are created before applying package rules:
+#
+# * distdir
+# * origin
+# * package_{file{,name},name}
+# * name (package_name)
+# * src_uri (src_uri_base)
+#
+# "Foreign" info keys (never set or modified here):
+#
+# * category
+# * src_uri_dest
#
LOGGER = logging.getLogger ( 'PackageInfo' )
@@ -116,7 +125,7 @@ class PackageInfo ( object ):
self.overlay_package_ref = None
self.logger = LOGGER
#self._evars = dict()
- #self.lazy_actions = list()
+ #self._lazy_actions = list()
#(or set(), but list preserves order for actions with the same condition)
self.update ( **initial_info )
@@ -129,13 +138,28 @@ class PackageInfo ( object ):
arguments:
* lazy_action --
"""
- raise NotImplementedError ( "method stub" )
+ raise NotImplementedError ( "lazy actions are disabled." )
+ if hasattr ( self, '_lazy_actions' ):
+ self._lazy_actions.append ( lazy_action )
+ else:
+ self._lazy_actions = [ lazy_action ]
# --- end of attach_lazy_action (...) ---
def apply_lazy_actions ( self ):
"""Tries to apply all attached (lazy) actions.
Removes actions that have been applied."""
- raise NotImplementedError ( "method stub" )
+ raise NotImplementedError ( "lazy actions are disabled." )
+ if hasattr ( self, '_lazy_actions' ):
+ retry_later = list()
+ for action in self._lazy_actions:
+ if not action.try_apply_action ( self ):
+ retry_later.append ( action )
+
+ if retry_later:
+ self._lazy_actions = retry_later
+ else:
+ del self._lazy_actions
+ # -- end if;
# --- end of apply_lazy_actions (...) ---
def set_readonly ( self, immediate=False, final=False ):
@@ -529,6 +553,11 @@ class PackageInfo ( object ):
"in _update(): unknown info key {}!".format ( key )
)
# -- end for;
+
+ # FIXME (if needed):
+ # the package rule parser doesn't create lazy actions, currently,
+ # so calling apply_lazy_actions() would do nothing
+ ##self.apply_lazy_actions()
# --- end of _update (...) ---
def _use_filename ( self, _filename ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-06-05 18:08 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-06-13 16:34 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: 7e66abd0a28b088f3a657f483b1ed091b5d9a938
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 5 18:04:02 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 5 18:04:02 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=7e66abd0
roverlay/main: --fixup-category-move[-reverse]
---
roverlay/argutil.py | 30 ++++++++++++++++++++++++++++--
roverlay/main.py | 5 +++++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 689fe78..90d95df 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -88,7 +88,9 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
),
add_help=True,
formatter_class=argparse.RawDescriptionHelpFormatter,
- )
+ )
+
+ incremental_mutex = parser.add_mutually_exclusive_group()
arg = parser.add_argument
opt_in = dict ( default=False, action='store_true' )
@@ -223,6 +225,28 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
action='store_true',
)
+ incremental_mutex.add_argument (
+ '--fixup-category-move',
+ help='''
+ remove packages from the default category
+ if they exist in another one
+ ''',
+ dest='fixup_category_move',
+ default=None,
+ action='store_true'
+ )
+
+ incremental_mutex.add_argument (
+ '--fixup-category-move-reverse',
+ help='''
+ remove packages from other categories if they exist in the
+ default one
+ ''',
+ default=None,
+ dest='fixup_category_move_rev',
+ action='store_true'
+ )
+
arg (
'--stats',
help="print some stats",
@@ -288,7 +312,7 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
# --no-incremental currently means that an existing overlay won't be
# scanned for ebuilds (which means that ebuilds will be recreated),
# but old ebuilds won't be explicitly removed
- arg (
+ incremental_mutex.add_argument (
'--no-incremental',
help="start overlay creation from scratch (ignore an existing overlay)",
dest='incremental',
@@ -365,6 +389,8 @@ def parse_argv ( command_map, **kw ):
incremental = p.incremental,
immediate_ebuild_writes = p.immediate_ebuild_writes,
dump_file = p.dump_file,
+ fixup_category_move = p.fixup_category_move,
+ fixup_category_move_rev = p.fixup_category_move_rev,
)
if given ( 'overlay' ):
diff --git a/roverlay/main.py b/roverlay/main.py
index ab75099..a0ca8e4 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -272,6 +272,11 @@ def main (
overlay_creator.release_package_rules()
+ if OPTION ( 'fixup_category_move' ):
+ overlay_creator.remove_moved_ebuilds ( reverse=False )
+ elif OPTION ( 'fixup_category_move_rev' ):
+ overlay_creator.remove_moved_ebuilds ( reverse=True )
+
overlay_creator.run ( close_when_done=True )
optionally ( overlay_creator.write_overlay, 'write_overlay' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-06-19 18:58 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-06-19 18:59 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-19 18:59 UTC (permalink / raw
To: gentoo-commits
commit: ce623a4736308104f0c11e27c2e94feeda7bbb26
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 19 18:43:33 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 19 18:43:33 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ce623a47
roverlay/digest: support sha* and multihash mode
This commit adds support for sha1/sha256/sha512 (via hashlib) and whirlpool (via
portage.util).
It also adds the mulihash[_file]() function(s) that create more than one digest
at once.
---
roverlay/digest.py | 89 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 82 insertions(+), 7 deletions(-)
diff --git a/roverlay/digest.py b/roverlay/digest.py
index 218f98c..983ca1a 100644
--- a/roverlay/digest.py
+++ b/roverlay/digest.py
@@ -11,23 +11,98 @@ __all__ = [ 'digest_compare', 'digest_supported',
]
import hashlib
+import portage.util.whirlpool
-def md5sum_file ( fh, binary_digest=False ):
- """Returns the md5 sum for an already opened file."""
- md5 = hashlib.md5()
- blocksize = 16384
+_HASH_CREATE_MAP = {
+ 'md5' : hashlib.md5,
+ 'sha1' : hashlib.sha1,
+ 'sha256' : hashlib.sha256,
+ 'sha512' : hashlib.sha512,
+ 'whirlpool' : portage.util.whirlpool.new,
+}
+def _generic_obj_hash ( hashobj, fh, binary_digest=False, blocksize=16384 ):
block = fh.read ( blocksize )
while block:
- md5.update ( block )
+ hashobj.update ( block )
block = fh.read ( blocksize )
- return md5.digest() if binary_digest else md5.hexdigest()
+ return hashobj.digest() if binary_digest else hashobj.hexdigest()
+# --- end of _hashsum_generic (...) ---
+
+def multihash ( fh, hashlist, binary_digest=False, blocksize=16384 ):
+ """Calculates multiple digests for an already openened file and returns the
+ resulting hashes as dict.
+
+ arguments:
+ * fh -- file handle
+ * hashlist -- iterable with hash names (e.g. md5)
+ * binary_digest -- whether the hashes should be binary or not
+ * blocksize -- block size for reading
+ """
+ hashobj_dict = {
+ h: _HASH_CREATE_MAP[h]() for h in hashlist
+ }
+ block = fh.read ( blocksize )
+ while block:
+ for hashobj in hashobj_dict.values():
+ hashobj.update ( block )
+ block = fh.read ( blocksize )
+
+ if binary_digest:
+ return { h: hashobj.digest() for h, hashobj in hashobj_dict.items() }
+ else:
+ return { h: hashobj.hexdigest() for h, hashobj in hashobj_dict.items() }
+# --- end of multihash (...) ---
+
+def multihash_file ( filepath, digest_types, **kwargs ):
+ """Calculates multiple digests for the given file path.
+
+ Returns an empty dict if digest_types is empty.
+
+ arguments:
+ * filepath --
+ * digest_types --
+ * **kwargs -- passed to multihash()
+ """
+ if digest_types:
+ with open ( filepath, mode='rb' ) as fh:
+ hashdict = multihash ( fh, digest_types, **kwargs )
+ return hashdict
+ else:
+ return dict()
+# --- end of multihash_file (...) ---
+
+def md5sum_file ( fh, binary_digest=False ):
+ """Returns the md5 sum for an already opened file."""
+ return _generic_obj_hash ( hashlib.md5(), fh, binary_digest )
# --- end of md5sum_file (...) ---
+def sha1_file ( fh, binary_digest=False ):
+ return _generic_obj_hash ( hashlib.sha1(), fh, binary_digest )
+# --- end of sha1_file (...) ---
+
+def sha256_file ( fh, binary_digest=False ):
+ return _generic_obj_hash ( hashlib.sha256(), fh, binary_digest )
+# --- end of sha256_file (...) ---
+
+def sha512_file ( fh, binary_digest=False ):
+ return _generic_obj_hash ( hashlib.sha512(), fh, binary_digest )
+# --- end of sha512_file (...) ---
+
+def whirlpool_file ( fh, binary_digest=False ):
+ return _generic_obj_hash (
+ portage.util.whirlpool.new(), fh, binary_digest
+ )
+# --- end of whirlpool_file (...) ---
+# TODO: remove
_DIGEST_MAP = dict (
- md5 = md5sum_file,
+ md5 = md5sum_file,
+ sha1 = sha1_file,
+ sha256 = sha256_file,
+ sha512 = sha512_file,
+ whirlpool = whirlpool_file,
)
def digest_supported ( digest_type ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-06-19 18:58 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-06-22 15:24 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
To: gentoo-commits
commit: daf73b9acc9191382332ef2e4582e906db9ad435
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 19 18:51:35 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 19 18:51:35 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=daf73b9a
packageinfo: create distmap data, make hashes
---
roverlay/packageinfo.py | 43 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 90b4250..e8004d0 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -18,6 +18,8 @@ import os.path
import logging
import threading
+import roverlay.digest
+
from roverlay import config, strutil
from roverlay.rpackage import descriptionreader
@@ -123,7 +125,7 @@ class PackageInfo ( object ):
self._info = dict()
self.readonly = False
self._update_lock = threading.RLock()
- self.overlay_package_ref = None
+ #self.overlay_package_ref = None
self.logger = LOGGER
#self._evars = dict()
#self._lazy_actions = list()
@@ -373,9 +375,7 @@ class PackageInfo ( object ):
elif key_low == 'package_src_destpath':
# src file path relative to distroot (mirror root dir)
destpath = self._info.get ('src_uri_dest', None )
- return (
- destpath or os.path.basename ( self._info ['package_filename'] )
- )
+ return ( destpath or self._info ['package_filename'] )
# end if <key matches ...>
@@ -450,6 +450,41 @@ class PackageInfo ( object ):
return self._info ['desc_data']
# --- end of get_desc_data (...) ---
+ def get_distmap_item ( self ):
+ return ( self.get_distmap_key(), self.get_distmap_value() )
+ # --- end of get_distmap_item (...) ---
+
+ def get_distmap_key ( self ):
+ return self.get ( "package_src_destpath" )
+ # --- end of get_distmap_key (...) ---
+
+ def get_distmap_value ( self ):
+ assert 'sha256' in self.hashdict
+
+ repo = self.get ( "origin" )
+ return (
+ repo.name,
+ os.path.relpath ( self.get ( "package_file" ), repo.distdir ),
+ self.hashdict ['sha256']
+ )
+ # --- end of get_distmap_value (...) ---
+
+ def make_hashes ( self, hashlist ):
+ pkgfile = self.get ( "package_file" )
+
+ if hasattr ( self, 'hashdict' ) and self.hashdict:
+ new_hashes = (
+ frozenset ( hashlist ) - frozenset ( self.hashdict.keys() )
+ )
+
+ if new_hashes:
+ self.hashdict.update (
+ roverlay.digest.multihash_file ( pkgfile, new_hashes )
+ )
+ else:
+ self.hashdict = roverlay.digest.multihash_file ( pkgfile, hashlist )
+ # --- end of make_hashes (...) ---
+
def __getitem__ ( self, key ):
"""Returns an item."""
return self.get ( key, do_fallback=False )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-22 15:24 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
To: gentoo-commits
commit: ddc3781f3fe2df940306c14a0ee2779a07454cb4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 20 23:27:41 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 20 23:27:41 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ddc3781f
roverlay/digest: fixup
---
roverlay/digest.py | 86 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 54 insertions(+), 32 deletions(-)
diff --git a/roverlay/digest.py b/roverlay/digest.py
index 983ca1a..a031889 100644
--- a/roverlay/digest.py
+++ b/roverlay/digest.py
@@ -6,13 +6,19 @@
"""provides digest related utility functions (e.g. md5sum_file())"""
-__all__ = [ 'digest_compare', 'digest_supported',
- 'dodigest_file', 'md5sum_file'
+__all__ = [
+ 'digest_compare', 'digest_comparator',
+ 'digest_supported', 'dodigest_file',
+ 'multihash', 'multihash_file',
+ 'md5sum_file', 'sha1_file', 'sha256_file', 'sha512_file',
+ 'whirlpool_file',
]
import hashlib
import portage.util.whirlpool
+DEFAULT_BLOCKSIZE=16384
+
_HASH_CREATE_MAP = {
'md5' : hashlib.md5,
'sha1' : hashlib.sha1,
@@ -21,7 +27,10 @@ _HASH_CREATE_MAP = {
'whirlpool' : portage.util.whirlpool.new,
}
-def _generic_obj_hash ( hashobj, fh, binary_digest=False, blocksize=16384 ):
+
+def _generic_obj_hash (
+ hashobj, fh, binary_digest=False, blocksize=DEFAULT_BLOCKSIZE
+):
block = fh.read ( blocksize )
while block:
hashobj.update ( block )
@@ -30,7 +39,17 @@ def _generic_obj_hash ( hashobj, fh, binary_digest=False, blocksize=16384 ):
return hashobj.digest() if binary_digest else hashobj.hexdigest()
# --- end of _hashsum_generic (...) ---
-def multihash ( fh, hashlist, binary_digest=False, blocksize=16384 ):
+def _generic_file_obj_hash (
+ hashobj, filepath, binary_digest=False, blocksize=DEFAULT_BLOCKSIZE
+):
+ with open ( filepath, 'rb' ) as fh:
+ ret = _generic_obj_hash ( hashobj, fh, binary_digest, blocksize )
+ return ret
+# --- end of _generic_file_obj_hash (...) ---
+
+def multihash (
+ fh, hashlist, binary_digest=False, blocksize=DEFAULT_BLOCKSIZE
+):
"""Calculates multiple digests for an already openened file and returns the
resulting hashes as dict.
@@ -73,50 +92,53 @@ def multihash_file ( filepath, digest_types, **kwargs ):
return dict()
# --- end of multihash_file (...) ---
-def md5sum_file ( fh, binary_digest=False ):
- """Returns the md5 sum for an already opened file."""
- return _generic_obj_hash ( hashlib.md5(), fh, binary_digest )
+def md5sum_file ( filepath, **kw ):
+ """Returns the md5 sum for a file."""
+ return _generic_file_obj_hash ( hashlib.md5(), filepath, **kw )
# --- end of md5sum_file (...) ---
-def sha1_file ( fh, binary_digest=False ):
- return _generic_obj_hash ( hashlib.sha1(), fh, binary_digest )
+def sha1_file ( filepath, **kw ):
+ return _generic_obj_hash ( hashlib.sha1(), filepath, **kw )
# --- end of sha1_file (...) ---
-def sha256_file ( fh, binary_digest=False ):
- return _generic_obj_hash ( hashlib.sha256(), fh, binary_digest )
+def sha256_file ( filepath, **kw ):
+ return _generic_obj_hash ( hashlib.sha256(), filepath, **kw )
# --- end of sha256_file (...) ---
-def sha512_file ( fh, binary_digest=False ):
- return _generic_obj_hash ( hashlib.sha512(), fh, binary_digest )
+def sha512_file ( filepath, **kw ):
+ return _generic_obj_hash ( hashlib.sha512(), filepath, **kw )
# --- end of sha512_file (...) ---
-def whirlpool_file ( fh, binary_digest=False ):
+def whirlpool_file ( filepath, **kw ):
return _generic_obj_hash (
- portage.util.whirlpool.new(), fh, binary_digest
+ portage.util.whirlpool.new(), filepath, **kw
)
# --- end of whirlpool_file (...) ---
-# TODO: remove
-_DIGEST_MAP = dict (
- md5 = md5sum_file,
- sha1 = sha1_file,
- sha256 = sha256_file,
- sha512 = sha512_file,
- whirlpool = whirlpool_file,
-)
-
def digest_supported ( digest_type ):
"""Returns True if the given digest type is supported, else False."""
- return digest_type in _DIGEST_MAP
+ return digest_type in _HASH_CREATE_MAP
# --- digest_supported (...) ---
-def dodigest_file ( _file, digest_type, binary_digest=False ):
- ret = None
- with open ( _file, mode='rb' ) as fh:
- ret = _DIGEST_MAP [digest_type] ( fh, binary_digest=binary_digest )
- return ret
+def dodigest_file ( _file, digest_type, **kwargs ):
+ return _generic_file_obj_hash (
+ hashobj = _HASH_CREATE_MAP [digest_type](),
+ filepath = _file,
+ **kwargs
+ )
# --- end of dodigest_file (...) ---
-def digest_compare ( _file, digest, digest_type, binary_digest=False ):
- return digest == dodigest_file ( _file, digest_type, binary_digest )
+def digest_compare ( digest, digest_type, filepath, **kwargs ):
+ return digest == dodigest_file ( filepath, digest_type, **kwargs )
# --- end of digest_compare (...) ---
+
+# digest_comparator :: digest_type -> digest -> ( filepath, ... ) -> bool
+digest_comparator = (
+ lambda digest_type : (
+ lambda digest : (
+ lambda filepath, *args, **kwargs : digest_compare (
+ digest, digest_type, *args, **kwargs
+ )
+ )
+ )
+)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-22 15:24 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
To: gentoo-commits
commit: 7a98234f8f14a864be8a1ba2ebb8e45d202a9c00
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 20 23:38:38 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 20 23:38:38 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=7a98234f
roverlay/main: run hook after overlay creation
---
roverlay/main.py | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/roverlay/main.py b/roverlay/main.py
index a0ca8e4..207bea6 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -81,6 +81,34 @@ def main (
return call ( *args, **kw )
# --- end of optionally (...) ---
+ def run_hook ( hook_key, phase ):
+ print ( "RUN_HOOK?", hook_key, phase )
+ script = roverlay.config.get ( hook_key, None )
+ if script:
+ print ( "YES.", str ( script ) )
+ return roverlay.tools.shenv.run_script (
+ script, phase.lower(), return_success=True
+ )
+ else:
+ print ( "NO." )
+ # nop
+ return True
+ # --- end of run_hook (...) ---
+
+ def run_hook_lazy ( phase ):
+ crelpath, sepa, ckey = phase.rpartition ( '_' )
+ if sepa:
+ # HOOK.~phase
+ cpath = (
+ 'HOOK.' + crelpath.replace ( '_', '.' ).upper()
+ + '.' + ckey.lower()
+ )
+
+ return run_hook ( cpath, phase )
+ else:
+ raise Exception ( "cannot parse phase {!r}".format ( phase ) )
+ # --- end of run_hook_lazy (...) ---
+
def run_sync():
if "sync" in actions_done: return
try:
@@ -284,6 +312,14 @@ def main (
if OPTION ( 'print_stats' ):
print ( "\n" + overlay_creator.stats_str() )
+
+ # FIXME/TODO:
+ # this hook should be called _after_ verifying the overlay
+ # (verification is not implemented yet)
+ #
+ if not run_hook_lazy ( 'overlay_success' ):
+ die ( "overlay_success hook returned non-zero", DIE.OV_CREATE )
+
set_action_done ( "create" )
except KeyboardInterrupt:
@@ -466,6 +502,9 @@ def main (
try:
from roverlay.remote import RepoList
from roverlay.overlay.creator import OverlayCreator
+
+ import roverlay.config
+ import roverlay.tools.shenv
except ImportError:
if HIDE_EXCEPTIONS:
die ( "Cannot import roverlay modules!", DIE.IMPORT )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-22 15:24 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
To: gentoo-commits
commit: 305933fc8ce3375745927cfda5fca824eb67f004
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Jun 22 10:31:24 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Jun 22 10:31:24 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=305933fc
roverlay/packageinfo: support revbumps
---
roverlay/packageinfo.py | 91 ++++++++++++++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 35 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 83a05ed..b75eb8c 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -16,6 +16,8 @@ __all__ = [ 'PackageInfo', ]
import re
import os.path
import logging
+# TODO: remove threading/locks here, exclusive access to PackageInfo instances
+# should be guaranteed
import threading
import roverlay.digest
@@ -320,10 +322,6 @@ class PackageInfo ( object ):
return self._info [key_low]
# 'virtual' keys - calculate result
- elif key_low == 'name':
- # no special name, using package_name
- return self._info ['package_name']
-
elif key_low == 'package_file':
distdir = self.get ( 'distdir', do_fallback=True )
if distdir:
@@ -443,14 +441,14 @@ class PackageInfo ( object ):
"""Returns the DESCRIPTION data for this PackageInfo (by reading the
R package file if necessary).
"""
- if 'desc_data' in self._info:
- return self._info ['desc_data']
-
- self._writelock_acquire()
if 'desc_data' not in self._info:
- self._info ['desc_data'] = descriptionreader.read ( self )
+ self._writelock_acquire()
+ if 'desc_data' not in self._info:
+ self._info ['desc_data'] = descriptionreader.read ( self )
+
+ self._update_lock.release()
+ # -- end if;
- self._update_lock.release()
return self._info ['desc_data']
# --- end of get_desc_data (...) ---
@@ -518,12 +516,14 @@ class PackageInfo ( object ):
arguments:
* newrev -- new revision, (current rev + 1) is used if this is None
"""
- raise NotImplementedError ( "revbump code" )
if newrev is None:
# get old rev and increment it
- pass
+ ## direct dict access
+ self._info ['rev'] += 1
else:
- pass
+ self._info ['rev'] = int ( newrev )
+
+ self._reset_version_str()
return self
# --- end of revbump (...) ---
@@ -635,6 +635,19 @@ class PackageInfo ( object ):
return None
# --- end of get_evars (...) ---
+ def _reset_version_str ( self ):
+ rev = self ['rev']
+ version = self ['version']
+
+ if rev > 0:
+ vstr = '.'.join ( str ( k ) for k in version ) + '-r' + str ( rev )
+ else:
+ vstr = '.'.join ( str ( k ) for k in version )
+
+ self._info ['ebuild_verstr'] = vstr
+ #return vstr
+ # --- end of _reset_version_str (...) ---
+
def _update ( self, info ):
"""Updates self._info using the given info dict.
@@ -645,15 +658,14 @@ class PackageInfo ( object ):
for key, value in info.items():
- if key in self.__class__._UPDATE_KEYS_SIMPLE:
- self [key] = value
-
- elif initial and key in self.__class__._UPDATE_KEYS_SIMPLE_INITIAL:
- self [key] = value
+ if key in self.__class__._UPDATE_KEYS_SIMPLE or (
+ initial and key in self.__class__._UPDATE_KEYS_SIMPLE_INITIAL
+ ):
+ self._info [key] = value
elif key in self.__class__._UPDATE_KEYS_FILTER_NONE:
if value is not None:
- self [key] = value
+ self._info [key] = value
elif key == 'filename':
self._use_filename ( value )
@@ -662,10 +674,10 @@ class PackageInfo ( object ):
self._use_pvr ( value )
elif key == 'suggests':
- self ['has_suggests'] = value
+ self._info ['has_suggests'] = value
elif key == 'depres_result':
- self ['has_suggests'] = value [2]
+ self._info ['has_suggests'] = value [2]
elif key == 'filepath':
self._use_filepath ( value )
@@ -720,7 +732,7 @@ class PackageInfo ( object ):
try:
version = tuple ( int ( z ) for z in version_str.split ( '.' ) )
- self ['version'] = version
+ self._info ['version'] = version
except ValueError as ve:
# version string is malformed, cannot use it
self.logger.error (
@@ -736,24 +748,33 @@ class PackageInfo ( object ):
# removing illegal chars from the package_name
ebuild_name = strutil.fix_ebuild_name ( package_name )
- if ebuild_name != package_name:
- self ['name'] = ebuild_name
-
- self ['ebuild_verstr'] = version_str
-
# for DescriptionReader
- self ['package_name'] = package_name
+ self._info ['package_name'] = package_name
- self ['package_filename'] = filename_with_ext
+ self._info ['rev'] = 0
+ self._info ['name'] = ebuild_name
+ self._info ['ebuild_verstr'] = version_str
+ self._info ['package_filename'] = filename_with_ext
# --- end of _use_filename (...) ---
def _use_pvr ( self, pvr ):
- # 0.1_pre2-r17 -> ( 0, 1 )
- pv = pvr.partition ( '-' ) [0]
- self ['version'] = tuple (
- int ( z ) for z in ( pv.partition ( '_' ) [0].split ( '.' ) )
- )
- self ['ebuild_verstr'] = pvr
+ # 0.1_pre2-r17 -> ( ( 0, 1 ), ( 17 ) )
+ pv_str, DONT_CARE, pr_str = pvr.partition ( '-r' )
+ pv, DONT_CARE, pv_suffix = pv_str.partition ( '_' )
+
+ if pv_suffix:
+ # not supported
+ raise NotImplementedError (
+ "version suffix {!r} cannot be preserved for $PVR {!r}".format (
+ pv_suffix, pvr
+ )
+ )
+ # non-digit chars in pv are unsupported, too
+
+ self._info ['version'] = tuple ( int ( z ) for z in pv.split ( '.' ) )
+ self._info ['rev'] = int ( pr_str ) if pr_str else 0
+
+ self._info ['ebuild_verstr'] = pvr
# --- end of _use_pvr (...) ---
def _remove_auto ( self, ebuild_status ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-06-22 15:24 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
To: gentoo-commits
commit: 5374a6066d9f8615243bba9b0a2d0c5be487f653
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Jun 22 15:03:05 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Jun 22 15:03:05 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5374a606
roverlay/packageinfo, revbump: set src_uri_dest
Rename distfiles of rev-bumped ebuilds.
---
roverlay/packageinfo.py | 48 ++++++++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 7b74425..b86d69d 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -94,6 +94,7 @@ class PackageInfo ( object ):
PKGSUFFIX_REGEX = re.compile (
config.get_or_fail ( 'R_PACKAGE.suffix_regex' ) + '$'
)
+ EBUILDREV_REGEX = re.compile ( '[-]r[0-9]+$' )
ALWAYS_FALLBACK = frozenset ( ( 'ebuild', 'ebuild_file' ) )
_UPDATE_KEYS_SIMPLE = frozenset ((
@@ -505,19 +506,36 @@ class PackageInfo ( object ):
def revbump ( self, newrev=None ):
"""Do whatever necessary to revbump this pakages, that is set/update
- all data like src_uri_destfile.
+ all data like src_uri_dest and ebuild_verstr.
arguments:
* newrev -- new revision, (current rev + 1) is used if this is None
"""
- if newrev is None:
- # get old rev and increment it
- ## direct dict access
- self._info ['rev'] += 1
- else:
- self._info ['rev'] = int ( newrev )
+ rev = self._info['rev'] + 1 if newrev is None else int ( newrev )
+ rev_str = ( '-r' + str ( rev ) ) if rev > 0 else ''
+ vstr = '.'.join ( str ( k ) for k in self ['version'] ) + rev_str
+
+ # preserve destpath directory
+ # (this allows to handle paths like "a/b.tar/pkg.tgz" properly)
+ #
+ old_destpath = self ['package_src_destpath'].rpartition ( os.path.sep )
+
+ # os.path.splitext does not "recognize" .tar.gz
+ fhead, ftar, fext = old_destpath[2].rpartition ( '.tar' )
+ if not ftar:
+ fhead, fext = os.path.splitext ( fext )
+
+ # FIXME: any way to get this reliably (+faster) done without a regex?
+ # ( a,b,c=fhead.rpartition ( '-r' ); try int(c) ...; ?)
+ distfile = (
+ old_destpath[0] + old_destpath[1]
+ + self.EBUILDREV_REGEX.sub ( '', fhead ) + rev_str + ftar + fext
+ )
+
+ self._info ['rev'] = rev
+ self._info ['ebuild_verstr'] = vstr
+ self._info ['src_uri_dest'] = distfile
- self._reset_version_str()
return self
# --- end of revbump (...) ---
@@ -620,20 +638,6 @@ class PackageInfo ( object ):
return None
# --- end of get_evars (...) ---
- def _reset_version_str ( self ):
- """Recreates the version_str ($PVR) of this PackageInfo instance."""
- rev = self ['rev']
- version = self ['version']
-
- if rev > 0:
- vstr = '.'.join ( str ( k ) for k in version ) + '-r' + str ( rev )
- else:
- vstr = '.'.join ( str ( k ) for k in version )
-
- self._info ['ebuild_verstr'] = vstr
- #return vstr
- # --- end of _reset_version_str (...) ---
-
def _update ( self, info ):
"""Updates self._info using the given info dict.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-12 13:57 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-12 13:57 UTC (permalink / raw
To: gentoo-commits
commit: 55b83ffd569c0c3ce9ae46e6198805873864e8a4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 12 13:47:45 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 12 13:47:45 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=55b83ffd
roverlay, setupdirs command: dont load field def
---
roverlay/__init__.py | 27 ++++++++++++++++-----------
roverlay/main.py | 2 ++
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 175f2d1..f660a4a 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -30,17 +30,21 @@ def setup_initial_logger():
"""Sets up initial logging."""
roverlay.recipe.easylogger.setup_initial()
-def load_config_file ( cfile, extraconf=None, setup_logger=True ):
+def load_config_file (
+ cfile, extraconf=None, setup_logger=True, load_main_only=False
+):
"""
Loads the config, including the field definition file.
Sets up the logger afterwards.
(Don't call this method more than once.)
arguments:
- * cfile -- path to the config file
- * extraconf -- a dict with additional config entries that will override
- entries read from cfile
- * setup_logger -- set up logger (defaults to True)
+ * cfile -- path to the config file
+ * extraconf -- a dict with additional config entries that will override
+ entries read from cfile
+ * setup_logger -- set up logger (defaults to True)
+ * load_main_only -- if set and True: load main config file only
+ (= do not load field def, ...)
"""
roverlay_config = roverlay.config.access()
@@ -55,12 +59,13 @@ def load_config_file ( cfile, extraconf=None, setup_logger=True ):
if setup_logger:
roverlay.recipe.easylogger.setup ( roverlay_config )
- confloader.load_field_definition (
- roverlay_config.get_or_fail ( "DESCRIPTION.field_definition_file" )
- )
+ if not load_main_only:
+ confloader.load_field_definition (
+ roverlay_config.get_or_fail ( "DESCRIPTION.field_definition_file" )
+ )
- confloader.load_use_expand_map (
- roverlay_config.get ( "EBUILD.USE_EXPAND.rename_file" )
- )
+ confloader.load_use_expand_map (
+ roverlay_config.get ( "EBUILD.USE_EXPAND.rename_file" )
+ )
return roverlay_config
diff --git a/roverlay/main.py b/roverlay/main.py
index 75d1e2f..0fec74d 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -101,6 +101,7 @@ def run_setupdirs ( config, target_uid, target_gid ):
os.path.dirname ( value.rstrip ( os.sep ) )
if dirmask & WANT_FILEDIR else value.rstrip ( os.sep )
)
+
if dirpath:
dodir ( dirpath )
if dirmask & WANT_PRIVATE:
@@ -459,6 +460,7 @@ def main (
config_file,
extraconf=additional_config,
setup_logger=want_logging,
+ load_main_only=do_setupdirs,
)
del config_file, additional_config
except:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-07-15 22:31 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-07-16 16:36 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-16 16:36 UTC (permalink / raw
To: gentoo-commits
commit: 6e32f77915e8bf388059f79750a5a30bf8d2fb49
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 15 22:29:05 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 15 22:29:05 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6e32f779
--run-script: respect EvENT_HOOK_RESTRICT
---
roverlay/hook.py | 4 ++--
roverlay/main.py | 25 +++++++++++++++----------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/roverlay/hook.py b/roverlay/hook.py
index e56aa33..262d3c2 100644
--- a/roverlay/hook.py
+++ b/roverlay/hook.py
@@ -32,12 +32,12 @@ _EVENT_POLICY = 0
class HookException ( Exception ):
pass
-def setup():
+def setup ( force=False ):
global _EVENT_SCRIPT
global _EVENT_POLICY
global _EVENT_RESTRICT
- if roverlay.config.get ( 'write_disabled', False ):
+ if roverlay.config.get ( 'write_disabled', False ) and not force:
_EVENT_SCRIPT = False
return
diff --git a/roverlay/main.py b/roverlay/main.py
index 24c02c6..7a88171 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -497,16 +497,21 @@ def main (
if do_runscript:
import roverlay.tools.shenv
- sys.exit (
- roverlay.tools.shenv.run_script (
- script = extra_opts ['run_script'],
- phase = "user",
- argv = extra_opts ['run_script_args'],
- return_success = False,
- log_output = False,
- initial_dir = os.getcwd(),
- ).returncode
- )
+ import roverlay.hook
+ roverlay.hook.setup ( force=True )
+ if roverlay.hook.phase_allowed ( "user" ):
+ sys.exit (
+ roverlay.tools.shenv.run_script (
+ script = extra_opts ['run_script'],
+ phase = "user",
+ argv = extra_opts ['run_script_args'],
+ return_success = False,
+ log_output = False,
+ initial_dir = os.getcwd(),
+ ).returncode
+ )
+ else:
+ die ( "--run-script: 'user' phase is not allowed." )
elif do_setupdirs:
sys.exit ( run_setupdirs (
conf, extra_opts['target_uid'], extra_opts['target_gid']
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-07-17 18:05 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-07-17 18:05 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-17 18:05 UTC (permalink / raw
To: gentoo-commits
commit: a01c5b354610331bdd684aa3632a1f692a44d6cb
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jul 17 17:58:11 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jul 17 18:00:00 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a01c5b35
fix versiontuple (again)
The le/lt/ge/gt comparision functions were completely wrong, which caused
selfdep validation to misbehave. Checking "(0,97) <= (1,1,2)" always returned
False (but 0 < 1!), whereas "(1,1,2) >= (0,97)" returned False, too (which is
be correct, but "neither less nor greater nor equal" makes no sense at all).
In a second (incremental) run, all comparisions would then evaluate to true,
because PackageInfo created normal tuples for scanned ebuilds, for which
IntVersionTuple returns NotImplemented (when comparing).
And bool( NotImplemented ) <=> True,
so even IntVersionTuple(1,1) was "less than" tuple(0,0).
This commit fixes this issue.
---
roverlay/packageinfo.py | 9 +++++----
roverlay/versiontuple.py | 52 +++++++++++++++++++++++++++++++++++++-----------
2 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 0224d6c..feee360 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -108,7 +108,7 @@ class PackageInfo ( object ):
'has_suggests',
))
_UPDATE_KEYS_SIMPLE_INITIAL = frozenset ((
- 'package_filename',
+ 'package_filename', 'name',
))
_UPDATE_KEYS_FILTER_NONE = frozenset ((
'src_uri_base',
@@ -810,9 +810,10 @@ class PackageInfo ( object ):
)
)
# non-digit chars in pv are unsupported, too
-
- self._info ['version'] = tuple ( int ( z ) for z in pv.split ( '.' ) )
- self._info ['rev'] = int ( pr_str ) if pr_str else 0
+ self._info ['version'] = roverlay.versiontuple.IntVersionTuple (
+ int ( z ) for z in pv.split ( '.' )
+ )
+ self._info ['rev'] = int ( pr_str ) if pr_str else 0
self._info ['ebuild_verstr'] = pvr
# --- end of _use_pvr (...) ---
diff --git a/roverlay/versiontuple.py b/roverlay/versiontuple.py
index 0ca902a..20d5cf8 100644
--- a/roverlay/versiontuple.py
+++ b/roverlay/versiontuple.py
@@ -166,36 +166,64 @@ class IntVersionTuple ( VersionTuple ):
def __le__ ( self, other ):
if isinstance ( other, self.__class__ ):
- return all ( a <= b
- for a, b in _zip_longest ( self, other, fillvalue=0 )
- )
+ #
+ # ( k0, k1, ..., kN ) x ( l0, l1, ..., lN )
+ #
+ # from left to right (high to low)
+ # if k_j < l_j
+ # return True (k <= j)
+ # elif k_j == l_j
+ # continue with next
+ # else
+ # return False (k > j)
+ #
+ # return True if last pair was equal
+ for a, b in _zip_longest ( self, other, fillvalue=0 ):
+ if a < b:
+ return True
+ elif a > b:
+ return False
+ else:
+ return True
else:
return NotImplemented
# --- end of __le__ (...) ---
def __ge__ ( self, other ):
if isinstance ( other, self.__class__ ):
- return all ( a >= b
- for a, b in _zip_longest ( self, other, fillvalue=0 )
- )
+ for a, b in _zip_longest ( self, other, fillvalue=0 ):
+ if a > b:
+ return True
+ elif a < b:
+ return False
+ else:
+ return True
else:
return NotImplemented
# --- end of __ge__ (...) ---
def __lt__ ( self, other ):
if isinstance ( other, self.__class__ ):
- return all ( a < b
- for a, b in _zip_longest ( self, other, fillvalue=0 )
- )
+ for a, b in _zip_longest ( self, other, fillvalue=0 ):
+ if a < b:
+ return True
+ elif a > b:
+ return False
+ else:
+ return False
else:
return NotImplemented
# --- end of __lt__ (...) ---
def __gt__ ( self, other ):
if isinstance ( other, self.__class__ ):
- return all ( a > b
- for a, b in _zip_longest ( self, other, fillvalue=0 )
- )
+ for a, b in _zip_longest ( self, other, fillvalue=0 ):
+ if a > b:
+ return True
+ elif a < b:
+ return False
+ else:
+ return False
else:
return NotImplemented
# --- end of __gt__ (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-23 7:51 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-23 7:51 UTC (permalink / raw
To: gentoo-commits
commit: 09b615d1352bab7662426b3b5c64bb60ae4e4a7b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 19 17:45:47 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 19 17:45:47 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=09b615d1
roverlay/strutil: unquote_all()
---
roverlay/strutil.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index b4e2631..755a191 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -108,7 +108,7 @@ def pipe_lines ( _pipe, use_filter=False, filter_func=None ):
return lines
# --- end of pipe_lines (...) ---
-def unquote ( _str, keep_going=False):
+def unquote ( _str, keep_going=False ):
"""Removes enclosing quotes from a string.
arguments:
@@ -124,6 +124,10 @@ def unquote ( _str, keep_going=False):
return _str
# --- end of unquote (...) ---
+def unquote_all ( s ):
+ return unquote ( s, keep_going=True )
+# --- end of unquote_all (...) ---
+
def bytes_try_decode (
byte_str,
encodings=_DEFAULT_ENCODINGS,
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-23 7:51 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-23 7:51 UTC (permalink / raw
To: gentoo-commits
commit: 80a5617c256f0c650221849a5f0c0d39b3cb2686
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 22 12:08:45 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 22 12:08:45 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=80a5617c
roverlay/argutil: remove --run-script entirely
---
roverlay/argutil.py | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index df40d34..449b359 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -6,8 +6,6 @@
"""provides arg parsing for the roverlay main script"""
-# TODO: remove --run-script here
-
__all__ = [ 'parse_argv', ]
import os
@@ -409,18 +407,6 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
type=is_gid,
)
- arg (
- '--run-script', '-X', default=argparse.SUPPRESS,
- metavar="<script>",
- help="run a script in roverlay\'s environment and exit afterwards",
- type=is_fs_file,
- )
-
- arg (
- '--script-args', dest='run_script_args', default=argparse.SUPPRESS,
- metavar="<args>",
- help="args for --run-script",
- )
# # TODO
# arg (
@@ -496,12 +482,6 @@ def parse_argv ( command_map, **kw ):
target_gid = p.target_gid,
)
- if given ( 'run_script' ):
- extra ['run_script'] = p.run_script
- extra ['run_script_args'] = tuple (
- getattr ( p, 'run_script_args', "" ).split ( None )
- )
- # or use shlex for splitting
if given ( 'overlay' ):
doconf ( p.overlay, 'OVERLAY.dir' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
2013-07-19 18:00 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-07-23 7:51 ` André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-23 7:51 UTC (permalink / raw
To: gentoo-commits
commit: 545daa132cf9ea6e52e925c57b3a3718e2916ad1
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 19 18:00:12 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 19 18:00:12 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=545daa13
roverlay/main: use new depres console
---
roverlay/main.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/roverlay/main.py b/roverlay/main.py
index 31a5ea0..b97b5cd 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -579,10 +579,15 @@ def main (
die ( "depres_console cannot be run with other commands!", DIE.USAGE )
try:
- from roverlay.depres.simpledeprule.console import DepResConsole
- con = DepResConsole()
- con.run()
- set_action_done ( "depres_console" )
+ from roverlay.console.depres import DepresConsole
+ con = DepresConsole()
+ con.setup ( config=conf )
+ try:
+ con.run_forever()
+ set_action_done ( "depres_console" )
+ finally:
+ con.close()
+
except ImportError:
if HIDE_EXCEPTIONS:
die ( "Cannot import depres console!", DIE.IMPORT )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-26 13:02 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-26 13:02 UTC (permalink / raw
To: gentoo-commits
commit: 638280bfa2dd4a10c99a8c6a3deac8ef9ba63ef4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 26 13:00:19 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 26 13:00:19 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=638280bf
roverlay/main: use/show new stats
temporary change
* stats need to be persistent (write them to file/db)
* stats need proper str() 'visualization'
---
roverlay/main.py | 39 +++++++++++++++++----------------------
1 file changed, 17 insertions(+), 22 deletions(-)
diff --git a/roverlay/main.py b/roverlay/main.py
index b97b5cd..cc3a5ab 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -10,10 +10,10 @@ __all__ = [ 'main' ]
import os
import sys
-import time
import roverlay
import roverlay.tools.shenv
+import roverlay.stats.collector
# roverlay modules will be imported later
@@ -214,22 +214,17 @@ def main (
repo_list.load()
## this runs _nosync() or _sync(), depending on extra_opts->nosync
- t_start = time.time()
repo_list.sync()
- global sync_time
- sync_time = time.time() - t_start
-
set_action_done ( "sync" )
except KeyboardInterrupt:
die ( "Interrupted", DIE.INTERRUPT )
except:
if HIDE_EXCEPTIONS:
- die (
- "nosync() failed!" if OPTION ( "nosync" ) \
- else "sync() failed!",
- DIE.SYNC
- )
+ die (
+ ( "no" if OPTION ( "nosync" ) else "" ) + "sync() failed!",
+ DIE.SYNC
+ )
else:
raise
# --- end of run_sync() ---
@@ -338,20 +333,18 @@ def main (
FH_SHARED = False
FH = open ( dump_file, 'wt' )
- time_start = time.time()
repo_list.add_packages ( receive_package_counting )
- time_add_packages = time.time() - time_start
if modify_counter [0] > 0:
FH.write ( "\n" )
#FH.write (
sys.stdout.write (
- 'done after {t} seconds\n'
+ 'done after {t:.2f} seconds\n'
'{p} packages processed in total, out of which\n'
'{m} have been modified and '
'{n} have been filtered out\n'.format (
- t = round ( time_add_packages, 1 ),
+ t = roverlay.stats.collector.static.repo.queue_time.get_total(),
p = sum ( modify_counter ),
m = modify_counter [0],
n = modify_counter [2],
@@ -376,14 +369,7 @@ def main (
immediate_ebuild_writes = OPTION ( 'immediate_ebuild_writes' ),
)
- if 'sync_time' in globals():
- overlay_creator.set_timestats ( 'sync_packages', sync_time )
-
- t_start = time.time()
repo_list.add_packages ( overlay_creator.add_package )
- overlay_creator.set_timestats (
- 'add_packages', time.time() - t_start
- )
overlay_creator.release_package_rules()
@@ -399,7 +385,7 @@ def main (
optionally ( overlay_creator.write_overlay, 'write_overlay' )
optionally ( overlay_creator.show_overlay, 'show_overlay' )
if OPTION ( 'print_stats' ):
- print ( "\n" + overlay_creator.stats_str() )
+ print ( "\n***old stats are disabled (--stats)***" )
# FIXME/TODO:
@@ -508,6 +494,7 @@ def main (
raise
try:
+ roverlay.stats.collector.static.time.begin ( "setup" )
roverlay.setup_initial_logger()
conf = roverlay.load_config_file (
@@ -527,6 +514,8 @@ def main (
)
else:
raise
+ else:
+ roverlay.stats.collector.static.time.end ( "setup" )
if do_setupdirs:
sys.exit ( run_setupdirs (
@@ -637,6 +626,12 @@ def main (
run_overlay_create()
+ # *** TEMPORARY ***
+ print ( "\n{:-^60}".format ( " stats dump " ) )
+ print ( roverlay.stats.collector.static )
+ print ( "{:-^60}".format ( " end stats dump " ) )
+
+
if len ( actions ) > len ( actions_done ):
die (
"Some actions (out of {!r}) could not be performed!".format (
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-29 8:55 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-29 8:55 UTC (permalink / raw
To: gentoo-commits
commit: 563e9dba634c7a1525055476019168fb7f541139
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 29 08:55:06 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 29 08:55:06 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=563e9dba
roverlay/main: print formatted stats str
---
roverlay/argutil.py | 8 ++++++++
roverlay/main.py | 15 +++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 449b359..04ea84f 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -322,6 +322,13 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--dump-stats',
+ help='print all stats to stdout (raw format)',
+ default=False,
+ action='store_true',
+ )
+
+ arg (
'--nosync', '--no-sync', default=argparse.SUPPRESS,
help="disable syncing with remotes (offline mode).",
action='store_true',
@@ -480,6 +487,7 @@ def parse_argv ( command_map, **kw ):
fixup_category_move_rev = p.fixup_category_move_rev,
target_uid = p.target_uid,
target_gid = p.target_gid,
+ dump_stats = p.dump_stats,
)
diff --git a/roverlay/main.py b/roverlay/main.py
index cc3a5ab..80a6813 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -385,7 +385,12 @@ def main (
optionally ( overlay_creator.write_overlay, 'write_overlay' )
optionally ( overlay_creator.show_overlay, 'show_overlay' )
if OPTION ( 'print_stats' ):
- print ( "\n***old stats are disabled (--stats)***" )
+ sys.stdout.write ( '\n' )
+ sys.stdout.write (
+ roverlay.stats.collector.static.get_creation_str()
+ )
+ sys.stdout.write ( '\n\n' )
+ sys.stdout.flush()
# FIXME/TODO:
@@ -627,9 +632,11 @@ def main (
# *** TEMPORARY ***
- print ( "\n{:-^60}".format ( " stats dump " ) )
- print ( roverlay.stats.collector.static )
- print ( "{:-^60}".format ( " end stats dump " ) )
+ if OPTION ( 'dump_stats' ):
+ print ( "\n{:-^60}".format ( " stats dump " ) )
+ print ( roverlay.stats.collector.static )
+ print ( "{:-^60}".format ( " end stats dump " ) )
+ # *** END TEMPORARY ***
if len ( actions ) > len ( actions_done ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-07-29 14:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-07-29 14:56 UTC (permalink / raw
To: gentoo-commits
commit: 3dae409f5f64cb96e095d9759b08cd9cf7e5fc48
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 29 14:55:58 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 29 14:55:58 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=3dae409f
roverlay/main: optionally write stats db file
---
roverlay/main.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/roverlay/main.py b/roverlay/main.py
index 80a6813..04678fa 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -620,6 +620,12 @@ def main (
# initialize roverlay.hook
roverlay.hook.setup()
+ # initialize database
+ STATS_DB_FILE = conf.get ( 'RRD_DB.file', None )
+ if STATS_DB_FILE:
+ roverlay.stats.collector.static.setup_database ( conf )
+ want_db_commit = False
+
# always run sync 'cause commands = {create,sync,apply_rules}
# and create,apply_rules implies (no)sync
run_sync()
@@ -629,6 +635,12 @@ def main (
run_apply_package_rules()
elif 'create' in actions:
run_overlay_create()
+ want_db_commit = True
+
+
+ if STATS_DB_FILE and want_db_commit:
+ roverlay.stats.collector.static.write_db()
+ roverlay.hook.run ( 'db_written' )
# *** TEMPORARY ***
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-01 12:44 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-01 12:44 UTC (permalink / raw
To: gentoo-commits
commit: 9b576fa2d1fc1b4b5c202793e8d5c2eafe079304
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 1 12:30:46 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 1 12:30:46 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9b576fa2
roverlay/packageinfo: bind hashdict in __init__()
---
roverlay/packageinfo.py | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 25e67d9..752f996 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -134,6 +134,8 @@ class PackageInfo ( object ):
# self.selfdeps is a list of _mandatory_ selfdeps
self.selfdeps = None
+ self.hashdict = dict()
+
#self.selfdeps_valid = UNDEF
#self.overlay_package_ref = None
#self._evars = dict()
@@ -537,17 +539,18 @@ class PackageInfo ( object ):
"""
pkgfile = self.get ( "package_file" )
- if hasattr ( self, 'hashdict' ) and self.hashdict:
+ if self.hashdict:
new_hashes = (
frozenset ( hashlist ) - frozenset ( self.hashdict.keys() )
)
-
- if new_hashes:
- self.hashdict.update (
- roverlay.digest.multihash_file ( pkgfile, new_hashes )
- )
else:
- self.hashdict = roverlay.digest.multihash_file ( pkgfile, hashlist )
+ new_hashes = hashlist
+
+
+ if new_hashes:
+ self.hashdict.update (
+ roverlay.digest.multihash_file ( pkgfile, new_hashes )
+ )
return self.hashdict
# --- end of make_hashes (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-01 12:44 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-01 12:44 UTC (permalink / raw
To: gentoo-commits
commit: 29ed894fc47817f4a67c90af6c1fe664d6c95dc0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 1 12:26:22 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 1 12:26:22 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=29ed894f
roverlay: disable revbump check via --no-revbump
The revbump-on-tarball-change check when doing incremental overlay creation
takes some time. The --no-revbump switch allows to disable it.
---
roverlay/argutil.py | 9 +++++++++
roverlay/main.py | 5 ++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index b101169..1f9a0bf 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -389,6 +389,14 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--no-revbump',
+ help="disable revbump-on-tarball change (saves time)",
+ dest='revbump',
+ default=True,
+ action='store_false',
+ )
+
+ arg (
'--dump-file',
help='''
standard file or stdout target for dumping information
@@ -483,6 +491,7 @@ def parse_argv ( command_map, **kw ):
force_distroot = p.force_distroot,
skip_manifest = p.no_manifest,
incremental = p.incremental,
+ revbump = p.revbump,
immediate_ebuild_writes = p.immediate_ebuild_writes,
dump_file = p.dump_file,
fixup_category_move = p.fixup_category_move,
diff --git a/roverlay/main.py b/roverlay/main.py
index 7830d23..dff81a8 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -292,7 +292,10 @@ def main (
)
repo_list.add_packages ( overlay_creator.add_package )
- overlay_creator.enqueue_postponed()
+ if OPTION ( 'revbump' ):
+ overlay_creator.enqueue_postponed()
+ else:
+ overlay_creator.discard_postponed()
overlay_creator.release_package_rules()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-02 10:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-02 10:34 UTC (permalink / raw
To: gentoo-commits
commit: 43ab1d2328ee2968dc0d5076f33629f859e12718
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 2 10:17:52 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 2 10:17:52 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=43ab1d23
support suffixes $PV when importing ebuilds
Selfdep validation may fail/ignore when dealing with import ebuilds with a
version suffix ("_pre..." etc.).
---
roverlay/packageinfo.py | 18 +++++++++++-------
roverlay/versiontuple.py | 30 +++++++++++++++++++++++++++---
2 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 752f996..704807e 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -805,17 +805,21 @@ class PackageInfo ( object ):
pv_str, DONT_CARE, pr_str = pvr.partition ( '-r' )
pv, DONT_CARE, pv_suffix = pv_str.partition ( '_' )
+ # non-digit chars in pv are not supported
+ pv_list = [ int(z) for z in pv.split ( '.' ) ]
+
if pv_suffix:
# not supported
- raise NotImplementedError (
- "version suffix {!r} cannot be preserved for $PVR {!r}".format (
- pv_suffix, pvr
+ self._info ['version'] = (
+ roverlay.versiontuple.SuffixedIntVersionTuple (
+ pv_list, pv_suffix
)
)
- # non-digit chars in pv are unsupported, too
- self._info ['version'] = roverlay.versiontuple.IntVersionTuple (
- int ( z ) for z in pv.split ( '.' )
- )
+ else:
+ self._info ['version'] = (
+ roverlay.versiontuple.IntVersionTuple ( pv_list )
+ )
+
self._info ['rev'] = int ( pr_str ) if pr_str else 0
self._info ['ebuild_verstr'] = pvr
diff --git a/roverlay/versiontuple.py b/roverlay/versiontuple.py
index 6586088..579471f 100644
--- a/roverlay/versiontuple.py
+++ b/roverlay/versiontuple.py
@@ -67,9 +67,9 @@ def pkgver_decorator ( func ):
class VersionTuple ( tuple ):
- def __init__ ( self, *args, **kwargs ):
- super ( VersionTuple, self ).__init__ ( *args, **kwargs )
- # --- end of __init__ (...) ---
+ def __new__ ( cls, gen_tuple, *args, **kwargs ):
+ return super ( VersionTuple, cls ).__new__ ( cls, gen_tuple )
+ # --- end of __new__ (...) ---
def get_comparator ( self, mode ):
"""Returns a function "this ~ other" that returns
@@ -228,4 +228,28 @@ class IntVersionTuple ( VersionTuple ):
return NotImplemented
# --- end of __gt__ (...) ---
+ def __str__ ( self ):
+ return '.'.join ( str(k) for k in self )
+ # --- end of __str__ ( self )
+
# --- end of IntVersionTuple ---
+
+class SuffixedIntVersionTuple ( VersionTuple ):
+ # inherit VersionTuple: does not implement comparision functions
+
+ def __init__ ( self, gen_tuple, suffix ):
+ super ( SuffixedIntVersionTuple, self ).__init__ ( gen_tuple )
+ self.suffix = suffix
+ # --- end of __init__ (...) ---
+
+ def get_suffix_str ( self ):
+ ret = str ( self.suffix )
+ if not ret or ret[0] == '_':
+ return ret
+ else:
+ return '_' + ret
+ # --- end of get_suffix_str (...) ---
+
+ def __str__ ( self ):
+ return '.'.join ( str(k) for k in self ) + self.get_suffix_str()
+ # --- end of __str__ (...) ----
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-02 10:34 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-02 10:34 UTC (permalink / raw
To: gentoo-commits
commit: 6efa8bdd1923b472dab2895823ab975009a94d2f
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 2 10:21:49 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 2 10:21:49 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6efa8bdd
roverlay/argutil: --sync-imports
--sync-imports: fetch src when importing ebuilds even if --nosync is given
---
roverlay/argutil.py | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 1f9a0bf..0f0b593 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -337,6 +337,16 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--sync-imports',
+ default=None, dest='sync_imported',
+ help=(
+ 'allow fetching src files for imported ebuilds even if sync '
+ 'is forbidden'
+ ),
+ action='store_true',
+ )
+
+ arg (
'--force-distroot',
help="always use <DISTROOT>/<repo name> as repo distdir.",
**opt_in
@@ -499,6 +509,7 @@ def parse_argv ( command_map, **kw ):
target_uid = p.target_uid,
target_gid = p.target_gid,
dump_stats = p.dump_stats,
+ sync_imported = p.sync_imported,
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-02 14:30 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-02 14:30 UTC (permalink / raw
To: gentoo-commits
commit: fa34e37bc4e28f54e4a952331063e9b02b8f5fcc
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 2 14:27:10 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 2 14:27:10 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=fa34e37b
roverlay/hook: set initial directory
run(): set initial working directory depending on phase
---
roverlay/hook.py | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/roverlay/hook.py b/roverlay/hook.py
index 262d3c2..d89eca0 100644
--- a/roverlay/hook.py
+++ b/roverlay/hook.py
@@ -4,7 +4,7 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
-import os.path
+import os
import logging
import roverlay.config
@@ -29,6 +29,10 @@ _EVENT_RESTRICT = None
_EVENT_POLICY = 0
+PHASE_INITIAL_DIRS = {
+ 'user': True,
+}
+
class HookException ( Exception ):
pass
@@ -184,9 +188,13 @@ def run ( phase, catch_failure=True ):
# -- end if
- if _EVENT_SCRIPT and phase_allowed ( phase ):
+ if _EVENT_SCRIPT and phase_allowed ( phase.lower() ):
+ initial_dir = PHASE_INITIAL_DIRS.get ( phase.lower() )
+ if initial_dir is True:
+ initial_dir = os.getcwd()
+
if roverlay.tools.shenv.run_script (
- _EVENT_SCRIPT, phase, return_success=True
+ _EVENT_SCRIPT, phase, return_success=True, initial_dir=initial_dir,
):
return True
elif catch_failure:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-07 16:10 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-07 16:10 UTC (permalink / raw
To: gentoo-commits
commit: 1feee9c63998b09147f9de18c4e39c5f97f8e067
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 7 15:40:56 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 7 15:40:56 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1feee9c6
roverlay: --strict[-sync]
--strict-sync: exit (call die()) if sync doesn't succeed
--strict: enable all --strict- switches
---
roverlay/argutil.py | 16 ++++++++++++++++
roverlay/main.py | 8 +++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 0f0b593..13f23df 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -331,6 +331,20 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--strict',
+ help='enable all --strict-<sth> options',
+ default=False,
+ action='store_true',
+ )
+
+ arg (
+ '--strict-sync',
+ help='exit on any sync errors',
+ default=False,
+ action='store_true',
+ )
+
+ arg (
'--nosync', '--no-sync', default=argparse.SUPPRESS,
help="disable syncing with remotes (offline mode).",
action='store_true',
@@ -510,6 +524,8 @@ def parse_argv ( command_map, **kw ):
target_gid = p.target_gid,
dump_stats = p.dump_stats,
sync_imported = p.sync_imported,
+ strict = p.strict,
+ strict_sync = p.strict_sync,
)
diff --git a/roverlay/main.py b/roverlay/main.py
index 4954645..4a65aee 100644
--- a/roverlay/main.py
+++ b/roverlay/main.py
@@ -120,6 +120,9 @@ def main (
def run_sync():
if "sync" in actions_done: return
+
+ STRICT_SYNC = OPTION ( 'strict' ) or OPTION ( 'strict_sync' )
+
try:
# set up the repo list
global repo_list
@@ -136,7 +139,7 @@ def main (
repo_list.load()
## this runs _nosync() or _sync(), depending on extra_opts->nosync
- repo_list.sync()
+ sync_success = repo_list.sync ( fail_greedy=STRICT_SYNC )
set_action_done ( "sync" )
except KeyboardInterrupt:
@@ -149,6 +152,9 @@ def main (
)
else:
raise
+ else:
+ if not sync_success and STRICT_SYNC:
+ die ( "errors occured while syncing.", DIE.SYNC )
# --- end of run_sync() ---
def run_apply_package_rules():
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-12 8:18 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-12 8:18 UTC (permalink / raw
To: gentoo-commits
commit: 4d16ea3712b1694bed4f6bbbca84ef90095631cf
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 12 08:15:39 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 12 08:15:39 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4d16ea37
roverlay: do not fail if rrdtool is missing
If rrdtool is missing: disable persistent stats collection and continue.
Additionally, database setup/writing has been moved to RuntimeEnvironment.
---
roverlay/defaultscript.py | 12 +++--------
roverlay/runtime.py | 54 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index 9d00e94..0aa32d8 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -60,6 +60,7 @@ def main ( installed, *args, **kw ):
else:
roverlay.hook.setup()
+ main_env.setup_database()
retcode = os.EX_OK
@@ -70,15 +71,8 @@ def main ( installed, *args, **kw ):
else:
die ( "unknown command: {!r}".format ( main_env.command ) )
- if main_env.stats_db_file and main_env.want_db_commit:
- main_env.stats.write_database()
- roverlay.hook.run ( 'db_written' )
-
- if main_env.options ['dump_stats']:
- print ( "\n{:-^60}".format ( " stats dump " ) )
- print ( main_env.stats )
- print ( "{:-^60}".format ( " end stats dump " ) )
-
+ main_env.write_database()
+ main_env.dump_stats()
sys.exit ( retcode )
# --- end of main (...) ---
diff --git a/roverlay/runtime.py b/roverlay/runtime.py
index f44dbad..81a7726 100644
--- a/roverlay/runtime.py
+++ b/roverlay/runtime.py
@@ -4,9 +4,12 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
+import logging
+import errno
import os
import sys
+
import roverlay.argparser
import roverlay.core
import roverlay.hook
@@ -24,6 +27,7 @@ class RuntimeEnvironment ( object ):
):
super ( RuntimeEnvironment, self ).__init__()
+ self.logger = logging.getLogger()
self.HLINE = 79 * '-'
self.stats = roverlay.stats.collector.static
self.config = None
@@ -109,10 +113,7 @@ class RuntimeEnvironment ( object ):
raise
- self.stats_db_file = self.config.get ( 'RRD_DB.file', None )
- if self.stats_db_file:
- self.stats.setup_database ( self.config )
-
+ self.stats_db_file = self.config.get ( 'RRD_DB.file', None )
self.command = command
self.options = options
self.additional_config = additional_config
@@ -125,6 +126,51 @@ class RuntimeEnvironment ( object ):
self.stats.time.end ( "setup" )
# --- end of setup (...) ---
+ def setup_database ( self ):
+ if self.stats_db_file:
+ try:
+ self.stats.setup_database ( self.config )
+
+ except OSError as oserr:
+ if oserr.errno == errno.ENOENT:
+ self.stats_db_file = None
+ self.logger.error (
+ 'rrdtool not available. '
+ 'Persistent stats collection has been disabled.'
+ )
+ return False
+ else:
+ raise
+
+ else:
+ return True
+ else:
+ return False
+ # --- end of setup_database (...) ---
+
+ def write_database ( self, hook_event=True ):
+ if self.stats_db_file and self.want_db_commit:
+ self.stats.write_database()
+ if hook_event:
+ roverlay.hook.run ( "db_written" )
+ return True
+ else:
+ return False
+ # --- end of write_database (...) ---
+
+ def dump_stats ( self, stream=None, force=False ):
+ if force or self.options ['dump_stats']:
+ cout = sys.stdout.write if stream is None else stream.write
+
+ cout ( "\n{:-^60}\n".format ( " stats dump " ) )
+ cout ( str ( self.stats ) )
+ cout ( "\n{:-^60}\n".format ( " end stats dump " ) )
+
+ return True
+ else:
+ return False
+ # --- end of dump_stats (...) ---
+
def set_action_done ( self, action ):
self.actions_done.add ( action )
# --- end of set_action_done (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-12 8:28 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-12 8:28 UTC (permalink / raw
To: gentoo-commits
commit: 5895b5e0763ebf9b52dedf2a5760bc4791ad1c1d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 12 08:25:49 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 12 08:28:25 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5895b5e0
setupdirs command: don't modify symlinks
---
roverlay/defaultscript.py | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index 0aa32d8..dfbe29d 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -170,12 +170,18 @@ def run_setupdirs ( env ):
)
if dirpath:
- dodir ( dirpath )
- if dirmask & WANT_PRIVATE:
- os.chmod ( dirpath, dirmode_private )
- if dirmask & WANT_USERDIR and should_chown:
- os.chown ( dirpath, target_uid, target_gid )
-
+ if os.path.islink ( dirpath ):
+ sys.stdout.write (
+ '{!r} is a symlink - skipping setupdir '
+ 'actions.\n'.format ( dirpath )
+ )
+ else:
+ #elif dodir ( dirpath ):
+ dodir ( dirpath )
+ if dirmask & WANT_PRIVATE:
+ os.chmod ( dirpath, dirmode_private )
+ if dirmask & WANT_USERDIR and should_chown:
+ os.chown ( dirpath, target_uid, target_gid )
return os.EX_OK
# --- end of run_setupdirs (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-13 8:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-13 8:56 UTC (permalink / raw
To: gentoo-commits
commit: 6ab122cf449017862a26e6da196ce33badfe7ba6
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 13 08:40:26 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 13 08:40:26 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6ab122cf
roverlay/argparser: RoverlayStatusArgumentParser
arg parser for the status script.
This commit also modifies the main script's parser (-> defaultscript.main) as
both parser now inherit RoverlayArgumentParser (and not ~Base).
---
roverlay/argparser.py | 203 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 157 insertions(+), 46 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 054d710..84e1478 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -22,16 +22,32 @@ from roverlay.argutil import \
class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
+
+ DESCRIPTION_TEMPLATE = None
+
def __init__ (
- self, defaults=None, description=True, formatter_class=True, **kwargs
+ self, defaults=None, description=True, formatter_class=True,
+ format_description=False, **kwargs
):
+ if description is True:
+ if self.DESCRIPTION_TEMPLATE is None:
+ desc = (
+ roverlay.core.description_str + '\n'
+ + roverlay.core.license_str
+ )
+ else:
+ desc = self.format_description()
+ elif description:
+ if format_description:
+ desc = self.format_description ( description )
+ else:
+ desc = description
+ else:
+ desc = None
+
super ( RoverlayArgumentParserBase, self ).__init__ (
- defaults = defaults,
- description = (
- '\n'.join ((
- roverlay.core.description_str, roverlay.core.license_str
- )) if description is True else description
- ),
+ defaults = defaults,
+ description = desc,
formatter_class = (
argparse.RawDescriptionHelpFormatter
if formatter_class is True else formatter_class
@@ -43,6 +59,24 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
self.extra_conf = None
# --- end of __init__ (...) ---
+ def format_description ( self, desc=None ):
+ return ( self.DESCRIPTION_TEMPLATE if desc is None else desc ).format (
+ version=roverlay.core.version,
+ license=roverlay.core.license_str,
+ )
+ # --- end of format_description (...) ---
+
+ def format_command_map ( self, command_map ):
+ return (
+ "\nKnown commands:\n" + '\n'.join (
+ # '* <space> <command> - <command description>'
+ '* {cmd} - {desc}'.format (
+ cmd=cmd.ljust ( 15 ), desc=desc
+ ) for cmd, desc in command_map.items()
+ )
+ )
+ # --- end of format_command_map (...) ---
+
def do_extraconf ( self, value, path ):
pos = self.extra_conf
if isinstance ( path, str ):
@@ -456,7 +490,122 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
# --- end of RoverlayArgumentParserBase ---
-class RoverlayMainArgumentParser ( RoverlayArgumentParserBase ):
+class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
+
+ COMMAND_DESCRIPTION = None
+ DEFAULT_COMMAND = None
+
+ def __init__ ( self, default_command=None, **kwargs ):
+ super ( RoverlayArgumentParser, self ).__init__ ( **kwargs )
+ self.default_command = (
+ self.DEFAULT_COMMAND if default_command is None else default_command
+ )
+ self.command = None
+
+ if self.default_command:
+ assert self.default_command in self.COMMAND_DESCRIPTION
+ # --- end of __init__ (...) ---
+
+ def setup_actions ( self ):
+ arg = self.add_argument_group (
+ "actions", title="actions",
+ description=self.format_command_map ( self.COMMAND_DESCRIPTION ),
+ )
+
+ arg (
+ 'command', default=self.default_command, metavar='<action>',
+ nargs="?", choices=self.COMMAND_DESCRIPTION.keys(),
+ flags=self.ARG_HELP_DEFAULT,
+ help="action to perform"
+ )
+
+ return arg
+ # --- end of setup_actions (...) ---
+
+ def parse_actions ( self ):
+ command = self.parsed ['command']
+ # --- end of parse_actions (...) ---
+
+# --- end of RoverlayArgumentParser ---
+
+class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
+
+ DESCRIPTION_TEMPLATE = "roverlay status tool {version}\n{license}"
+
+ SETUP_TARGETS = (
+ 'version',
+ 'output_options', 'script_mode', 'config_minimal',
+ 'actions',
+ )
+ PARSE_TARGETS = ( 'config', 'actions', 'extra', )
+
+ COMMAND_DESCRIPTION = {
+ 'status': 'report overlay status',
+ }
+ DEFAULT_COMMAND = 'status'
+
+ MODES = frozenset ({ 'cgi', 'cli' })
+ DEFAULT_MODE = 'cli'
+
+ def setup_script_mode ( self ):
+ arg = self.add_argument_group (
+ "script_mode", title="script mode",
+ )
+
+ arg (
+ '-m', '--mode', dest='script_mode',
+ default=self.DEFAULT_MODE, metavar='<mode>',
+ flags=self.ARG_WITH_DEFAULT, choices=self.MODES,
+ help='set script mode (%(choices)s)',
+ )
+
+ for script_mode in self.MODES:
+ arg (
+ '--' + script_mode, dest='script_mode',
+ flags=self.ARG_SHARED, action='store_const', const=script_mode,
+ help='set script mode to {!r}'.format ( script_mode ),
+ )
+
+ return arg
+ # --- end of setup_script_mode (...) ---
+
+ def setup_output_options ( self ):
+ arg = self.add_argument_group (
+ 'output_options', title='output options',
+ )
+
+ arg (
+ '-O', '--output', dest='outfile', default='-',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_META_FILE,
+ type=couldbe_stdout_or_file,
+ help='output file (or stdout)',
+ )
+
+ arg (
+ '-t', '--template', dest='template', default=argparse.SUPPRESS,
+ flags=self.ARG_WITH_DEFAULT|self.ARG_META_FILE,
+ type=is_fs_file,
+ help='template file for generating output',
+ )
+
+ arg (
+ '--cgi-content-type', dest='cgi_content_type', default="text/html",
+ flags=self.ARG_WITH_DEFAULT, metavar='<type>',
+ help='cgi content type',
+ )
+
+ return arg
+ # --- end of setup_output_options (...) ---
+
+ def parse_extra ( self ):
+ self.parsed ['want_logging'] = False
+ self.parsed ['load_main_only'] = True
+ # --- end of parse_extra (...) ---
+
+
+# --- end of RoverlayStatusArgumentParser (...) ---
+
+class RoverlayMainArgumentParser ( RoverlayArgumentParser ):
SETUP_TARGETS = (
'version', 'actions', 'config', 'overlay', 'remote',
@@ -485,21 +634,6 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParserBase ):
DEFAULT_COMMAND = 'create'
- def __init__ ( self, default_command=None, command_desc=None,**kwargs ):
- super ( RoverlayMainArgumentParser, self ).__init__ ( **kwargs )
-
- self.default_command = (
- self.DEFAULT_COMMAND if default_command is None else default_command
- )
- self.command_desc = (
- self.COMMAND_DESCRIPTION if command_desc is None else command_desc
- )
-
- self.command = None
-
- assert self.default_command in self.command_desc
- # --- end of __init__ (...) ---
-
def parse_actions ( self ):
command = self.parsed ['command']
@@ -522,29 +656,6 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParserBase ):
self.command = command
# --- end of parse_actions (...) ---
- def setup_actions ( self ):
- arg = self.add_argument_group (
- "actions", title="actions",
- description=(
- "\nKnown commands:\n" + '\n'.join (
- # '* <space> <command> - <command description>'
- '* {cmd} - {desc}'.format (
- cmd=cmd.ljust ( 15 ), desc=desc
- ) for cmd, desc in self.command_desc.items()
- )
- )
- )
-
- arg (
- 'command', default=self.default_command, metavar='<action>',
- nargs="?", choices=self.command_desc.keys(),
- flags=self.ARG_HELP_DEFAULT,
- help="action to perform"
- )
-
- return arg
- # --- end of setup_actions (...) ---
-
def setup_setupdirs ( self ):
arg = self.add_argument_group (
'setupdirs', title='setupdirs options',
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-13 8:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-13 8:56 UTC (permalink / raw
To: gentoo-commits
commit: 4cef51017af1d97fa4c75625fcabc351486804cb
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 13 08:42:54 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 13 08:42:54 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4cef5101
roverlay/runtime: make runtime object modular
split RuntimeEnvironment into a common (RuntimeEnvironmentBase) and a "main
script"-specific part (RuntimeEnvironment, as before).
The runtime object does no longer set up itself in __init__(), setup() has to be
called manually now.
---
roverlay/defaultscript.py | 1 +
roverlay/runtime.py | 144 +++++++++++++++++++++++++++-------------------
2 files changed, 85 insertions(+), 60 deletions(-)
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index dfbe29d..8c629f8 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -35,6 +35,7 @@ def main_installed ( *args, **kw ):
def main ( installed, *args, **kw ):
main_env = roverlay.runtime.RuntimeEnvironment ( installed, *args, **kw )
+ main_env.setup()
if main_env.want_command ( 'setupdirs' ):
sys.exit ( run_setupdirs ( main_env ) )
diff --git a/roverlay/runtime.py b/roverlay/runtime.py
index 81a7726..a65555d 100644
--- a/roverlay/runtime.py
+++ b/roverlay/runtime.py
@@ -18,113 +18,137 @@ import roverlay.stats.collector
from roverlay.core import DIE, die
+class RuntimeEnvironmentBase ( object ):
+
+ ARG_PARSER_CLS = None
+ KEEP_ARG_PARSER = False
-class RuntimeEnvironment ( object ):
def __init__ ( self,
installed,
hide_exceptions=False,
config_file_name=roverlay.core.DEFAULT_CONFIG_FILE_NAME
):
- super ( RuntimeEnvironment, self ).__init__()
-
+ super ( RuntimeEnvironmentBase, self ).__init__()
self.logger = logging.getLogger()
+ self.installed = bool ( installed )
+ self.hide_exceptions = bool ( hide_exceptions )
+ self.config_file_name = str ( config_file_name )
self.HLINE = 79 * '-'
+
self.stats = roverlay.stats.collector.static
self.config = None
self.additional_config = None
self.options = None
- self.actions_done = set()
self.command = None
+ # --- end of __init__ (...) ---
- self._repo_list = None
- self._overlay_creator = None
- self.stats_db_file = None
-
- self.want_db_commit = False
-
- self.hide_exceptions = hide_exceptions
- if hide_exceptions:
+ def setup ( self ):
+ roverlay.core.setup_initial_logger()
+ self.stats.time.begin ( "setup" )
+ if self.hide_exceptions:
try:
- self.setup ( installed, config_file_name )
+ self.do_setup()
except:
die ( "failed to initialize runtime environment." )
else:
- self.setup ( installed, config_file_name )
- # --- end of __init__ (...) ---
-
- def get_repo_list ( self ):
- if self._repo_list is None:
- self._repo_list = roverlay.remote.repolist.RepoList (
- sync_enabled = not self.config.get_or_fail ( 'nosync' ),
- force_distroot = self.options.get ( 'force_distroot' )
- )
- return self._repo_list
- # --- end of get_repo_list (...) ---
-
- def get_overlay_creator ( self ):
- if self._overlay_creator is None:
- self._overlay_creator = roverlay.overlay.creator.OverlayCreator (
- skip_manifest = not self.options ['manifest'],
- incremental = self.options ['incremental'],
- allow_write = self.options ['write_overlay'],
- immediate_ebuild_writes = self.options ['immediate_ebuild_writes'],
- )
- return self._overlay_creator
- # --- end of get_overlay_creator (...) ---
-
- def setup ( self, installed, config_file_name ):
- roverlay.core.setup_initial_logger()
- self.stats.time.begin ( "setup" )
+ self.do_setup()
+ self.stats.time.end ( "setup" )
+ # --- end of setup (...) ---
- parser = roverlay.argparser.RoverlayMainArgumentParser (
+ def do_setup_parser ( self ):
+ parser = self.ARG_PARSER_CLS (
defaults={
'config_file': roverlay.core.locate_config_file (
- installed, config_file_name
+ self.installed, self.config_file_name
)
}
)
parser.setup()
parser.parse()
- parser.do_extraconf ( installed, 'installed' )
-
- command = parser.command
- options = parser.parsed
- additional_config = parser.extra_conf
+ parser.do_extraconf ( self.installed, 'installed' )
- del parser
+ self.command = getattr ( parser, 'command', None )
+ self.options = parser.parsed
+ self.additional_config = parser.extra_conf
+ if self.KEEP_ARG_PARSER:
+ self.parser = parser
+ # --- end of do_setup_parser (...) ---
+ def do_setup_config ( self ):
try:
self.config = roverlay.core.load_config_file (
- options ['config_file'],
- extraconf = additional_config,
- setup_logger = options ['want_logging'],
- load_main_only = options ['load_main_only'],
+ self.options ['config_file'],
+ extraconf = self.additional_config,
+ setup_logger = self.options.get ( 'want_logging', False ),
+ load_main_only = self.options.get ( 'load_main_only', True ),
)
except:
if self.hide_exceptions:
die (
"Cannot load config file {!r}".format (
- options ['config_file']
+ self.options ['config_file']
),
DIE.CONFIG
)
else:
raise
+ # --- end of do_setup_config (...) ---
+
+ def do_setup ( self ):
+ self.do_setup_parser()
+ self.do_setup_config()
+ # --- end of do_setup (...) ---
+
+# --- end of RuntimeEnvironmentBase (...) ---
+
+class RuntimeEnvironment ( RuntimeEnvironmentBase ):
+ ARG_PARSER_CLS = roverlay.argparser.RoverlayMainArgumentParser
- self.stats_db_file = self.config.get ( 'RRD_DB.file', None )
- self.command = command
- self.options = options
- self.additional_config = additional_config
+ def __init__ ( self, installed, *args, **kw ):
+ super ( RuntimeEnvironment, self ).__init__ ( installed, *args, **kw )
+
+ self.actions_done = set()
+ self.command = None
+
+ self.stats_db_file = None
+ self.want_db_commit = False
+
+ self._repo_list = None
+ self._overlay_creator = None
+ # --- end of __init__ (...) ---
+ def get_repo_list ( self ):
+ if self._repo_list is None:
+ self._repo_list = roverlay.remote.repolist.RepoList (
+ sync_enabled = not self.config.get_or_fail ( 'nosync' ),
+ force_distroot = self.options.get ( 'force_distroot' )
+ )
+ return self._repo_list
+ # --- end of get_repo_list (...) ---
+
+ def get_overlay_creator ( self ):
+ if self._overlay_creator is None:
+ self._overlay_creator = roverlay.overlay.creator.OverlayCreator (
+ skip_manifest = not self.options ['manifest'],
+ incremental = self.options ['incremental'],
+ allow_write = self.options ['write_overlay'],
+ immediate_ebuild_writes = self.options ['immediate_ebuild_writes'],
+ )
+ return self._overlay_creator
+ # --- end of get_overlay_creator (...) ---
+
+ def do_setup ( self ):
+ self.do_setup_parser()
+ self.do_setup_config()
+
+ self.stats_db_file = self.config.get ( 'RRD_DB.file', None )
# want_logging <=> <have a command that uses hooks>
- if options ['want_logging']:
+ if self.options ['want_logging']:
roverlay.hook.setup()
-
- self.stats.time.end ( "setup" )
- # --- end of setup (...) ---
+ # --- end of do_setup (...) ---
def setup_database ( self ):
if self.stats_db_file:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-13 8:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-13 8:56 UTC (permalink / raw
To: gentoo-commits
commit: a5254ba1cab1dde89f78a9552373dd342de8ae97
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 13 08:50:12 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 13 08:50:12 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a5254ba1
roverlay/status: status report generation
roverlay/status creates an environment for generating status reports based on
mako templates. CGI mode is supported, too ("--cgi").
---
roverlay/status.py | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 314 insertions(+)
diff --git a/roverlay/status.py b/roverlay/status.py
new file mode 100644
index 0000000..7872674
--- /dev/null
+++ b/roverlay/status.py
@@ -0,0 +1,314 @@
+# R overlay -- create status reports based on templates
+# -*- 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.
+
+from __future__ import print_function
+#from __future__ import division
+
+import os
+import sys
+import cgi
+import cgitb
+import weakref
+
+
+# using mako
+import mako.exceptions
+import mako.lookup
+import mako.template
+
+
+import roverlay.argparser
+import roverlay.runtime
+import roverlay.tools.shenv
+import roverlay.db.rrdtool
+import roverlay.util.common
+
+
+class ReferenceableDict ( dict ):
+ def ref ( self ):
+ return weakref.ref ( self )
+ # --- end of ref (...) ---
+
+ def sorted_items ( self, keysort=None ):
+ if keysort is None:
+ return sorted ( self.items(), key=lambda kv: kv[0] )
+ else:
+ return sorted ( self.items(), key=lambda kv: keysort ( kv[0] ) )
+ # --- end of sorted_items (...) ---
+
+# --- end of ReferenceableDict ---
+
+class SelfReferencingDict ( ReferenceableDict ):
+ SELFREF_KEY = 'dictref'
+
+## def __setitem__ ( self, key, *args, **kw ):
+## if key == self.__class__.SELFREF_KEY:
+## raise AttributeError (
+## "{!r} is readonly.".format ( self.__class__.SELFREF_KEY )
+## )
+## else:
+## return super ( SelfReferencingDict, self ).__setitem__ (
+## key, *args, **kw
+## )
+## # --- end of __setitem__ (...) ---
+
+ def __init__ ( self, *args, **kwargs ):
+ super ( SelfReferencingDict, self ).__init__ ( *args, **kwargs )
+ self [self.__class__.SELFREF_KEY] = self.ref()
+ # or use __getitem__
+ # --- end of __init__ (...) ---
+
+# --- end of SelfReferencingDict ---
+
+
+class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
+ ARG_PARSER_CLS = roverlay.argparser.RoverlayStatusArgumentParser
+
+ TEMPLATE_ENCODING = 'utf-8'
+
+ # variables from /etc/nginx/fastcgi.conf
+ # (will be kept in template env dict depending on script mode)
+ #
+ # sed -nr -e 's,^fastcgi_param\s+(\S+)\s+.*$,"\1"\,,p' \
+ # /etc/nginx/fastcgi.conf | sort
+ #
+ NGINX_CGI_VARS = frozenset ({
+ "CONTENT_LENGTH",
+ "CONTENT_TYPE",
+ "DOCUMENT_ROOT",
+ "DOCUMENT_URI",
+ "GATEWAY_INTERFACE",
+ "HTTPS",
+ "QUERY_STRING",
+ "REDIRECT_STATUS",
+ "REMOTE_ADDR",
+ "REMOTE_PORT",
+ "REQUEST_METHOD",
+ "REQUEST_URI",
+ "SCRIPT_FILENAME",
+ "SCRIPT_NAME",
+ "SERVER_ADDR",
+ "SERVER_NAME",
+ "SERVER_PORT",
+ "SERVER_PROTOCOL",
+ "SERVER_SOFTWARE",
+ })
+
+ # common cgi vars as listed in
+ # /usr/lib/python3.2/cgi.py
+ #
+ COMMON_CGI_VARS = frozenset ({
+ "AUTH_TYPE",
+ "CONTENT_LENGTH",
+ "CONTENT_TYPE",
+ "DATE_GMT",
+ "DATE_LOCAL",
+ "DOCUMENT_NAME",
+ "DOCUMENT_ROOT",
+ "DOCUMENT_URI",
+ "GATEWAY_INTERFACE",
+ "LAST_MODIFIED",
+ #"PATH",
+ "PATH_INFO",
+ "PATH_TRANSLATED",
+ "QUERY_STRING",
+ "REMOTE_ADDR",
+ "REMOTE_HOST",
+ "REMOTE_IDENT",
+ "REMOTE_USER",
+ "REQUEST_METHOD",
+ "SCRIPT_NAME",
+ "SERVER_NAME",
+ "SERVER_PORT",
+ "SERVER_PROTOCOL",
+ "SERVER_ROOT",
+ "SERVER_SOFTWARE",
+ "HTTP_ACCEPT",
+ "HTTP_CONNECTION",
+ "HTTP_HOST",
+ "HTTP_PRAGMA",
+ "HTTP_REFERER",
+ "HTTP_USER_AGENT",
+ })
+
+
+ def do_setup_mako ( self ):
+ template_dirs = []
+
+ if 'template' in self.options:
+ dirname, basename = os.path.split (
+ self.options ['template'].rstrip ( os.sep )
+ )
+ assert dirname and basename
+ template_dirs.append ( dirname )
+ self.default_template = basename
+ else:
+ self.default_template = self.script_mode
+ # -- end if
+
+ if self.installed:
+ template_dirs.append (
+ self.config.get_or_fail ( 'INSTALLINFO.libexec' )
+ )
+
+ extra_dirs = self.config.get ( 'STATS.TEMPLATE.root' )
+ if extra_dirs:
+ template_dirs.extend ( extra_dirs )
+
+ if not template_dirs:
+ raise Exception ( "no template directories found!" )
+
+
+ module_dir = self.config.get ( 'STATS.TEMPLATE.module_dir', None )
+ if module_dir is None:
+ module_dir = self.config.get ( 'CACHEDIR.root', None )
+ if module_dir:
+ module_dir += os.sep + 'mako_templates'
+
+
+ self._mako_lookup = mako.lookup.TemplateLookup (
+ directories=template_dirs, module_directory=module_dir,
+ output_encoding=self.TEMPLATE_ENCODING,
+ )
+ # --- end of do_setup_mako (...) ---
+
+ def do_setup ( self ):
+ self.do_setup_parser()
+ script_mode = self.options ['script_mode']
+ assert script_mode and script_mode.islower()
+ if script_mode == 'cgi':
+ cgitb.enable()
+
+ self.do_setup_config()
+ self.template_vars = SelfReferencingDict (
+ roverlay.tools.shenv.setup_env()
+ )
+ roverlay.tools.shenv.restore_msg_vars ( self.template_vars )
+
+ try:
+ del self.template_vars ['STATS_DB']
+ except KeyError:
+ pass
+
+ self.script_mode = script_mode
+ self.outfile = self.options ['outfile']
+ if self.outfile == '-':
+ self.outfile = None
+
+ self.set_template_vars (
+ EXE=sys.argv[0], EXE_NAME=os.path.basename ( sys.argv[0] ),
+ SCRIPT_MODE=script_mode
+ )
+
+ if script_mode == 'cgi':
+ # inherit cgi-related vars from os.environ
+ self.set_template_vars (
+ roverlay.util.common.keepenv_v (
+ self.NGINX_CGI_VARS|self.COMMON_CGI_VARS
+ ),
+ CGI_FORM=cgi.FieldStorage( keep_blank_values=0 ),
+ )
+
+
+ self.stats_db = None
+ stats_db_file = self.config.get ( 'RRD_DB.file', None )
+ if stats_db_file:
+ self.stats_db = roverlay.db.rrdtool.RRD (
+ stats_db_file, readonly=True
+ )
+ self.stats_db.make_cache()
+
+
+ # transfer db cache to template_vars
+ # * copy lastupdate
+ # * import values
+ #
+ self.set_template_vars (
+ self.stats_db.cache ['values'],
+ lastupdate=self.stats_db.cache ['lastupdate'],
+ STATS_DB=self.stats_db, STATS_DB_FILE=stats_db_file,
+ )
+
+ self.do_setup_mako()
+ # --- end of do_setup (...) ---
+
+ def serve_template ( self, template_name=None, catch_exceptions=True ):
+ try:
+ my_template = self._mako_lookup.get_template (
+ template_name if template_name is not None
+ else self.default_template
+ )
+ ret = my_template.render ( **self.template_vars )
+ except:
+ if catch_exceptions:
+ if self.script_mode == 'cgi':
+ ret = mako.exceptions.html_error_template().render()
+ else:
+ ret = mako.exceptions.text_error_template().render()
+ else:
+ raise
+ # -- end if
+ return ret
+ # --- end of serve_template (...) ---
+
+ def set_template_vars ( self, *args, **kwargs ):
+ for kw in args:
+ self.template_vars.update ( kw )
+ self.template_vars.update ( kwargs )
+ # --- end of setup_vars (...) ---
+
+ def write_cgi_header ( self, stream, encode=False, force=False ):
+ if force or self.script_mode == 'cgi':
+ content_type = self.options ['cgi_content_type']
+ if content_type:
+ header = "Content-Type: {}\n\n".format ( content_type )
+ if encode:
+ stream.write ( header.encode ( self.TEMPLATE_ENCODING ) )
+ else:
+ stream.write ( header )
+ return True
+ return False
+ # --- end of write_cgi_header (...) ---
+
+ @classmethod
+ def encode ( cls, text ):
+ return str ( text ).encode ( cls.TEMPLATE_ENCODING )
+ # --- end of encode (...) ---
+
+ @classmethod
+ def decode ( cls, data, force=False ):
+ if force or not isinstance ( data, str ):
+ return data.decode ( cls.TEMPLATE_ENCODING )
+ else:
+ return str ( data )
+ # --- end of decode (...) ---
+
+# --- end of StatusRuntimeEnvironment ---
+
+
+def main_installed ( *args, **kwargs ):
+ return main ( True, *args, **kwargs )
+# --- end of main_installed (...) ---
+
+def main ( installed, *args, **kw ):
+ main_env = StatusRuntimeEnvironment ( installed, *args, **kw )
+ main_env.setup()
+
+ output_encoded = main_env.serve_template()
+
+ if main_env.outfile:
+ with open (
+ main_env.outfile,
+ 'w' + ( 'b' if not isinstance ( output, str ) else 't' )
+ ) as FH:
+ # COULDFIX: write cgi header to file?
+ #main_env.write_cgi_header ( FH, encode=True )
+ FH.write ( output_encoded )
+ else:
+ output = main_env.decode ( output_encoded )
+ main_env.write_cgi_header ( sys.stdout, force=True )
+ sys.stdout.write ( output )
+# --- end of main (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-14 14:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-14 14:56 UTC (permalink / raw
To: gentoo-commits
commit: 58094496a2b1393988a81f297ef62e3db4612937
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 13 12:07:29 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 13 12:07:29 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=58094496
roverlay/status: smart(er) template file lookup
automatically append file extensions when searching for the template file,
depending on the script mode ('.html' for cgi, '.txt' for cli).
---
roverlay/argparser.py | 7 ++---
roverlay/status.py | 80 ++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 72 insertions(+), 15 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 84e1478..a01d1c9 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -523,7 +523,7 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
# --- end of setup_actions (...) ---
def parse_actions ( self ):
- command = self.parsed ['command']
+ self.command = self.parsed ['command']
# --- end of parse_actions (...) ---
# --- end of RoverlayArgumentParser ---
@@ -583,9 +583,8 @@ class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
arg (
'-t', '--template', dest='template', default=argparse.SUPPRESS,
- flags=self.ARG_WITH_DEFAULT|self.ARG_META_FILE,
- type=is_fs_file,
- help='template file for generating output',
+ flags=self.ARG_ADD_DEFAULT, metavar='<file|name>',
+ help='template file or name for generating output',
)
arg (
diff --git a/roverlay/status.py b/roverlay/status.py
index 7872674..56a2d61 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -5,7 +5,6 @@
# either version 2 of the License, or (at your option) any later version.
from __future__ import print_function
-#from __future__ import division
import os
import sys
@@ -39,6 +38,14 @@ class ReferenceableDict ( dict ):
return sorted ( self.items(), key=lambda kv: keysort ( kv[0] ) )
# --- end of sorted_items (...) ---
+ def sorted_env_vars ( self, keysort=None ):
+ # return list with "scalar" types only
+ return list (
+ kv for kv in self.sorted_items ( keysort=keysort )
+ if isinstance ( kv[1], ( str, int, float ) )
+ )
+ # --- end of sorted_env_vars (...) ---
+
# --- end of ReferenceableDict ---
class SelfReferencingDict ( ReferenceableDict ):
@@ -69,6 +76,11 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
TEMPLATE_ENCODING = 'utf-8'
+ SCRIPT_MODE_FILE_EXT = {
+ 'cgi': '.html',
+ 'cli': '.txt',
+ }
+
# variables from /etc/nginx/fastcgi.conf
# (will be kept in template env dict depending on script mode)
#
@@ -137,16 +149,22 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
def do_setup_mako ( self ):
template_dirs = []
+ self.default_template = self.script_mode
if 'template' in self.options:
- dirname, basename = os.path.split (
+ # not ideal, but should suffice
+ # otherwise, introduce a --template-name arg
+ #
+ fspath = os.path.abspath (
self.options ['template'].rstrip ( os.sep )
)
- assert dirname and basename
- template_dirs.append ( dirname )
- self.default_template = basename
- else:
- self.default_template = self.script_mode
+ if os.path.isfile ( fspath ):
+ dirname, basename = os.path.split ( fspath )
+ assert dirname and basename
+ template_dirs.append ( dirname )
+ self.default_template = basename
+ else:
+ self.default_template = self.options ['template']
# -- end if
if self.installed:
@@ -172,6 +190,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
self._mako_lookup = mako.lookup.TemplateLookup (
directories=template_dirs, module_directory=module_dir,
output_encoding=self.TEMPLATE_ENCODING,
+ #future_imports=[ 'print_function', 'division', ],
)
# --- end of do_setup_mako (...) ---
@@ -187,6 +206,8 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
roverlay.tools.shenv.setup_env()
)
roverlay.tools.shenv.restore_msg_vars ( self.template_vars )
+ #self.template_vars ['ROVERLAY_PHASE'] = 'status_' + self.command
+ self.template_vars ['ROVERLAY_PHASE'] = 'status'
try:
del self.template_vars ['STATS_DB']
@@ -235,12 +256,42 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
self.do_setup_mako()
# --- end of do_setup (...) ---
- def serve_template ( self, template_name=None, catch_exceptions=True ):
+ def serve_template ( self,
+ template_name = None,
+ file_extensions = [ '', '.mako', '.tmpl' ],
+ append_mode_ext = True,
+ catch_exceptions = True,
+ ):
try:
- my_template = self._mako_lookup.get_template (
+ my_template_name = (
template_name if template_name is not None
else self.default_template
)
+
+ if append_mode_ext:
+ fext_list = list ( file_extensions )
+ fext_list.append ( self.get_script_mode_file_ext() )
+ else:
+ fext_list = file_extensions
+
+ # TODO/FIXME: does TemplateLookup support file extension_s_ lookup?
+ last_fext_index = len ( fext_list ) - 1
+ for index, f_ext in enumerate ( fext_list ):
+ if index == last_fext_index:
+ my_template = self._mako_lookup.get_template (
+ my_template_name + f_ext
+ )
+ else:
+ try:
+ my_template = self._mako_lookup.get_template (
+ my_template_name + f_ext
+ )
+ except mako.exceptions.TopLevelLookupException:
+ pass
+ else:
+ break
+ # -- end if
+
ret = my_template.render ( **self.template_vars )
except:
if catch_exceptions:
@@ -286,6 +337,12 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
return str ( data )
# --- end of decode (...) ---
+ def get_script_mode_file_ext ( self ):
+ return self.SCRIPT_MODE_FILE_EXT.get (
+ self.script_mode, ( '.' + self.script_mode )
+ )
+ # --- end of get_script_mode_file_ext (...) ---
+
# --- end of StatusRuntimeEnvironment ---
@@ -294,6 +351,7 @@ def main_installed ( *args, **kwargs ):
# --- end of main_installed (...) ---
def main ( installed, *args, **kw ):
+
main_env = StatusRuntimeEnvironment ( installed, *args, **kw )
main_env.setup()
@@ -308,7 +366,7 @@ def main ( installed, *args, **kw ):
#main_env.write_cgi_header ( FH, encode=True )
FH.write ( output_encoded )
else:
- output = main_env.decode ( output_encoded )
- main_env.write_cgi_header ( sys.stdout, force=True )
+ output = main_env.decode ( output_encoded ).lstrip ( '\n' )
+ main_env.write_cgi_header ( sys.stdout )
sys.stdout.write ( output )
# --- end of main (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-14 14:56 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-14 14:56 UTC (permalink / raw
To: gentoo-commits
commit: 4827a57fe083426e9d0c9c4637f9ae551565edd1
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 14 14:54:59 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 14 14:55:13 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4827a57f
roverlay/status: graph creation example
---
roverlay/status.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 62 insertions(+), 4 deletions(-)
diff --git a/roverlay/status.py b/roverlay/status.py
index 56a2d61..5e68301 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -25,6 +25,9 @@ import roverlay.tools.shenv
import roverlay.db.rrdtool
import roverlay.util.common
+# temporary import
+import roverlay.db.rrdgraph
+
class ReferenceableDict ( dict ):
def ref ( self ):
@@ -149,7 +152,8 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
def do_setup_mako ( self ):
template_dirs = []
- self.default_template = self.script_mode
+ if not getattr ( self, 'default_template', None ):
+ self.default_template = self.script_mode
if 'template' in self.options:
# not ideal, but should suffice
@@ -190,7 +194,6 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
self._mako_lookup = mako.lookup.TemplateLookup (
directories=template_dirs, module_directory=module_dir,
output_encoding=self.TEMPLATE_ENCODING,
- #future_imports=[ 'print_function', 'division', ],
)
# --- end of do_setup_mako (...) ---
@@ -232,15 +235,24 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
),
CGI_FORM=cgi.FieldStorage( keep_blank_values=0 ),
)
+ # TODO (maybe):
+ # set default_template depending on CGI_FORM
+ #
+ # -- end if
- self.stats_db = None
- stats_db_file = self.config.get ( 'RRD_DB.file', None )
+ self.stats_db = None
+ self.graph_factory = None
+ stats_db_file = self.config.get ( 'RRD_DB.file', None )
if stats_db_file:
self.stats_db = roverlay.db.rrdtool.RRD (
stats_db_file, readonly=True
)
self.stats_db.make_cache()
+ self.graph_factory = roverlay.db.rrdgraph.RRDGraphFactory (
+ rrd_db=self.stats_db,
+ )
+ # -- end if
# transfer db cache to template_vars
@@ -345,6 +357,50 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
# --- end of StatusRuntimeEnvironment ---
+def graph_example ( main_env, dump_file="/tmp/roverlay_graph.png" ):
+ """graph creation - work in progress"""
+
+ graph = main_env.graph_factory.get_new()
+ graph.title = "R_Overlay"
+ graph.colors = [
+ # colors from munin (Munin::Master::GraphOld[.pm])
+ 'BACK#F0F0F0', # Area around the graph
+ 'FRAME#F0F0F0', # Line around legend spot
+ 'CANVAS#FFFFFF', # Graph background, max contrast
+ 'FONT#666666', # Some kind of gray
+ 'AXIS#CFD6F8', # And axis like html boxes
+ 'ARROW#CFD6F8', # And arrow, ditto.
+ ]
+
+ graph.end = "now"
+ graph.start = "end-" + str ( graph.SECONDS_DAY/4 ) + "s"
+ graph.extra_options.extend ((
+ '--width', '400', '--border', '0',
+ '--font', 'DEFAULT:0:DejaVuSans,DejaVu Sans,DejaVu LGC Sans,Bitstream Vera Sans',
+ '--font', 'LEGEND:7:DejaVuSansMono,DejaVu Sans Mono,DejaVu LGC Sans Mono,Bitstream Vera Sans Mono,monospace',
+
+ ))
+
+ graph.add_def ( "pkg_success", "pc_success", "LAST" )
+ graph.add_def ( "pkg_fail", "pc_fail", "LAST" )
+
+ graph.add_vdef ( "pkg_success_max", "pkg_success,MAXIMUM" )
+ graph.add_vdef ( "pkg_fail_max", "pkg_fail,MAXIMUM" )
+
+ graph.add_line ( "pkg_success", "blue", width=4, legend="pkg success" )
+ graph.add_print ( "pkg_success_max", "%.2lf %S\l", inline=True )
+
+ graph.add_line ( "pkg_fail", "red", width=4, legend="pkg fail " )
+ graph.add_print ( "pkg_fail_max", "%.2lf %S\l", inline=True )
+
+ graph.make()
+
+ image = graph.get_image()
+ if image:
+ with open ( dump_file, 'wb' ) as FH:
+ FH.write ( graph.get_image() )
+
+# --- end of graph_example (...) ---
def main_installed ( *args, **kwargs ):
return main ( True, *args, **kwargs )
@@ -355,6 +411,8 @@ def main ( installed, *args, **kw ):
main_env = StatusRuntimeEnvironment ( installed, *args, **kw )
main_env.setup()
+ #graph_example ( main_env )
+
output_encoded = main_env.serve_template()
if main_env.outfile:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-16 10:43 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-16 10:43 UTC (permalink / raw
To: gentoo-commits
commit: 818bfa863c7da84c37fc45871c84c5dbe67ac9af
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 16 10:18:58 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 16 10:18:58 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=818bfa86
roverlay/argparser, status scritp: add 'html' mode
Similar to the 'cgi' mode, but doesn't print the "Content-Type: ..." header.
---
roverlay/argparser.py | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index a01d1c9..7b7d9e9 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -544,7 +544,7 @@ class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
}
DEFAULT_COMMAND = 'status'
- MODES = frozenset ({ 'cgi', 'cli' })
+ MODES = ( 'cli', 'cgi', 'html', )
DEFAULT_MODE = 'cli'
def setup_script_mode ( self ):
@@ -588,11 +588,18 @@ class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
)
arg (
- '--cgi-content-type', dest='cgi_content_type', default="text/html",
+ '-T', '--cgi-content-type', dest='cgi_content_type',
+ default="text/html",
flags=self.ARG_WITH_DEFAULT, metavar='<type>',
help='cgi content type',
)
+## arg (
+## '-o', '--template-options', dest='template_options',
+## metavar='<option>', action='append',
+## help='pass arbitrary options to templates',
+## )
+
return arg
# --- end of setup_output_options (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-16 10:43 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-16 10:43 UTC (permalink / raw
To: gentoo-commits
commit: b6c49313277e4685bc63c1b8f1c5983253b19d66
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 16 10:24:24 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 16 10:26:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b6c49313
roverlay/status: use stats rating
Other change:
* some example_graph() experiments
* moved "find template" functionality from serve_template() to get_template()
* TODO notes (RRA creation,UNKNOWNS)
* write mako modules to python-version specific subdirectories
---
roverlay/status.py | 169 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 114 insertions(+), 55 deletions(-)
diff --git a/roverlay/status.py b/roverlay/status.py
index 5e68301..2a80977 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -4,6 +4,11 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
+# --- TODO/FIXME ---
+# * what happens if the database has UNKNOWNS?
+# * RRA creation doesn't seem to be correct
+#
+
from __future__ import print_function
import os
@@ -24,11 +29,32 @@ import roverlay.runtime
import roverlay.tools.shenv
import roverlay.db.rrdtool
import roverlay.util.common
+import roverlay.stats.rating
# temporary import
import roverlay.db.rrdgraph
+class DBStats ( roverlay.stats.rating.RoverlayNumStatsRating ):
+
+ def __init__ ( self, db_cache, description=None ):
+ super ( DBStats, self ).__init__ (
+ db_cache['values'], description=description
+ )
+ self.lastupdate = db_cache['lastupdate']
+ self.suggestions = None
+ # --- end of __init__ (...) ---
+
+ def make_suggestions ( self, pure_text=False ):
+ self.suggestions = list ( self.get_suggestions ( pure_text=pure_text ) )
+ return bool ( self.suggestions )
+ # --- end of __init__ (...) ---
+
+# --- end of DBStats ---
+
+
+
+
class ReferenceableDict ( dict ):
def ref ( self ):
return weakref.ref ( self )
@@ -80,8 +106,9 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
TEMPLATE_ENCODING = 'utf-8'
SCRIPT_MODE_FILE_EXT = {
- 'cgi': '.html',
- 'cli': '.txt',
+ 'cli' : '.txt',
+ 'cgi' : '.html',
+ 'html': '.html',
}
# variables from /etc/nginx/fastcgi.conf
@@ -152,8 +179,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
def do_setup_mako ( self ):
template_dirs = []
- if not getattr ( self, 'default_template', None ):
- self.default_template = self.script_mode
+ self.default_template = 'status'
if 'template' in self.options:
# not ideal, but should suffice
@@ -190,6 +216,14 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
if module_dir:
module_dir += os.sep + 'mako_templates'
+ # use per-version module dirs
+ # modules generated with python2.7 are not compatible with python3.2
+ if module_dir:
+ module_dir += ( os.sep +
+ 'python_' + '.'.join ( map ( str, sys.version_info[:2] ) )
+ )
+ # 'python_' + hex ( sys.hexversion>>16 )
+
self._mako_lookup = mako.lookup.TemplateLookup (
directories=template_dirs, module_directory=module_dir,
@@ -222,10 +256,11 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
if self.outfile == '-':
self.outfile = None
- self.set_template_vars (
- EXE=sys.argv[0], EXE_NAME=os.path.basename ( sys.argv[0] ),
- SCRIPT_MODE=script_mode
- )
+ self.template_vars ['EXE'] = sys.argv[0]
+ self.template_vars ['EXE_NAME'] = os.path.basename ( sys.argv[0] )
+ self.template_vars ['SCRIPT_MODE'] = script_mode
+
+
if script_mode == 'cgi':
# inherit cgi-related vars from os.environ
@@ -244,6 +279,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
self.stats_db = None
self.graph_factory = None
stats_db_file = self.config.get ( 'RRD_DB.file', None )
+
if stats_db_file:
self.stats_db = roverlay.db.rrdtool.RRD (
stats_db_file, readonly=True
@@ -252,62 +288,74 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
self.graph_factory = roverlay.db.rrdgraph.RRDGraphFactory (
rrd_db=self.stats_db,
)
- # -- end if
- # transfer db cache to template_vars
- # * copy lastupdate
- # * import values
- #
- self.set_template_vars (
- self.stats_db.cache ['values'],
- lastupdate=self.stats_db.cache ['lastupdate'],
- STATS_DB=self.stats_db, STATS_DB_FILE=stats_db_file,
- )
+ # transfer db cache to template_vars
+ # * copy lastupdate
+ # * import values
+ #
+ self.set_template_vars (
+ self.stats_db.cache ['values'],
+ lastupdate=self.stats_db.cache ['lastupdate'],
+ STATS_DB_FILE=stats_db_file,
+ STATS_DB=DBStats ( self.stats_db.cache ),
+ )
+
+ # -- end if
self.do_setup_mako()
# --- end of do_setup (...) ---
- def serve_template ( self,
- template_name = None,
- file_extensions = [ '', '.mako', '.tmpl' ],
- append_mode_ext = True,
- catch_exceptions = True,
+ def get_template ( self,
+ template_name,
+ file_extensions=[ '', ],
+ add_mode_ext=True
):
- try:
- my_template_name = (
- template_name if template_name is not None
- else self.default_template
- )
+ my_template = None
- if append_mode_ext:
- fext_list = list ( file_extensions )
- fext_list.append ( self.get_script_mode_file_ext() )
+ if add_mode_ext:
+ fext_list = (
+ [ self.get_script_mode_file_ext() ] + list ( file_extensions )
+ )
+ else:
+ fext_list = file_extensions
+
+ # TODO/FIXME: does TemplateLookup support file extension_s_ lookup?
+ last_fext_index = len ( fext_list ) - 1
+ for index, f_ext in enumerate ( fext_list ):
+ if index == last_fext_index:
+ my_template = self._mako_lookup.get_template (
+ template_name + f_ext
+ )
else:
- fext_list = file_extensions
-
- # TODO/FIXME: does TemplateLookup support file extension_s_ lookup?
- last_fext_index = len ( fext_list ) - 1
- for index, f_ext in enumerate ( fext_list ):
- if index == last_fext_index:
+ try:
my_template = self._mako_lookup.get_template (
- my_template_name + f_ext
+ template_name + f_ext
)
+ except mako.exceptions.TopLevelLookupException:
+ pass
else:
- try:
- my_template = self._mako_lookup.get_template (
- my_template_name + f_ext
- )
- except mako.exceptions.TopLevelLookupException:
- pass
- else:
- break
- # -- end if
+ break
+ # -- end if
+ return my_template
+ # --- end of get_template (...) ---
+
+ def serve_template ( self,
+ template_name=None, catch_exceptions=True, lookup_kwargs={}
+ ):
+ try:
+ my_template = self.get_template (
+ template_name=(
+ template_name if template_name is not None
+ else self.default_template
+ ),
+ **lookup_kwargs
+ )
ret = my_template.render ( **self.template_vars )
except:
if catch_exceptions:
- if self.script_mode == 'cgi':
+ if self.script_mode in { 'cgi', 'html' }:
ret = mako.exceptions.html_error_template().render()
else:
ret = mako.exceptions.text_error_template().render()
@@ -373,7 +421,7 @@ def graph_example ( main_env, dump_file="/tmp/roverlay_graph.png" ):
]
graph.end = "now"
- graph.start = "end-" + str ( graph.SECONDS_DAY/4 ) + "s"
+ graph.start = "end-" + str ( graph.SECONDS_DAY//4 ) + "s"
graph.extra_options.extend ((
'--width', '400', '--border', '0',
'--font', 'DEFAULT:0:DejaVuSans,DejaVu Sans,DejaVu LGC Sans,Bitstream Vera Sans',
@@ -381,17 +429,28 @@ def graph_example ( main_env, dump_file="/tmp/roverlay_graph.png" ):
))
- graph.add_def ( "pkg_success", "pc_success", "LAST" )
- graph.add_def ( "pkg_fail", "pc_fail", "LAST" )
+ graph.add_def ( "pkg_success", "pc_success", "MAX" )
+ graph.add_def ( "pkg_fail", "pc_fail", "MAX" )
graph.add_vdef ( "pkg_success_max", "pkg_success,MAXIMUM" )
+ graph.add_vdef ( "pkg_success_min", "pkg_success,MINIMUM" )
graph.add_vdef ( "pkg_fail_max", "pkg_fail,MAXIMUM" )
+ graph.add_vdef ( "pkg_fail_min", "pkg_fail,MINIMUM" )
+
+ graph.add_arg ( "COMMENT: " )
+ graph.add_arg ( "COMMENT: min " )
+ graph.add_arg ( "COMMENT: max\l" )
+
+ graph.add_line ( "pkg_success", "blue", width=1, legend="pkg success" )
+ graph.add_print ( "pkg_success_min", "%7.0lf %S", inline=True )
+ graph.add_print ( "pkg_success_max", "%7.0lf %S\l", inline=True )
+
- graph.add_line ( "pkg_success", "blue", width=4, legend="pkg success" )
- graph.add_print ( "pkg_success_max", "%.2lf %S\l", inline=True )
- graph.add_line ( "pkg_fail", "red", width=4, legend="pkg fail " )
- graph.add_print ( "pkg_fail_max", "%.2lf %S\l", inline=True )
+ #graph.add_line ( "pkg_fail", "red", width=1, legend="pkg fail " )
+ graph.add_area ( "pkg_fail", "red", legend="pkg fail " )
+ graph.add_print ( "pkg_fail_min", "%7.0lf %S", inline=True )
+ graph.add_print ( "pkg_fail_max", "%7.0lf %S\l", inline=True )
graph.make()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-16 11:02 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-16 11:02 UTC (permalink / raw
To: gentoo-commits
commit: faadf46ac9cbd3927498d68ea15c306b808f82b3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 16 11:01:45 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 16 11:01:45 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=faadf46a
roverlay/status: fix mako templates location
... when installed
---
roverlay/status.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/roverlay/status.py b/roverlay/status.py
index 2a80977..617aaab 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -200,6 +200,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
if self.installed:
template_dirs.append (
self.config.get_or_fail ( 'INSTALLINFO.libexec' )
+ + os.sep + 'mako_templates'
)
extra_dirs = self.config.get ( 'STATS.TEMPLATE.root' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-16 14:05 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-16 14:05 UTC (permalink / raw
To: gentoo-commits
commit: 83298a990357b3511dcd32b23fa4f4e446f4c79c
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 16 14:05:01 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 16 14:05:01 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=83298a99
status script: accept --module-root arg
This allows to use another user's config file when running in cgi mode.
---
roverlay/argparser.py | 7 +++++++
roverlay/status.py | 14 +++++++++-----
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 7b7d9e9..0a73c9b 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -594,6 +594,13 @@ class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
help='cgi content type',
)
+ arg (
+ '-M', '--module-root', dest='module_root',
+ default=argparse.SUPPRESS, metavar="<dir>",
+ type=couldbe_fs_dir,
+ help="directory for storing cached templates",
+ )
+
## arg (
## '-o', '--template-options', dest='template_options',
## metavar='<option>', action='append',
diff --git a/roverlay/status.py b/roverlay/status.py
index 617aaab..59c8cb6 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -211,11 +211,15 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
raise Exception ( "no template directories found!" )
- module_dir = self.config.get ( 'STATS.TEMPLATE.module_dir', None )
- if module_dir is None:
- module_dir = self.config.get ( 'CACHEDIR.root', None )
- if module_dir:
- module_dir += os.sep + 'mako_templates'
+
+ if 'module_root' in self.options:
+ module_dir = self.options ['module_root']
+ else:
+ module_dir = self.config.get ( 'STATS.TEMPLATE.module_dir', None )
+ if module_dir is None:
+ module_dir = self.config.get ( 'CACHEDIR.root', None )
+ if module_dir:
+ module_dir += os.sep + 'mako_templates'
# use per-version module dirs
# modules generated with python2.7 are not compatible with python3.2
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-19 15:42 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-19 15:42 UTC (permalink / raw
To: gentoo-commits
commit: bff3c7b545fb172c1c602a9a8ce7c027a497b151
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 19 15:22:08 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 19 15:22:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=bff3c7b5
roverlay/packageinfo: add repo_name, package_filename_x
---
roverlay/packageinfo.py | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 704807e..78d20c4 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -41,6 +41,7 @@ from roverlay.rpackage import descriptionreader
# * origin -- a package's origin (repository object)
# * package_file -- full fs path to the package file
# * package_filename -- file name (including file extension)
+# * package_filename_x -- file name without file extension
# * package_name -- package name (file name without version, f-ext)
# * physical_only -- bool that indicates whether a package exists as
# ebuild file only (True) or has additional
@@ -99,7 +100,6 @@ class PackageInfo ( object ):
ALWAYS_FALLBACK = frozenset ( ( 'ebuild', 'ebuild_file' ) )
_UPDATE_KEYS_SIMPLE = frozenset ((
- 'origin',
'ebuild',
'ebuild_file',
'imported',
@@ -710,6 +710,10 @@ class PackageInfo ( object ):
if value is not None:
self._info [key] = value
+ elif key == 'origin':
+ self._info ['origin'] = value
+ self._info ['repo_name'] = value.name
+
elif key == 'filename':
self._use_filename ( value )
@@ -792,12 +796,12 @@ class PackageInfo ( object ):
ebuild_name = strutil.fix_ebuild_name ( package_name )
# for DescriptionReader
- self._info ['package_name'] = package_name
-
- self._info ['rev'] = 0
- self._info ['name'] = ebuild_name
- self._info ['ebuild_verstr'] = version_str
- self._info ['package_filename'] = filename_with_ext
+ self._info ['package_name'] = package_name
+ self._info ['rev'] = 0
+ self._info ['name'] = ebuild_name
+ self._info ['ebuild_verstr'] = version_str
+ self._info ['package_filename'] = filename_with_ext
+ self._info ['package_filename_x'] = filename
# --- end of _use_filename (...) ---
def _use_pvr ( self, pvr ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-23 13:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-23 13:52 UTC (permalink / raw
To: gentoo-commits
commit: 2f2f33a397e8fe22cafe701e02ff2d234fbf8758
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 23 11:14:45 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 23 11:14:45 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2f2f33a3
roverlay/core: clean up locate_config_file()
---
roverlay/core.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/roverlay/core.py b/roverlay/core.py
index 8430fd9..2872c48 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -138,7 +138,6 @@ def load_config_file (
def locate_config_file (
ROVERLAY_INSTALLED, CONFIG_FILE_NAME=DEFAULT_CONFIG_FILE_NAME
):
- DEFAULT_CONFIG_FILE = None
# search for the config file if roverlay has been installed
if ROVERLAY_INSTALLED:
cfg = None
@@ -147,14 +146,12 @@ def locate_config_file (
for config_dir in CONFIG_DIRS:
cfg = config_dir + os.sep + CONFIG_FILE_NAME
if os.path.isfile ( cfg ):
- DEFAULT_CONFIG_FILE = cfg
- break
+ return cfg
- del config_dir, cfg
elif os.path.exists ( CONFIG_FILE_NAME ):
- DEFAULT_CONFIG_FILE = CONFIG_FILE_NAME
+ return CONFIG_FILE_NAME
- return DEFAULT_CONFIG_FILE
+ return None
# --- end of locate_config_file (...) ---
def load_locate_config_file (
@@ -181,6 +178,7 @@ def default_helper_setup ( ROVERLAY_INSTALLED, log_to_console=True ):
ROVERLAY_INSTALLED, extraconf={ 'installed': ROVERLAY_INSTALLED, },
setup_logger=False, load_main_only=True,
)
+
roverlay.tools.shenv.setup_env()
return config
# --- end of default_helper_setup (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-23 13:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-23 13:52 UTC (permalink / raw
To: gentoo-commits
commit: d9a1524c308d0da55a7a63316cfc00729c066545
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 23 11:15:07 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 23 11:15:07 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d9a1524c
roverlay/packageinfo: add depconf attribute
This attribute will be used for storing per-package dependency-related
configuration, e.g. for injecting deps.
---
roverlay/packageinfo.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 78d20c4..b4e38f1 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -135,6 +135,7 @@ class PackageInfo ( object ):
self.selfdeps = None
self.hashdict = dict()
+ self.depconf = None
#self.selfdeps_valid = UNDEF
#self.overlay_package_ref = None
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-23 13:52 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-23 13:52 UTC (permalink / raw
To: gentoo-commits
commit: 6250f850bd4f8f9708a66df52b2388ebf1f403ba
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 23 11:24:18 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 23 11:24:18 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6250f850
main script, "apply_rules": show modifed deps
---
roverlay/defaultscript.py | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index 1373ee1..7ab2ad0 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -91,9 +91,16 @@ def run_script_main ( installed ):
if len ( sys.argv ) < 2 or not sys.argv[0]:
die ( "no executable specified.", DIE.USAGE )
+ exe = sys.argv[1]
+ script_file = os.path.abspath ( exe )
+ if os.path.isfile ( script_file ) or os.sep in exe:
+ exe = script_file
+
+ print ( "X___", exe)
+
roverlay.core.default_helper_setup ( installed )
roverlay.tools.shenv.run_script_exec (
- sys.argv[1], "runscript", sys.argv[1:], use_path=True
+ exe, "runscript", sys.argv[1:], use_path=True
)
# --- end of run_script_main (...) ---
@@ -384,6 +391,24 @@ def run_apply_package_rules ( env ):
for evar in evars:
FH.write ( "* {}\n".format ( evar ) )
+ if P.depconf:
+ FH.write ( "dependencies manipulated:\n" )
+ for root_key, subdict in P.depconf.items():
+ if subdict:
+ klen = max ( len(s) for s in subdict.keys() )
+
+ FH.write ( "* {k}\n".format ( k=root_key ) )
+ for key, deplist in sorted (
+ subdict.items(), key=( lambda kv: kv[0] ),
+ ):
+ for dep in deplist:
+ FH.write (
+ " {key:<{l}} += \"{dep}\"\n".format (
+ key=key, dep=dep, l=klen
+ )
+ )
+
+
if P.modified_by_package_rules is not True:
# ^ check needs to be changed when adding more trace actions
FH.write ( "trace marks:\n" )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-27 15:39 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-27 15:39 UTC (permalink / raw
To: gentoo-commits
commit: 2a921c0056de70e4a05169cc7d599b809ede3dd6
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Aug 27 15:29:26 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Aug 27 15:29:26 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2a921c00
roverlay/status.py: some comments
---
roverlay/status.py | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/roverlay/status.py b/roverlay/status.py
index 59c8cb6..595e8fb 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -5,7 +5,6 @@
# either version 2 of the License, or (at your option) any later version.
# --- TODO/FIXME ---
-# * what happens if the database has UNKNOWNS?
# * RRA creation doesn't seem to be correct
#
@@ -46,6 +45,28 @@ class DBStats ( roverlay.stats.rating.RoverlayNumStatsRating ):
# --- end of __init__ (...) ---
def make_suggestions ( self, pure_text=False ):
+ """Creates a list of 2-tuples ( <topic>, list<details> ) with
+ suggestions and stores it as self.suggestions.
+
+ List example:
+ [
+ (
+ "normal/expected failure rate",
+ [
+ "write dependency rules",
+ "configure package ignore rules",
+ ]
+ ),
+ (
+ ...
+ ),
+ ]
+
+ arguments:
+ * pure_text -- disable html tags
+
+ Returns: True if any suggestions available, else False.
+ """
self.suggestions = list ( self.get_suggestions ( pure_text=pure_text ) )
return bool ( self.suggestions )
# --- end of __init__ (...) ---
@@ -53,9 +74,8 @@ class DBStats ( roverlay.stats.rating.RoverlayNumStatsRating ):
# --- end of DBStats ---
-
-
class ReferenceableDict ( dict ):
+
def ref ( self ):
return weakref.ref ( self )
# --- end of ref (...) ---
@@ -178,6 +198,9 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
def do_setup_mako ( self ):
+
+
+ # set up template_dirs / default_template
template_dirs = []
self.default_template = 'status'
@@ -211,7 +234,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
raise Exception ( "no template directories found!" )
-
+ # get module root (for caching)
if 'module_root' in self.options:
module_dir = self.options ['module_root']
else:
@@ -230,6 +253,7 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
# 'python_' + hex ( sys.hexversion>>16 )
+ # create lookup object
self._mako_lookup = mako.lookup.TemplateLookup (
directories=template_dirs, module_directory=module_dir,
output_encoding=self.TEMPLATE_ENCODING,
@@ -316,6 +340,20 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
file_extensions=[ '', ],
add_mode_ext=True
):
+ """Tries to find a template.
+
+ arguments:
+ * template_name -- name of the template
+ * file_extensions -- an iterable containing possible file extensions,
+ in order
+ * add_mode_ext -- whether to try script_mode-specific file extension
+ first (Defaults to True).
+
+ Returns: a Template object
+
+ Raises:
+ * Passes mako.exceptions.TopLevelLookupException if template not found
+ """
my_template = None
if add_mode_ext:
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-28 15:54 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-28 15:54 UTC (permalink / raw
To: gentoo-commits
commit: 9db31e67bd33d0486a3499063a4cc0830efb7759
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Aug 28 15:51:02 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Aug 28 15:51:02 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9db31e67
packageinfo: create_vartable()
creates a dict with variables like P, PN, PF, ... for "parsing" ebuilds.
---
roverlay/packageinfo.py | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index b4e38f1..a3be89b 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -861,6 +861,23 @@ class PackageInfo ( object ):
self._use_filename ( os.path.basename ( filepath ) )
# --- end of _use_filepath (...) ---
+ def create_vartable ( self, category ):
+ PN = self._info ['name']
+ PV = str ( self._info ['version'] )
+ PR = str ( self._info ['rev'] )
+ PVR = PV if PR == '0' else ( PV + '-' + PR )
+
+ return {
+ 'P' : PN + '-' + PV,
+ 'PN' : PN,
+ 'PV' : PV,
+ 'PR' : PR,
+ 'PVR' : PVR,
+ 'PF' : PN + PVR,
+ 'CATEGORY' : category,
+ }
+ # --- end of create_vartable (...) ---
+
def __str__ ( self ):
return "<PackageInfo for {pkg}>".format (
pkg=self.get (
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-29 12:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-29 12:36 UTC (permalink / raw
To: gentoo-commits
commit: 6778dcf7eff2adc62e616c8ae998ac9e74298c6f
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 29 12:30:15 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 29 12:30:15 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6778dcf7
packageinfo: parse SRC_URI, get status view object
---
roverlay/packageinfo.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index a3be89b..e991ed7 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -17,9 +17,12 @@ import re
import os.path
import logging
+
import roverlay.digest
import roverlay.versiontuple
import roverlay.db.distmap
+import roverlay.util.objects
+import roverlay.util.ebuildparser
from roverlay import config, strutil
from roverlay.rpackage import descriptionreader
@@ -66,7 +69,28 @@ from roverlay.rpackage import descriptionreader
LOGGER = logging.getLogger ( 'PackageInfo' )
-class PackageInfo ( object ):
+
+class PackageInfoStatus ( roverlay.util.objects.ObjectView ):
+
+ def __init__ ( self, package_info ):
+ super ( PackageInfoStatus, self ).__init__ ( package_info )
+ self.has_ebuild_file = False
+ # --- end of __init__ (...) ---
+
+ def get_name ( self ):
+ return self.deref_safe().get ( 'name' )
+ # --- end of get_name (...) ---
+
+ def update ( self ):
+ self.has_ebuild_file = bool (
+ self.deref_safe().get ( 'ebuild_file', do_fallback=True )
+ )
+ # --- end of update (...) ---
+
+# --- end of PackageInfoStatus ---
+
+
+class PackageInfo ( roverlay.util.objects.Referenceable ):
"""PackageInfo offers easy, subscriptable access to package
information, whether stored or calculated.
@@ -92,6 +116,8 @@ class PackageInfo ( object ):
called.
"""
+ CACHE_REF = True
+
EBUILDVER_REGEX = re.compile ( '[-]{1,}' )
PKGSUFFIX_REGEX = re.compile (
config.get_or_fail ( 'R_PACKAGE.suffix_regex' ) + '$'
@@ -128,6 +154,8 @@ class PackageInfo ( object ):
arguments:
* **initial_info -- passed to update ( **kw )
"""
+ super ( PackageInfo, self ).__init__()
+
self._info = dict()
self.readonly = False
self.logger = LOGGER
@@ -188,6 +216,12 @@ class PackageInfo ( object ):
return v
# --- end of has_valid_selfdeps (...) ---
+ def get_status_object ( self ):
+ obj = PackageInfoStatus ( self )
+ obj.update()
+ return obj
+ # --- end of get_status_object (...) ---
+
def attach_lazy_action ( self, lazy_action ):
"""Attaches a lazy action.
Unsafe operation (no locks will be acquired etc.).
@@ -684,6 +718,18 @@ class PackageInfo ( object ):
self._evars [evar.get_pseudo_hash()] = evar
# --- end of add_evar (...) ---
+ def parse_ebuild_src_uri ( self, category_name ):
+ return roverlay.util.ebuildparser.SrcUriParser.from_file (
+ self._info ['ebuild_file'], self.create_vartable ( category_name )
+ )
+ # --- end of parse_ebuild_src_uri (...) ---
+
+ def parse_ebuild_distfiles ( self, category_name ):
+ parser = self.parse_ebuild_src_uri ( category_name )
+ for distfile in parser.iter_local_files():
+ yield distfile
+ # --- end of parse_ebuild_distfiles (...) ---
+
def get_evars ( self ):
"""Returns all ebuild variables."""
if hasattr ( self, '_evars' ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-29 12:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-29 12:36 UTC (permalink / raw
To: gentoo-commits
commit: dd5751a54bdeac73478f58f21ffdcff3d2ea9010
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 29 12:29:27 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 29 12:29:27 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=dd5751a5
roverlay/status, ReferenceableDict: inherit Referenceable
---
roverlay/status.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/roverlay/status.py b/roverlay/status.py
index 595e8fb..7843380 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -28,6 +28,7 @@ import roverlay.runtime
import roverlay.tools.shenv
import roverlay.db.rrdtool
import roverlay.util.common
+import roverlay.util.objects
import roverlay.stats.rating
# temporary import
@@ -74,11 +75,7 @@ class DBStats ( roverlay.stats.rating.RoverlayNumStatsRating ):
# --- end of DBStats ---
-class ReferenceableDict ( dict ):
-
- def ref ( self ):
- return weakref.ref ( self )
- # --- end of ref (...) ---
+class ReferenceableDict ( roverlay.util.objects.Referenceable, dict ):
def sorted_items ( self, keysort=None ):
if keysort is None:
@@ -113,7 +110,7 @@ class SelfReferencingDict ( ReferenceableDict ):
def __init__ ( self, *args, **kwargs ):
super ( SelfReferencingDict, self ).__init__ ( *args, **kwargs )
- self [self.__class__.SELFREF_KEY] = self.ref()
+ self [self.__class__.SELFREF_KEY] = self.get_ref()
# or use __getitem__
# --- end of __init__ (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-30 14:49 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-30 14:49 UTC (permalink / raw
To: gentoo-commits
commit: b2f292197b8d91de553c312c663d897eaa49d41c
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 30 12:52:40 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 30 12:52:40 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b2f29219
break long line
---
roverlay/packageinfo.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index abf0dbb..193fe18 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -561,7 +561,8 @@ class PackageInfo ( roverlay.util.objects.Referenceable ):
def make_distmap_hash ( self ):
"""Creates (and returns) the distmap package file hash."""
- return self.make_hashes ( { self.DISTMAP_DIGEST_TYPE, } ) [self.DISTMAP_DIGEST_TYPE]
+ return self.make_hashes (
+ { self.DISTMAP_DIGEST_TYPE, } ) [self.DISTMAP_DIGEST_TYPE]
# --- end of make_distmap_hash (...) ---
def make_hashes ( self, hashlist ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-08-30 14:49 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-08-30 14:49 UTC (permalink / raw
To: gentoo-commits
commit: 40c50b74eb316072732b7170cd3f3f22997c477b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug 30 12:38:31 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug 30 12:38:31 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=40c50b74
roverlay/packageinfo: rename get_status_{object,view}
---
roverlay/packageinfo.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index e991ed7..abf0dbb 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -216,11 +216,11 @@ class PackageInfo ( roverlay.util.objects.Referenceable ):
return v
# --- end of has_valid_selfdeps (...) ---
- def get_status_object ( self ):
+ def get_status_view ( self ):
obj = PackageInfoStatus ( self )
obj.update()
return obj
- # --- end of get_status_object (...) ---
+ # --- end of get_status_view (...) ---
def attach_lazy_action ( self, lazy_action ):
"""Attaches a lazy action.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-02 8:44 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-02 8:44 UTC (permalink / raw
To: gentoo-commits
commit: c65023a5dc2ac5e77f913910f8e9419f801352f3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep 2 08:41:39 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep 2 08:41:39 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c65023a5
packageinfo: get_src_uri_dest()
identical to get_distmap_key()
---
roverlay/packageinfo.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 43fe4f3..af44450 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -132,6 +132,7 @@ class PackageInfo ( roverlay.util.objects.Referenceable ):
'physical_only',
'src_uri',
'has_suggests',
+ 'src_uri_dest',
))
_UPDATE_KEYS_SIMPLE_INITIAL = frozenset ((
'package_filename', 'name',
@@ -554,10 +555,14 @@ class PackageInfo ( roverlay.util.objects.Referenceable ):
)
# --- end of get_distmap_item (...) ---
- def get_distmap_key ( self ):
- """Returns a key for the distmap."""
+ def get_src_uri_dest ( self ):
+ """Returns a the package's filesystem path relative to the mirror
+ directory."""
return self.get ( "package_src_destpath" )
- # --- end of get_distmap_key (...) ---
+ # --- end of get_src_uri_dest (...) ---
+
+ # which is also the key for distmap entries
+ get_distmap_key = get_src_uri_dest
def get_distmap_value ( self, allow_digest_create=False, no_digest=False ):
"""Returns a data tuple for creating DistMapInfo instances.
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-02 12:27 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-02 12:27 UTC (permalink / raw
To: gentoo-commits
commit: 0f45bb772f6f80766f54f6e18ac3fbef9b7b20d3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep 2 12:25:29 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep 2 12:25:29 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0f45bb77
fix --sync-imports
---
roverlay/argparser.py | 2 +-
roverlay/defaultscript.py | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index def3076..e1ded67 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -415,7 +415,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
arg = self.setup_remote_minimal()
arg (
- '--sync-imports', dest='sync_imports',
+ '--sync-imports', dest='sync_imported', default=argparse.SUPPRESS,
flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
help=(
'allow fetching of source files for imported ebuilds even if '
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index 6e2443c..5f47e39 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -266,6 +266,8 @@ def run_overlay_create ( env ):
ebuild_import_nosync = env.option ( 'sync_imported' )
if ebuild_import_nosync is None:
ebuild_import_nosync = env.config.get_or_fail ( 'nosync' )
+ else:
+ ebuild_import_nosync = not ebuild_import_nosync
overlay_creator.overlay.import_ebuilds (
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-03 15:50 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-03 15:50 UTC (permalink / raw
To: gentoo-commits
commit: 1777b3476fa5ccd8c97d74f79b178debf0bb5ad7
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 3 15:43:29 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 3 15:43:29 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1777b347
packageinfo, parse_ebuild_distfiles(): accept kwargs
---
roverlay/packageinfo.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index af44450..fb7b996 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -740,9 +740,9 @@ class PackageInfo ( roverlay.util.objects.Referenceable ):
)
# --- end of parse_ebuild_src_uri (...) ---
- def parse_ebuild_distfiles ( self, category_name ):
+ def parse_ebuild_distfiles ( self, category_name, **kw ):
parser = self.parse_ebuild_src_uri ( category_name )
- for distfile in parser.iter_local_files():
+ for distfile in parser.iter_local_files ( **kw ):
yield distfile
# --- end of parse_ebuild_distfiles (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-06 17:27 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-06 17:27 UTC (permalink / raw
To: gentoo-commits
commit: fba66f36ad0cad176d7b024880d92d2693058800
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 6 17:24:28 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 6 17:24:28 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=fba66f36
roverlay/runtime: IndependentRuntimeEnvironment
env for scripts that are independent of roverlay's core functionality.
This allows to add a setup script that handles config file creation (already
implemented as roverlay-mkconfig), config initialization (fs layout and what's
currently done by pkg_config() in the live ebuild, but more controlled)
and enabling/disabling hooks.
---
roverlay/runtime.py | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 122 insertions(+), 3 deletions(-)
diff --git a/roverlay/runtime.py b/roverlay/runtime.py
index de20f91..bbc73d7 100644
--- a/roverlay/runtime.py
+++ b/roverlay/runtime.py
@@ -14,10 +14,54 @@ import roverlay.core
import roverlay.hook
import roverlay.remote.repolist
import roverlay.stats.collector
+import roverlay.util.objects
+import roverlay.recipe.easylogger
from roverlay.core import DIE, die
-class RuntimeEnvironmentBase ( object ):
+# TODO: move/merge roverlay.core.DIE into runtime env
+
+
+class MinimalRuntimeEnvironment ( object ):
+
+ HLINE = 79 * '-'
+
+ def __init__ ( self ):
+ super ( MinimalRuntimeEnvironment, self ).__init__()
+ self.logger = None
+ self.bind_logger ( logging.getLogger() )
+ # -- end of __init__ (...) ---
+
+ def bind_logger ( self, logger ):
+ self.logger = logger
+ self.log_debug = logger.debug
+ self.log_info = logger.info
+ self.log_warn = logger.warn
+ self.log_warning = logger.warning
+ self.log_error = logger.error
+ self.log_critical = logger.critical
+ # --- end of bind_logger (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def setup ( self ):
+ pass
+
+ def die ( self, msg=None, code=None ):
+ """
+ Calls syst.exit (code:=1) after printing a message (if any).
+ """
+ code = 1 if code is None else code
+ if msg is not None:
+ sys.stderr.write ( msg + "\n" )
+# else:
+# sys.stderr.write ( "died.\n" )
+ sys.exit ( code )
+ # --- end of die (...) ---
+
+# --- end of MinimalRuntimeEnvironment ---
+
+
+class RuntimeEnvironmentBase ( MinimalRuntimeEnvironment ):
ARG_PARSER_CLS = None
KEEP_ARG_PARSER = False
@@ -28,11 +72,9 @@ class RuntimeEnvironmentBase ( object ):
config_file_name=roverlay.core.DEFAULT_CONFIG_FILE_NAME
):
super ( RuntimeEnvironmentBase, self ).__init__()
- self.logger = logging.getLogger()
self.installed = bool ( installed )
self.hide_exceptions = bool ( hide_exceptions )
self.config_file_name = str ( config_file_name )
- self.HLINE = 79 * '-'
self.stats = roverlay.stats.collector.static
self.config = None
@@ -220,3 +262,80 @@ class RuntimeEnvironment ( RuntimeEnvironmentBase ):
# --- end of optionally (...) ---
# --- end of RuntimeEnvironment ---
+
+
+class IndependentRuntimeEnvironment ( MinimalRuntimeEnvironment ):
+
+ LOG_FORMAT = None
+
+ def __init__ ( self, installed=True ):
+ super ( IndependentRuntimeEnvironment, self ).__init__()
+ self.config = roverlay.config.tree.ConfigTree ( register_static=False )
+
+ self.CONFIG_DEFAULTS = { 'installed': installed, }
+ self.extend_config ( self.CONFIG_DEFAULTS )
+
+ self.parser = None
+ self.options = None
+ self.commands = None
+ # --- end of __init__ (...) ---
+
+ def extend_config ( self, additional_config ):
+ self.config.merge_with ( additional_config )
+ # --- end of extend_config (...) ---
+
+ def reset_config ( self ):
+ self.config.reset()
+ self.extend_config ( self.CONFIG_DEFAULTS )
+ # --- end of reset_config (...) ---
+
+ def inject_config_path ( self, path, value ):
+ return self.config.inject ( path, value, suppress_log=True )
+ # --- end of inject_config_path (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def create_argparser ( self ):
+ pass
+ # --- end of create_argparser (...) ---
+
+ def setup_argparser ( self ):
+ parser = self.create_argparser()
+ if parser is not False:
+ parser.setup()
+ self.parser = parser
+
+ parser.parse()
+
+ self.options = parser.get_options()
+ self.commands = parser.get_commands()
+ # --- end of do_setup_parser (...) ---
+
+ def setup_common ( self ):
+ roverlay.recipe.easylogger.force_console_logging (
+ log_formatter=logging.Formatter ( self.LOG_FORMAT )
+ )
+ self.setup_argparser()
+ # --- end of setup_common (...) ---
+
+ def setup ( self ):
+ self.setup_common()
+ # --- end of setup (...) ---
+
+ def option ( self, key, fallback=None ):
+ return self.options.get ( key, fallback )
+ # --- end of option (...) ---
+
+ def optionally ( self, func, key, *args, **kwargs ):
+ if self.options.get ( key, False ):
+ return func ( *args, **kwargs )
+ else:
+ return None
+ # --- end of optionally (...) ---
+
+ def is_installed ( self ):
+ return self.config.get_or_fail ( 'installed' )
+ # --- end of is_installed (...) ---
+
+ installed = property ( is_installed )
+
+# --- end of IndependentRuntimeEnvironment ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-06 17:27 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-06 17:27 UTC (permalink / raw
To: gentoo-commits
commit: e89719a69f61008ac51bd8c7b3a3e24b905ea4f3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 6 17:21:56 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 6 17:21:56 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=e89719a6
argparser: support >=1 command(s)
+ get_options(), get_commands() functions for getting options/commands
---
roverlay/argparser.py | 14 ++++++++++++--
roverlay/argutil.py | 11 +++++++++++
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 98b09a1..c7be8f6 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -73,7 +73,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
# '* <space> <command> - <command description>'
'* {cmd} - {desc}'.format (
cmd=cmd.ljust ( 15 ), desc=desc
- ) for cmd, desc in command_map.items()
+ ) for cmd, desc in command_map.items() if cmd is not None
)
)
# --- end of format_command_map (...) ---
@@ -537,6 +537,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
+ MULTIPLE_COMMANDS = False
COMMAND_DESCRIPTION = None
DEFAULT_COMMAND = None
@@ -551,6 +552,13 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
assert self.default_command in self.COMMAND_DESCRIPTION
# --- end of __init__ (...) ---
+ def get_commands ( self ):
+ if self.MULTIPLE_COMMANDS:
+ return self.command
+ else:
+ return ( self.command, )
+ # --- end of get_commands (...) ---
+
def setup_actions ( self ):
arg = self.add_argument_group (
"actions", title="actions",
@@ -559,7 +567,8 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
arg (
'command', default=self.default_command, metavar='<action>',
- nargs="?", choices=self.COMMAND_DESCRIPTION.keys(),
+ nargs=( "*" if self.MULTIPLE_COMMANDS else "?" ),
+ choices=self.COMMAND_DESCRIPTION.keys(),
flags=self.ARG_HELP_DEFAULT,
help="action to perform"
)
@@ -573,6 +582,7 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
# --- end of RoverlayArgumentParser ---
+
class RoverlayStatusArgumentParser ( RoverlayArgumentParser ):
DESCRIPTION_TEMPLATE = "roverlay status tool {version}\n{license}"
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 73e88b6..d6ba97e 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -9,6 +9,9 @@ import argparse
import pwd
import grp
+
+from roverlay.config.entryutil import deref_entry_safe
+
def get_uid ( user ):
try:
return int ( user )
@@ -193,6 +196,14 @@ class ArgumentParserProxy ( object ):
self.parsed = None
# --- end of __init__ (...) ---
+ def get_options ( self ):
+ return self.parsed
+ # --- end of get_options (...) ---
+
+ def get_commands ( self ):
+ return ()
+ # --- end of get_commands (...) ---
+
def get_default ( self, key, *args ):
return self.defaults.get ( key, *args )
# --- end of get_default (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-10 14:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-10 14:40 UTC (permalink / raw
To: gentoo-commits
commit: c8c61bed9c1d086cf5675467ae1d1262d0659207
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 10 14:26:52 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 10 14:26:52 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c8c61bed
roverlay/runtime: config access
IndependentRuntimeEnvironment: create new config tree, access constants
---
roverlay/runtime.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 4 deletions(-)
diff --git a/roverlay/runtime.py b/roverlay/runtime.py
index bbc73d7..3e251b9 100644
--- a/roverlay/runtime.py
+++ b/roverlay/runtime.py
@@ -17,6 +17,9 @@ import roverlay.stats.collector
import roverlay.util.objects
import roverlay.recipe.easylogger
+import roverlay.config.tree
+import roverlay.config.const
+
from roverlay.core import DIE, die
# TODO: move/merge roverlay.core.DIE into runtime env
@@ -267,19 +270,55 @@ class RuntimeEnvironment ( RuntimeEnvironmentBase ):
class IndependentRuntimeEnvironment ( MinimalRuntimeEnvironment ):
LOG_FORMAT = None
+ LOG_LEVEL = None
- def __init__ ( self, installed=True ):
+ def __init__ ( self, installed=True, stdout=None, stderr=None ):
super ( IndependentRuntimeEnvironment, self ).__init__()
- self.config = roverlay.config.tree.ConfigTree ( register_static=False )
self.CONFIG_DEFAULTS = { 'installed': installed, }
- self.extend_config ( self.CONFIG_DEFAULTS )
+ self.config = self.create_new_config()
self.parser = None
self.options = None
self.commands = None
+
+ self.stdout = stdout if stdout is not None else sys.stdout
+ self.stderr = stderr if stderr is not None else sys.stderr
+ self.info = self.stdout.write
+ self.error = self.stderr.write
+
+ if installed:
+ self.INSTALLINFO = self.access_constant ( 'INSTALLINFO' )
+ else:
+ self.INSTALLINFO = None
# --- end of __init__ (...) ---
+ def create_new_config ( self, config_str=None, apply_defaults=True ):
+ ctree = roverlay.config.tree.ConfigTree ( register_static=False )
+
+ if apply_defaults:
+ ctree.merge_with ( self.CONFIG_DEFAULTS )
+
+ if config_str:
+ ctree.get_loader().parse_config ( config_str )
+
+ return ctree
+ # --- end of create_new_config (...) ---
+
+ def reconfigure ( self, config_str=None ):
+ self.reset_config()
+ if config_str:
+ self.config.get_loader().parse_config ( config_str )
+ # --- end of reconfigure (...) ---
+
+ def access_constant ( self, key ):
+ return roverlay.config.const.lookup ( key )
+ # --- end of access_constant (...) ---
+
+ def wants_command ( self, *commands ):
+ return any ( cmd in self.commands for cmd in commands )
+ # --- end of wants_command (...) ---
+
def extend_config ( self, additional_config ):
self.config.merge_with ( additional_config )
# --- end of extend_config (...) ---
@@ -312,7 +351,10 @@ class IndependentRuntimeEnvironment ( MinimalRuntimeEnvironment ):
def setup_common ( self ):
roverlay.recipe.easylogger.force_console_logging (
- log_formatter=logging.Formatter ( self.LOG_FORMAT )
+ log_formatter = logging.Formatter ( self.LOG_FORMAT ),
+ log_level = (
+ logging.DEBUG if self.LOG_LEVEL is None else self.LOG_LEVEL
+ ),
)
self.setup_argparser()
# --- end of setup_common (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-10 14:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-10 14:40 UTC (permalink / raw
To: gentoo-commits
commit: bed92a84ba5816f9db6320d335c08db2a47f73e4
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 10 14:28:24 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 10 14:29:37 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=bed92a84
fsutil: perform/simulate filesystem operations
rudimentary support for common fs operations.
The VirtualFsOps class can be used to print operations to a stream (stdout).
---
roverlay/fsutil.py | 416 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 416 insertions(+)
diff --git a/roverlay/fsutil.py b/roverlay/fsutil.py
new file mode 100644
index 0000000..5efac20
--- /dev/null
+++ b/roverlay/fsutil.py
@@ -0,0 +1,416 @@
+# R overlay --
+# -*- 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.
+
+import errno
+import os
+import pwd
+import stat
+import sys
+
+import roverlay.util.common
+import roverlay.util.objects
+
+_OS_CHOWN = getattr ( os, 'lchown', os.chown )
+_OS_CHMOD = getattr ( os, 'lchmod', os.chmod )
+
+
+def readlink_f ( fspath ):
+ try:
+ f = os.readlink ( fspath )
+ except OSError as oserr:
+ if oserr.errno in { errno.ENOENT, errno.EINVAL }:
+ f = fspath
+ else:
+ raise
+
+ return os.path.abspath ( f )
+# --- end of readlink_f (...) ---
+
+def create_subdir_check ( parent, fs_sep=os.sep ):
+ PARENT_PATH = parent.rstrip ( fs_sep ).split ( fs_sep )
+
+ def is_subdir ( dirpath ):
+ return all (
+ this == expect for this, expect in zip (
+ dirpath.rstrip ( fs_sep ).split ( fs_sep ),
+ PARENT_PATH
+ )
+ )
+ # --- end of is_subdir (...) ---
+
+ return is_subdir
+# --- end of create_subdir_check (...) ---
+
+
+def pwd_expanduser ( fspath, uid ):
+ if not fspath or fspath[0] != '~':
+ return fspath
+ elif len ( fspath ) < 2:
+ return pwd.getpwuid ( uid ).pw_dir
+ elif fspath[1] == os.sep:
+ return pwd.getpwuid ( uid ).pw_dir + fspath[1:]
+ else:
+ return fspath
+# --- end of pwd_expanduser (...) ---
+
+def get_bitwise_sum ( iterable, initial_value=None ):
+ ret = initial_value if initial_value is not None else 0
+ for item in iterable:
+ ret |= item
+ return ret
+# --- end of get_bitwise_sum (...) ---
+
+def get_stat_mode ( mode_str ):
+
+ def iter_mode_values ( mode_str ):
+ # rwxrwxrwx
+ # 012345678
+ # r -> pos % 3 == 0
+ # w -> pos % 3 == 1
+ # x -> pos % 3 == 2
+
+
+ # COULDFIX: parse sticky bit etc. (not necessary, currently)
+ if len ( mode_str ) > 9:
+ raise ValueError ( mode_str )
+
+ for pos, char in enumerate ( mode_str ):
+ if char != '-':
+ block = pos // 3
+ subpos = pos % 3
+ if subpos == 0:
+ # r
+ assert char == 'r'
+ if block == 0:
+ yield stat.S_IRUSR
+ elif block == 1:
+ yield stat.S_IRGRP
+ else:
+ yield stat.S_IROTH
+
+ elif subpos == 1:
+ # w
+ assert char == 'w'
+ if block == 0:
+ yield stat.S_IWUSR
+ elif block == 1:
+ yield stat.S_IWGRP
+ else:
+ yield stat.S_IWOTH
+
+ elif subpos == 2:
+ # x
+ assert char == 'x'
+ if block == 0:
+ yield stat.S_IXUSR
+ elif block == 1:
+ yield stat.S_IXGRP
+ else:
+ yield stat.S_IXOTH
+
+ # --- end of iter_mode_values (...) ---
+
+ return get_bitwise_sum ( iter_mode_values ( mode_str ) )
+# --- end of get_stat_mode (...) ---
+
+class ChownChmod ( object ):
+
+ def __init__ ( self, uid=None, gid=None, mode=None, pretend=False ):
+ super ( ChownChmod, self ).__init__()
+
+ self.pretend = bool ( pretend )
+ do_chown = uid is not None or gid is not None
+
+ self.uid = -1 if uid is None else uid
+ self.gid = -1 if gid is None else gid
+
+ if do_chown:
+ self.chown_str = "chown {uid:d}:{gid:d} {{}}".format (
+ uid=self.uid, gid=self.gid
+ )
+ if self.pretend:
+ self.chown = self.chown_str.format
+ else:
+ self.chown = self._do_chown
+ else:
+ self.chown_str = "NO CHOWN {}"
+ self.chown = self._nullfunc
+
+
+ if mode is None:
+ self.mode = None
+ elif isinstance ( mode, str ):
+ self.mode = get_stat_mode ( mode )
+ else:
+ self.mode = mode
+
+ if self.mode is None:
+ self.chmod_str = "NO CHMOD {}"
+ self.chmod = self._nullfunc
+ else:
+ self.chmod_str ="chmod {mode:o} {{}}".format ( mode=self.mode )
+ if self.pretend:
+ self.chmod = self.chmod_str.format
+ else:
+ self.chmod = self._do_chmod
+ # --- end of __init__ (...) ---
+
+ def _nullfunc ( self, fspath ):
+ return None
+
+ def _do_chown ( self, fspath, _chown=_OS_CHOWN ):
+ _chown ( fspath, self.uid, self.gid )
+ return self.chown_str.format ( fspath )
+
+ def _do_chmod ( self, fspath, _chmod=_OS_CHMOD ):
+ _chmod ( fspath, self.mode )
+ return self.chmod_str.format ( fspath )
+
+ def chown_chmod ( self, fspath ):
+ # should be renamed to chmod_chown()
+ return (
+ self.chmod ( fspath ),
+ self.chown ( fspath )
+ )
+ # --- end of chown_chmod (...) ---
+
+ def chown_chmod_recursive ( self, root ):
+ chown = self.chown
+ chmod = self.chmod
+
+ if os.path.isfile ( root ):
+ yield chmod ( root )
+ yield chown ( root )
+
+ else:
+ for current_root, dirnames, filenames in os.walk ( root ):
+ yield chmod ( current_root )
+ yield chown ( current_root )
+
+ for filename in filenames:
+ fpath = current_root + os.sep + filename
+ yield chmod ( fpath )
+ yield chown ( fpath )
+ # --- end of chown_chmod_recursive (...) ---
+
+# --- end of ChownChmod ---
+
+
+def chown_chmod ( root, uid=None, gid=None, mode=None, pretend=False ):
+ return ChownChmod ( uid, gid, mode, pretend ).chown_chmod ( root )
+# --- end of chown_chmod (...) ---
+
+def chown_chmod_recursive (
+ root, uid=None, gid=None, mode=None, pretend=False
+):
+ return ChownChmod (
+ uid, gid, mode, pretend ).chown_chmod_recursive ( root )
+# --- end of chown_chmod_recursive (...) ---
+
+
+class AbstractFsOperations ( object ):
+
+ PRETEND = None
+
+ def __init__ ( self,
+ stdout=None, stderr=None, uid=None, gid=None, mode=None
+ ):
+ if self.__class__.PRETEND is None:
+ raise AssertionError ( "derived classes have to set PRETEND." )
+
+ super ( AbstractFsOperations, self ).__init__()
+ self.perm_env = ChownChmod (
+ uid=uid, gid=gid, mode=mode, pretend=self.__class__.PRETEND
+ )
+ self._stdout = sys.stdout if stdout is None else stdout
+ self._stderr = sys.stderr if stderr is None else stderr
+
+ self.info = self._stdout.write
+ self.error = self._stderr.write
+ # --- end of __init__ (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def _dodir ( self, dirpath, mkdir_p ):
+ pass
+
+ @roverlay.util.objects.abstractmethod
+ def do_touch ( self, fspath ):
+ pass
+
+ @roverlay.util.objects.abstractmethod
+ def chown ( self, fspath ):
+ pass
+
+ @roverlay.util.objects.abstractmethod
+ def chmod ( self, fspath ):
+ pass
+
+ def chmod_chown ( self, fspath ):
+ self.chmod ( fspath )
+ self.chown ( fspath )
+
+ @roverlay.util.objects.abstractmethod
+ def chmod_chown_recursive ( self, root ):
+ pass
+
+ def dodir ( self, dirpath, mkdir_p=True, chown=True, chmod=True ):
+ if self._dodir ( dirpath, mkdir_p=mkdir_p ):
+ if chmod:
+ self.chmod ( dirpath )
+ if chown:
+ self.chown ( dirpath )
+
+ return True
+
+ else:
+ return False
+ # --- end of dodir (...) ---
+
+ def dodirs ( self, *dirs, **kwargs ):
+ for dirpath in dirs:
+ self.dodir ( dirpath, **kwargs )
+ # --- end of dodirs (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def rmdir ( self, dirpath ):
+ pass
+
+ @roverlay.util.objects.abstractmethod
+ def unlink ( self, fspath ):
+ pass
+
+ def wipe ( self, fspath ):
+ return self.rmdir ( fspath ) or self.unlink ( fspath )
+
+ @roverlay.util.objects.abstractmethod
+ def symlink ( self, source, link_name ):
+ pass
+
+ def check_writable ( self,
+ fspath, mkdir_chown=False, mkdir_chmod=False, mkdir_p=True
+ ):
+ """Checks whether fspath can be written. This creates all necessary
+ directories."""
+ success = False
+
+ try:
+ if self.do_touch ( fspath ):
+ success = True
+
+ except IOError as ioerr:
+ if ioerr.errno == errno.ENOENT:
+ try:
+ if self.dodir (
+ os.path.dirname ( fspath ),
+ chown=mkdir_chown, chmod=mkdir_chmod, mkdir_p=mkdir_p
+ ) and self.do_touch ( fspath ):
+ success = True
+
+ except ( OSError, IOError ) as err:
+ if err.errno != errno.EPERM:
+ raise
+
+ return success
+ # --- end of check_writable (...) ---
+
+# --- end of AbstractFsOperations ---
+
+class FsOperations ( AbstractFsOperations ):
+
+ PRETEND = False
+
+ def _dodir ( self, dirpath, mkdir_p ):
+ return roverlay.util.common.dodir (
+ dirpath, mkdir_p=mkdir_p, log_exception=False
+ )
+ # --- end of _dodir (...) ---
+
+ def chmod ( self, fspath ):
+ self.perm_env.chmod ( fspath )
+
+ def chown ( self, fspath ):
+ self.perm_env.chown ( fspath )
+
+ def chmod_chown ( self, fspath ):
+ self.perm_env.chown_chmod ( fspath )
+
+ def chmod_chown_recursive ( self, root ):
+ for ret in self.perm_env.chown_chmod_recursive ( root ):
+ pass
+
+ def rmdir ( self, dirpath ):
+ try:
+ os.rmdir ( dirpath )
+ except OSError as oserr:
+ return oserr.errno == errno.ENOENT
+ else:
+ return True
+ # --- end of rmdir (...) ---
+
+ def unlink ( self, fspath ):
+ try:
+ os.unlink ( fspath )
+ except OSError as oserr:
+ return oserr.errno == errno.ENOENT
+ else:
+ return True
+
+ def symlink ( self, source, link_name ):
+ try:
+ os.symlink ( source, link_name )
+ except OSError:
+ return False
+ else:
+ return True
+
+ def do_touch ( self, fspath ):
+ if not os.path.lexists ( fspath ):
+ with open ( fspath, 'a' ) as FH:
+ pass
+ return True
+
+
+class VirtualFsOperations ( AbstractFsOperations ):
+
+ PRETEND = True
+
+ def _dodir ( self, dirpath, mkdir_p ):
+ if mkdir_p:
+ self.info ( "mkdir -p {!s}\n".format ( dirpath ) )
+ else:
+ self.info ( "mkdir {!s}\n".format ( dirpath ) )
+ return True
+
+ def chown ( self, fspath ):
+ ret = self.perm_env.chown ( fspath )
+ if ret is not None:
+ self.info ( ret + "\n" )
+
+ def chmod ( self, fspath ):
+ ret = self.perm_env.chmod ( fspath )
+ if ret is not None:
+ self.info ( ret + "\n" )
+
+ def chmod_chown_recursive ( self, root ):
+ for word in self.perm_env.chmod_chown_recursive ( root ):
+ if word is not None:
+ self.info ( word + "\n" )
+
+ def unlink ( self, fspath ):
+ self.info ( "rm {!r}\n".format ( fspath ) )
+ return True
+
+ def rmdir ( self, dirpath ):
+ self.info ( "rmdir {!r}\n".format ( dirpath ) )
+ return True
+
+ def symlink ( self, source, link_name ):
+ self.info ( "ln -s {} {}\n".format ( source, link_name ) )
+ return True
+
+ def do_touch ( self, fspath ):
+ self.info ( "touch {}\n".format ( fspath ) )
+ return True
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-10 14:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-10 14:40 UTC (permalink / raw
To: gentoo-commits
commit: bfef26d7cf86185b1d15764e682a221431cce584
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 10 14:27:51 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 10 14:27:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=bfef26d7
misc argparser changes
---
roverlay/argparser.py | 25 ++++++++++++++++---------
roverlay/argutil.py | 6 ++++++
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index c7be8f6..a08cf00 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -18,7 +18,8 @@ from roverlay.argutil import \
get_gid, is_gid, get_uid, is_uid, \
is_fs_dir, is_fs_dir_or_void, is_fs_file, \
is_fs_file_or_dir, is_fs_file_or_void, \
- is_config_opt, dirstr, dirstr_existing, couldbe_dirstr_existing, \
+ is_config_opt, dirstr, dirstr_existing, \
+ couldbe_dirstr_existing, couldbe_dirstr_existing_or_empty, \
ArgumentParserProxy
@@ -497,14 +498,11 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
return self.setup_misc_minimal()
# --- end of setup_misc (...) ---
- def setup_setup_minimal ( self ):
- assert os.sep == "/"
-
- arg = self.add_argument_group ( 'setup', title='setup options' )
+ def setup_setup_minimal ( self, title='setup options' ):
+ arg = self.add_argument_group ( 'setup', title=title )
arg (
'--work-root', '-W', dest='work_root',
- default="~/roverlay",
flags=self.ARG_WITH_DEFAULT|self.ARG_META_DIR,
type=couldbe_dirstr_existing,
help=(
@@ -514,24 +512,33 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
arg (
'--data-root', '-D', dest='data_root',
- default="/usr/share/roverlay",
flags=self.ARG_WITH_DEFAULT|self.ARG_META_DIR,
type=couldbe_dirstr_existing,
help='roverlay\'s static data (eclass, hook scripts,...)',
)
arg (
- '--conf-root', '-C', dest='conf_root',
- default="/etc/roverlay",
+ '--conf-root', dest='conf_root',
flags=self.ARG_WITH_DEFAULT|self.ARG_META_DIR,
type=couldbe_dirstr_existing,
help='roverlay\'s config files (dependency rules,...)',
)
+ arg (
+ '--conf-dir', '--my-conf-root', '-C', dest='private_conf_root',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_META_DIR,
+ type=couldbe_dirstr_existing_or_empty,
+ help='private directory for config files (\'\' for --conf-root)',
+ )
return arg
# --- end of setup_setup_minimal (...) ---
+ def parse_setup_minimal ( self ):
+ if not self.parsed.get ( 'private_conf_root', True ):
+ self.parsed ['private_conf_root'] = self.parsed ['conf_root']
+ # --- end of parse_setup_minimal (...) ---
+
# --- end of RoverlayArgumentParserBase ---
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index d6ba97e..198ccda 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -146,6 +146,12 @@ def couldbe_dirstr_existing ( value ):
"{!r} cannot be a directory.".format ( dstr )
)
+def couldbe_dirstr_existing_or_empty ( value ):
+ if not value:
+ return ""
+ else:
+ return couldbe_dirstr_existing ( value )
+
class ArgumentParserError ( Exception ):
pass
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-10 14:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-10 14:40 UTC (permalink / raw
To: gentoo-commits
commit: 371a3c585e51383a05df6986f0c6b02631147cc7
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 10 14:33:09 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 10 14:40:01 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=371a3c58
roverlay: setupscript.py
This file provides various env objects and a main() function for setting up
roverlay.
It is meant to replace:
* the roverlay-mkconfig command (now "roverlay-setup mkconfig")
* most of the ebuild's pkg_config() and roverlay's setupdirs command
(unified in "roverlay-setup init" and more flexible/safer, e.g.
a has --pretend option that gives detailed information about what
would be done)
Additionally, it can be used to manage roverlay's hooks (besides setting up the
default hooks; TODO).
TODO notes:
* needs a cleanup
* only "--import-config symlink=root" is implemented, currently
* isn't able to handle not-installed versions of roverlay
* the replaced commands/functionality has to be removed
---
roverlay/setupscript.py | 1035 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1035 insertions(+)
diff --git a/roverlay/setupscript.py b/roverlay/setupscript.py
new file mode 100644
index 0000000..2a23103
--- /dev/null
+++ b/roverlay/setupscript.py
@@ -0,0 +1,1035 @@
+# R overlay -- setup script
+# -*- coding: utf-8 -*-
+
+from __future__ import print_function
+
+import argparse
+import collections
+import errno
+import logging
+import os
+import shutil
+import stat
+import sys
+import textwrap
+
+import roverlay.argutil
+import roverlay.argparser
+import roverlay.fsutil
+import roverlay.runtime
+
+import roverlay.config.defconfig
+import roverlay.config.entrymap
+import roverlay.config.entryutil
+
+import roverlay.static.hookinfo
+
+import roverlay.util.counter
+
+if sys.hexversion >= 0x3000000:
+ read_user_input = input
+else:
+ read_user_input = raw_input
+
+
+
+
+
+
+def arg_stdout_or_fs ( value ):
+ if value == '-':
+ return value
+ else:
+ return os.path.abspath ( os.path.expanduser ( value ) )
+# --- end of arg_stdout_or_fs (...) ---
+
+
+
+
+class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
+ MULTIPLE_COMMANDS = False
+ COMMAND_DESCRIPTION = {
+ 'init': 'initialize roverlay\'s config and filesystem layout',
+ 'mkconfig': 'generate a config file',
+ }
+ DEFAULT_COMMAND = "init"
+
+ COMMANDS_WITH_PRETEND = frozenset ({ 'init', })
+
+ SETUP_TARGETS = ( 'version', 'actions', 'setup', 'config', 'init', )
+ PARSE_TARGETS = ( 'actions', 'setup', 'init', )
+
+
+ def setup_setup ( self ):
+ arg = self.setup_setup_minimal ( title='common options' )
+
+ arg (
+ '--output', '-O', metavar="<file|dir|->", dest='output',
+ default='-', type=arg_stdout_or_fs,
+ flags=self.ARG_WITH_DEFAULT,
+ help='output file/dir/stream used by various commands (\'-\' for stdout)',
+ )
+
+ arg (
+ '--pretend', '-p', dest='pretend',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help='show what would be done',
+ )
+
+ arg (
+ '--ask', '-a', dest='wait_confirm',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help='get confirmation before actually doing anything',
+ )
+
+ return arg
+ # --- end of setup_setup (...) ---
+
+ def parse_setup ( self ):
+ self.parse_setup_minimal()
+
+ if self.parsed ['pretend']:
+ for cmd in self.get_commands():
+ if cmd not in self.__class__.COMMANDS_WITH_PRETEND:
+ self.parser.exit (
+ "{!r} command does not support --pretend.".format ( cmd )
+ )
+ # --- end of parse_setup (...) ---
+
+ def setup_config ( self ):
+ arg = self.add_argument_group (
+ "config", title="options for the main config file"
+ )
+
+ arg (
+ '--expand-user', dest='config_expand_user',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help="expand \'~\' to the target user\'s home directory",
+ )
+
+ arg (
+ '--variable', '-v', metavar="<key=\"value\">", dest='config_vars',
+ default=[], action='append',
+ type=roverlay.argutil.is_config_opt,
+ help="additional variables",
+ )
+
+ return arg
+ # --- end of setup_config (...) ---
+
+ def setup_init ( self ):
+ arg = self.add_argument_group (
+ 'init', title='options for the \'init\' command'
+ )
+
+ arg (
+ '--enable-default-hooks', dest='want_default_hooks',
+ default=True,
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help='enable/update the default hooks',
+ )
+
+ arg (
+ '--no-default-hooks', dest='want_default_hooks',
+ flags=self.ARG_SHARED|self.ARG_OPT_OUT,
+ help='disable the default hooks',
+ )
+
+ arg (
+ '--import-config', '-I', dest='import_config',
+ default="symlink",
+ choices=[
+ "disable",
+ "symlink", "symlink=root",
+ "symlink=dirs", "symlink=files",
+ "copy"
+ ],
+ metavar='<mode>',
+ flags=self.ARG_WITH_DEFAULT,
+ help=(
+ 'choose whether and how --conf-root should be imported: '
+ '%(choices)s'
+ ),
+ )
+
+ arg (
+ '--no-import-config', dest='import_config',
+ action='store_const', const='disable',
+ help='disable config import (same as \'--import-config disable\')',
+ )
+
+
+ arg (
+ '--target-uid', dest='target_uid', default=os.getuid(),
+ metavar='<uid>', type=roverlay.argutil.is_uid,
+ flags=self.ARG_WITH_DEFAULT,
+ help="uid of the user that will run roverlay",
+ )
+
+ arg (
+ '--target-gid', dest='target_gid', default=os.getgid(),
+ metavar='<gid>', type=roverlay.argutil.is_gid,
+ flags=self.ARG_WITH_DEFAULT,
+ help='gid of the user that will run roverlay',
+ )
+
+ # --- end of setup_init (...) ---
+
+ def parse_init ( self ):
+ my_uid = os.getuid()
+
+ if my_uid and self.parsed ['target_uid'] != my_uid:
+ if self.parsed ['pretend']:
+ sys.stderr.write (
+ "!!! --target-uid: users cannot configure other users.\n\n"
+ )
+ else:
+ self.parser.exit (
+ "--target-uid: users cannot configure other users."
+ )
+ # --- end of parse_init (...) ---
+
+
+# --- end of SetupArgParser ---
+
+
+class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
+
+ LOG_LEVEL = logging.INFO
+
+ SHARED_DIR_MODE = roverlay.fsutil.get_stat_mode ( "rwxrwxr-x" )
+ PRIVATE_DIR_MODE = roverlay.fsutil.get_stat_mode ( "rwxr-x---" )
+ SHARED_FILE_MODE = roverlay.fsutil.get_stat_mode ( "rw-rw-r--" )
+ PRIVATE_FILE_MODE = roverlay.fsutil.get_stat_mode ( "rw-r-----" )
+
+ def __init__ ( self, *args, **kwargs ):
+ super ( SetupEnvironment, self ).__init__ ( *args, **kwargs )
+
+ self.UID = os.getuid()
+ self.GID = os.getgid()
+
+ self.expanduser = None
+ self.fs_ops = None
+ self.fs_ops_virtual = None
+
+ self.want_chown = None
+ self.data_root = None
+ self.work_root = None
+ self.conf_root = None
+ self.user_conf_root = None
+ # --- end of __init__ (...) ---
+
+ def create_argparser ( self ):
+ instinfo = self.access_constant ( 'INSTALLINFO' )
+
+ return SetupArgParser (
+ description = 'roverlay setup script',
+ defaults = {
+ 'work_root' : instinfo ['workroot'],
+ 'data_root' : instinfo ['libexec'],
+ 'conf_root' : instinfo ['confroot'],
+ 'private_conf_root' : instinfo ['workroot'] + os.sep + 'config',
+ 'import_config' : 'symlink=root',
+ },
+ )
+ # --- end of create_argparser (...) ---
+
+ def _get_config_roots ( self ):
+ return (
+ os.path.realpath ( self.conf_root ),
+ os.path.realpath ( self.user_conf_root )
+ )
+ # --- end of get_config_roots (...) ---
+
+ def get_user_config_root ( self ):
+ conf_root, user_conf_root = self._get_config_roots()
+ if conf_root == user_conf_root:
+ return None
+ else:
+ return user_conf_root
+ # --- end of get_user_config_root (...) ---
+
+ def get_config_file_path ( self ):
+ return (
+ self.work_root + os.sep + self.access_constant ( 'config_file_name' )
+ )
+ # --- end of get_config_file_path (...) ---
+
+ def create_new_target_config ( self ):
+ return self.create_new_config (
+ config_str=self.create_config_file ( expand_user=True )
+ )
+ # --- end of create_new_target_config (...) ---
+
+ def _expanduser_pwd ( self, fspath ):
+ return roverlay.fsutil.pwd_expanduser (
+ fspath, self.options ['target_uid']
+ )
+ # --- end of _expanduser_pwd (...) ---
+
+ def create_config_file ( self, expand_user=False ):
+ conf_creator = roverlay.config.defconfig.RoverlayConfigCreation (
+ work_root = (
+ self.work_root if expand_user else self.options ['work_root']
+ ),
+ data_root = (
+ self.data_root if expand_user else self.options ['data_root']
+ ),
+ conf_root = (
+ self.user_conf_root if expand_user
+ else self.options ['private_conf_root']
+ ),
+ )
+
+ for kv in self.options ['config_vars']:
+ key, sepa, value = kv.partition ( '=' )
+ if not sepa:
+ raise Exception ( "bad variable given: {!r}".format ( kv ) )
+ else:
+ conf_creator.set_option ( key, value )
+
+ return conf_creator.get_str()
+ # --- end of create_config_file (...) ---
+
+ def write_config_file ( self, output=None, expand_user=None ):
+ config_file_str = self.create_config_file (
+ expand_user = (
+ self.options ['config_expand_user'] if expand_user is None
+ else expand_user
+ ),
+ )
+ if not output or output == '-':
+ self.info ( config_file_str )
+ else:
+ with open ( output, 'wt' ) as FH:
+ FH.write ( config_file_str )
+ # --- end of write_config_file (...) ---
+
+ def auto_reconfigure ( self ):
+ self.reconfigure ( self.create_config_file() )
+ # --- end of auto_reconfigure (...) ---
+
+ def setup ( self ):
+ self.PWD_INITIAL = os.getcwd()
+ self.setup_common()
+
+ # ref
+ options = self.options
+
+ target_uid = options ['target_uid']
+ target_gid = options ['target_gid']
+
+ self.want_chown = ( target_uid != self.UID or target_gid != self.GID )
+
+ if self.UID == target_uid:
+ expanduser = os.path.expanduser
+ self.expanduser = os.path.expanduser
+ else:
+ expanduser = self._expanduser_pwd
+ self.expanduser = self._expanduser_pwd
+
+ self.work_root = expanduser ( options ['work_root'] )
+ self.data_root = expanduser ( options ['data_root'] )
+ self.conf_root = expanduser ( options ['conf_root'] )
+ self.user_conf_root = expanduser ( options ['private_conf_root'] )
+
+
+ self.fs_ops_virtual = {
+ 'private_dir': roverlay.fsutil.VirtualFsOperations (
+ uid=target_uid, gid=target_gid, mode=self.PRIVATE_DIR_MODE,
+ ),
+ 'shared_dir': roverlay.fsutil.VirtualFsOperations (
+ uid=target_uid, gid=target_gid, mode=self.SHARED_DIR_MODE,
+ ),
+ 'private_file': roverlay.fsutil.VirtualFsOperations (
+ uid=target_uid, gid=target_gid, mode=self.PRIVATE_FILE_MODE,
+ ),
+ 'shared_file': roverlay.fsutil.VirtualFsOperations (
+ uid=target_uid, gid=target_gid, mode=self.SHARED_FILE_MODE,
+ ),
+ }
+
+ if options ['pretend']:
+ self.fs_ops = self.fs_ops_virtual
+ else:
+ self.fs_ops = {
+ 'private_dir': roverlay.fsutil.FsOperations (
+ uid=target_uid, gid=target_gid, mode=self.PRIVATE_DIR_MODE,
+ ),
+ 'shared_dir': roverlay.fsutil.FsOperations (
+ uid=target_uid, gid=target_gid, mode=self.SHARED_DIR_MODE,
+ ),
+ 'private_file': roverlay.fsutil.FsOperations (
+ uid=target_uid, gid=target_gid, mode=self.PRIVATE_FILE_MODE,
+ ),
+ 'shared_file': roverlay.fsutil.FsOperations (
+ uid=target_uid, gid=target_gid, mode=self.SHARED_FILE_MODE,
+ ),
+ }
+
+ # bind fs_ops
+ self.private_dir = self.fs_ops ['private_dir']
+ self.shared_dir = self.fs_ops ['shared_dir']
+ self.private_file = self.fs_ops ['private_file']
+ self.shared_file = self.fs_ops ['shared_file']
+ # --- end of setup (...) ---
+
+ def wait_confirm ( self,
+ message=None, message_inline=None,
+ prepend_newline=True, append_newline=True
+ ):
+ try:
+ if prepend_newline:
+ self.info ( '\n' )
+
+ if message is not None:
+ self.info ( str ( message ) + '\n' )
+
+ if message_inline:
+ self.info (
+ "Press Enter to continue ({!s}) ... ".format ( message_inline )
+ )
+ else:
+ self.info ( "Press Enter to continue ... " )
+
+ self.stdout.flush()
+
+ ret = read_user_input().strip()
+
+ except ( KeyboardInterrupt, EOFError ):
+ self.info ( "\n" )
+ sys.exit ( 130 )
+ else:
+ if append_newline:
+ self.info ( '\n' )
+
+ return ret
+ # --- end of wait_confirm (...) ---
+
+ def wait_confirm_can_skip ( self,
+ SKIP_WORDS=frozenset({ 'skip', 'no', 'n'}), **kwargs
+ ):
+ assert 'message_inline' not in kwargs
+
+ if self.options ['wait_confirm']:
+
+ user_reply = self.wait_confirm (
+ message_inline="type {} to skip this step".format (
+ '/'.join ( repr( word ) for word in sorted( SKIP_WORDS ) )
+ ),
+ **kwargs
+ )
+
+ return user_reply.lower() not in SKIP_WORDS
+ else:
+ return True
+ # --- end of wait_confirm (...) ---
+
+ def get_init_env ( self ):
+ return SetupInitEnvironment ( self )
+ # --- end of get_init_env (...) ---
+
+ def get_hook_env ( self ):
+ return SetupHookEnvironment ( self )
+ # --- end of get_hook_env (...) ---
+
+# --- end of SetupEnvironment ---
+
+
+class SetupSubEnvironment ( object ):
+
+ NEEDS_CONFIG_TREE = False
+
+ ACTIONS = None
+
+ def __init__ ( self, setup_env ):
+ super ( SetupSubEnvironment, self ).__init__()
+
+ self.setup_env = setup_env
+ self.stdout = setup_env.stdout
+ self.stderr = setup_env.stderr
+ self.info = setup_env.info
+ self.error = setup_env.error
+
+ if self.NEEDS_CONFIG_TREE:
+ self.config = self.setup_env.create_new_target_config()
+ else:
+ self.config = None
+
+ self.setup()
+ # --- end of __init__ (...) ---
+
+ def setup ( self ):
+ pass
+ # --- end of setup (...) ---
+
+ def run ( self, steps_to_skip=None, verbose_skip=True, steps=None ):
+ pretend = self.setup_env.options ['pretend']
+ ACTIONS = steps if steps is not None else self.ACTIONS
+
+ if ACTIONS:
+ if steps_to_skip:
+ methods_to_call = [
+ (
+ None if item[0] in steps_to_skip
+ else getattr ( self, 'do_' + item[0] )
+ ) for item in ACTIONS
+ ]
+ else:
+ methods_to_call = [
+ getattr ( self, 'do_' + item[0] ) for item in ACTIONS
+ ]
+
+ wait_confirm_can_skip = self.setup_env.wait_confirm_can_skip
+
+
+ for method, action in zip ( methods_to_call, ACTIONS ):
+ if method is None:
+ if verbose_skip:
+ self.info ( "{}: skipped.\n".format ( action[0] ) )
+
+ elif not action[1]:
+ method ( pretend=pretend )
+
+ elif wait_confirm_can_skip (
+ message=method.__doc__, append_newline=False
+ ):
+ method ( pretend=pretend )
+ else:
+ self.info ( "skipped.\n" )
+
+ else:
+ raise NotImplementedError (
+ "{}.{}()".format ( self.__class__.__name__, "do_all" )
+ )
+ # --- end of run (...) ---
+
+
+# --- end of SetupSubEnvironment ---
+
+
+class SetupInitEnvironment ( SetupSubEnvironment ):
+
+ ACTIONS = (
+ ( 'pretend', False ),
+ ( 'prepare_config_file', False ),
+ ( 'import_config', True ),
+ ( 'setupdirs', True ),
+ ( 'write_config_file', True ),
+ ( 'enable_default_hooks', True ),
+ )
+
+ NEEDS_CONFIG_TREE = True
+
+ def setup ( self ):
+ self.config_file_str = None
+ # --- end of setup (...) ---
+
+ IMPORT_CONFIG_DESC = {
+ 'disable' : False,
+ 'symlink' : 'symlink {conf_root} to {user_conf_root}',
+ 'symlink=root' : 'symlink {conf_root} to {user_conf_root}',
+ 'symlink=dirs' : (
+ 'symlink files/dirs from {conf_root} to {user_conf_root}/'
+ ),
+ 'symlink=files' : (
+ 'recursively copy {conf_root} to {user_conf_root}, '
+ 'but symlink files instead of copying them'
+ ),
+ 'copy' : 'recursively copy {conf_root} to {user_conf_root}',
+ }
+
+ def gen_pretend_options ( self ):
+ options = self.setup_env.options
+
+ def get_option ( key ):
+ val = options [key]
+ if isinstance ( val, str ):
+ return val
+ elif hasattr ( val, '__iter__' ):
+ return ' '.join ( str(x) for x in val )
+ elif isinstance ( val, bool ):
+ return "yes" if val else "no"
+ elif val is None:
+ return "<undef>"
+ else:
+ return str ( val )
+ # --- end of get_option (...) ---
+
+ comment_path = lambda a, b: a if a == b else ( a + ' (' + b + ')' )
+ get_path_option = lambda k, b: comment_path ( get_option ( k ), b )
+
+ fmt_vars = {
+ 'conf_root' : options ['conf_root'],
+ 'user_conf_root': options ['private_conf_root']
+ }
+
+ yield ( "user/uid", get_option ( 'target_uid' ) )
+ yield ( "group/gid", get_option ( 'target_gid' ) )
+
+ yield ( "work root",
+ get_path_option ( 'work_root', self.setup_env.work_root )
+ )
+ yield ( "data root",
+ get_path_option ( 'data_root', self.setup_env.data_root )
+ )
+ yield ( "roverlay\'s config root",
+ get_path_option ( 'conf_root', self.setup_env.conf_root )
+ )
+ yield ( "user\'s config root",
+ get_path_option ( 'private_conf_root', self.setup_env.user_conf_root )
+ )
+
+ import_config = get_option ( 'import_config' )
+ if import_config == 'disable':
+ yield ( "import config", "no" )
+ else:
+ yield ( "import config",
+ "yes, "
+ + self.IMPORT_CONFIG_DESC [import_config].format ( **fmt_vars )
+ )
+
+ yield ( "enable default hooks", get_option ( 'want_default_hooks' ) )
+ yield ( "additional config variables", get_option ( 'config_vars' ) )
+ # --- end of gen_pretend_options (...) ---
+
+ def gen_pretend_lines ( self, append_newline=True ):
+ options = list ( self.gen_pretend_options() )
+ COLUMNS = os.environ.get ( 'COLUMNS', 78 )
+ desc_len = min ( COLUMNS // 2,
+ 1 + max ( len(desc) for desc, value in options )
+ )
+
+ line_wrapper = textwrap.TextWrapper (
+ width=COLUMNS, initial_indent='',
+ subsequent_indent=( (desc_len+5) * ' ' ),
+ break_long_words=False, break_on_hyphens=False,
+ )
+
+
+ yield 'Configuration:'
+ for desc, value in options:
+ yield line_wrapper.fill (
+ "- {desc:<{l}}: {value}".format (
+ desc=desc, l=desc_len, value=value,
+ )
+ )
+
+ if append_newline:
+ yield ""
+ # --- end of gen_pretend_lines (...) ---
+
+ def do_pretend ( self, pretend ):
+ """Shows what would be done."""
+ self.info ( '\n'.join ( self.gen_pretend_lines() ) + '\n' )
+ # --- end of do_pretend (...) ---
+
+ def do_prepare_config_file ( self, pretend ):
+ """Creates the config file (in memory)."""
+ self.config_file_str = self.setup_env.create_config_file (
+ expand_user=self.setup_env.options ['config_expand_user']
+ )
+ # --- end of do_prepare_config_file (...) ---
+
+ def do_import_config ( self, pretend ):
+ """Imports the config."""
+ mode = self.setup_env.options ['import_config']
+ fs_ops = self.setup_env.private_dir
+ user_conf_root = self.setup_env.get_user_config_root()
+ # assert os.path.isdir ( os.path.dirname(user_conf_root) == work_root )
+
+ if user_conf_root is None and (
+ fs_ops.unlink ( self.setup_env.user_conf_root )
+ ):
+ # config_root was a symlink
+
+ if pretend:
+ user_conf_root = self.setup_env.user_conf_root
+ else:
+ user_conf_root = self.setup_env.get_user_config_root()
+
+ # -- end if
+
+
+ if user_conf_root is None:
+ self.info (
+ "user has no private config directory - skipping config import.\n"
+ )
+
+ elif mode in { 'symlink=root', 'symlink' }:
+ if not fs_ops.wipe ( user_conf_root ):
+ self.setup_env.die (
+ "failed to remove {!r}.\n".format ( user_conf_root )
+ )
+ elif not fs_ops.symlink ( self.setup_env.conf_root, user_conf_root ):
+ self.setup_env.die (
+ "could not create symlink to {!r}.".format (
+ self.setup_env.conf_root
+ )
+ )
+
+
+ pass
+ else:
+ raise NotImplementedError ( mode )
+ # --- end of do_import_config (...) ---
+
+ def do_setupdirs ( self, pretend ):
+ """Creates directories with proper permissions."""
+ create_subdir_check = roverlay.fsutil.create_subdir_check
+ config = self.config
+ find_config_path = roverlay.config.entryutil.find_config_path
+ dodir_private = self.setup_env.private_dir.dodir
+ dodir_shared = self.setup_env.shared_dir.dodir
+
+
+ WANT_USERDIR = roverlay.config.entrymap.WANT_USERDIR
+ WANT_PRIVATE = roverlay.config.entrymap.WANT_PRIVATE
+ WANT_FILEDIR = roverlay.config.entrymap.WANT_FILEDIR
+
+ listlike = lambda a: (
+ hasattr(a, '__iter__') and not isinstance(a, str)
+ )
+ iter_values = lambda b: (
+ () if b is None else (b if listlike(b) else ( b, ))
+ )
+
+ dirs_exclude = [
+ create_subdir_check ( self.setup_env.conf_root ),
+ create_subdir_check ( self.setup_env.data_root ),
+ ]
+ if self.setup_env.get_user_config_root() is None:
+ dirs_exclude.append (
+ create_subdir_check ( self.setup_env.user_conf_root )
+ )
+ else:
+ print ( self.setup_env.get_user_config_root() )
+
+ # don't print exclude/skip messages more than once per dir
+ dirs_already_excluded = set()
+
+ private_dirs = set()
+ private_dirs_chown = set()
+ shared_dirs = set()
+ shared_dirs_chown = set()
+
+ # it's not necessary to create all of the listed dirs because some of
+ # them are automatically created at runtime, but doing so results in
+ # a (mostly) complete filesystem layout
+ #
+ for config_key, entry in (
+ roverlay.config.entrymap.CONFIG_ENTRY_MAP.items()
+ ):
+ if isinstance ( entry, dict ) and 'want_dir_create' in entry:
+ for value in iter_values (
+ config.get ( find_config_path ( config_key ), None )
+ ):
+ dirmask = entry ['want_dir_create']
+ dirpath = (
+ os.path.dirname ( value.rstrip ( os.sep ) )
+ if dirmask & WANT_FILEDIR else value.rstrip ( os.sep )
+ )
+
+ if not dirpath or dirpath in dirs_already_excluded:
+ pass
+
+ elif any ( ex ( dirpath ) for ex in dirs_exclude ):
+ self.info (
+ "setupdirs: excluding {!r}\n".format ( dirpath )
+ )
+ dirs_already_excluded.add ( dirpath )
+
+ elif os.path.islink ( dirpath ):
+ self.info (
+ '{!r} is a symlink - skipping setupdir '
+ 'actions.\n'.format ( dirpath )
+ )
+ dirs_already_excluded.add ( dirpath )
+
+ elif dirmask & WANT_USERDIR:
+ if dirmask & WANT_PRIVATE:
+ private_dirs_chown.add ( dirpath )
+ else:
+ shared_dirs_chown.add ( dirpath )
+
+ elif dirmask & WANT_PRIVATE:
+ private_dirs.add ( dirpath )
+
+ else:
+ shared_dirs.add ( dirpath )
+ # -- end for
+
+
+ private_dirs -= private_dirs_chown
+ shared_dirs_chown -= private_dirs
+ shared_dirs -= shared_dirs_chown
+
+ for dirpath in shared_dirs:
+ dodir_shared ( dirpath, chown=False )
+
+ for dirpath in shared_dirs_chown:
+ dodir_shared ( dirpath, chown=True )
+
+ for dirpath in private_dirs:
+ dodir_private ( dirpath, chown=False )
+
+ for dirpath in private_dirs_chown:
+ dodir_private ( dirpath, chown=True )
+
+ self.setup_env.private_dir.chmod_chown ( self.setup_env.work_root )
+ # --- end of do_setupdirs (...) ---
+
+ def do_write_config_file ( self, pretend ):
+ """Writes the config file to disk."""
+ cfile = self.setup_env.get_config_file_path()
+ if not self.config_file_str:
+ self.setup_env.die ( "no config file created!" )
+ elif pretend:
+ self.info ( "Would write config file to {!r}.\n".format ( cfile ) )
+ else:
+ with open ( cfile, 'wt' ) as FH:
+ FH.write ( self.config_file_str )
+
+ self.setup_env.private_file.chmod_chown ( cfile )
+ # --- end of do_write_config_file (...) ---
+
+ def do_enable_default_hooks ( self, pretend ):
+ """Enables the default hooks, e.g. git history creation."""
+ hook_env = self.setup_env.get_hook_env()
+ if not hook_env.enable_defaults():
+ die ( "failed to enable hooks." )
+ # --- end of do_enable_default_hooks (...) ---
+
+# --- end of SetupInitEnvironment ---
+
+
+class HookScript ( object ):
+
+ def __init__ ( self, fspath, filename=None ):
+ super ( HookScript, self ).__init__()
+ fname = (
+ filename if filename is not None else os.path.basename ( fspath )
+ )
+
+ self.fspath = fspath
+ self.name = os.path.splitext ( fname )[0] or fname
+ static_entry = roverlay.static.hookinfo.get ( self.name, None )
+
+ if static_entry is not None:
+ self.default_events = static_entry[0]
+ self.priority = static_entry[1]
+ self.is_hidden = static_entry[2]
+ else:
+ self.default_events = False
+ self.priority = None
+ self.is_hidden = False
+ # --- end of __init__ (...) ---
+
+ def is_visible ( self ):
+ return not self.is_hidden and (
+ self.priority is None or self.priority >= 0
+ )
+ # --- end of is_visible (...) ---
+
+ def __str__ ( self ):
+ yesno = lambda k: 'y' if k else 'n'
+ return "<{cls} {name!r}, hidden={h} prio={p}>".format (
+ cls=self.__class__.__name__,
+ name=self.name,
+ h=yesno ( self.is_hidden ),
+ p=(
+ "auto" if self.priority is None else
+ ( "IGNORE" if self.priority < 0 else self.priority )
+ ),
+ )
+ # --- end of __str__ (...) ---
+
+ def set_priority_from_generator ( self, number_gen, only_if_unset=True ):
+ if self.priority is None:
+ self.priority = next ( number_gen )
+ return True
+ elif only_if_unset or self.priority < 0:
+ return False
+ else:
+ self.priority = next ( number_gen )
+ return True
+ # --- end of set_priority_from_generator (...) ---
+
+ def get_dest_name ( self, file_ext='.sh', digit_len=2 ):
+ # file_ext has to be .sh, else the script doesn't get recognized
+ # by mux.sh
+
+ prio = self.priority
+ if prio is None or prio < 0:
+ raise AssertionError ( "hook script has no priority." )
+
+ return "{prio:0>{l}d}-{fname}{f_ext}".format (
+ prio=prio, fname=self.name, f_ext=file_ext, l=digit_len,
+ )
+ # --- end of get_dest_name (...) ---
+
+
+# --- end of HookScript ---
+
+
+class HookScriptDir ( object ):
+
+ def __init__ ( self, root ):
+ super ( HookScriptDir, self ).__init__()
+
+ self.root = root
+ self._scripts = collections.OrderedDict()
+ # --- end of __init__ (...) ---
+
+ def __bool__ ( self ):
+ return bool ( self._scripts )
+ # --- end of __bool__ (...) ---
+
+ def get_script ( self, name ):
+ script = self._scripts [name]
+ return script if script.is_visible() else None
+ # --- end of get_scripts (...) ---
+
+ def iter_default_scripts ( self, unpack=False ):
+ if unpack:
+ for script in self._scripts.values():
+ if script.default_events:
+ for event in script.default_events:
+ yield ( event, script )
+ else:
+ for script in self._scripts.values():
+ if script.default_events:
+ yield script
+ # --- end of iter_default_scripts (...) ---
+
+ def get_default_scripts ( self ):
+ scripts = dict()
+ for event, script in self.iter_default_scripts ( unpack=True ):
+ if event not in scripts:
+ scripts [event] = [ script ]
+ else:
+ scripts [event].append ( script )
+
+ return scripts
+ # --- end of get_default_scripts (...) ---
+
+ def iter_scripts ( self ):
+ for script in self._scripts.values():
+ if script.is_visible():
+ yield script
+ # --- end of iter_scripts (...) ---
+
+ def scan ( self ):
+ root = self.root
+ try:
+ filenames = sorted ( os.listdir ( root ) )
+ except OSError as oserr:
+ if oserr.errno != errno.ENOENT:
+ raise
+
+ else:
+ for fname in filenames:
+ fspath = root + os.sep + fname
+ if os.path.isfile ( fspath ):
+ script_obj = HookScript ( fspath, fname )
+ self._scripts [script_obj.name] = script_obj
+ # --- end of scan (...) ---
+
+# --- end of HookScriptDir ---
+
+
+class SetupHookEnvironment ( SetupSubEnvironment ):
+
+ NEEDS_CONFIG_TREE = True
+
+ def setup ( self ):
+ additions_dir = self.config.get ( 'OVERLAY.additions_dir', None )
+ if additions_dir:
+ self.user_hook_root = os.path.join ( additions_dir, 'hooks' )
+ self.writable = self.setup_env.private_file.check_writable (
+ self.user_hook_root + os.sep + '.keep'
+ )
+ else:
+ self.user_hook_root = None
+ self.writable = None
+
+ self.hook_root = HookScriptDir (
+ os.path.join ( self.setup_env.data_root, 'hooks' )
+ )
+ self.hook_root.scan()
+ self._prio_gen = roverlay.util.counter.UnsafeCounter ( 30 )
+ # --- end of setup (...) ---
+
+ def _link_hook ( self, source, link ):
+ if os.path.lexists ( link ):
+ linkdest = os.path.realpath ( link )
+
+ message = 'Skipping activation of hook {!r} - '.format ( link )
+
+ if linkdest == source or linkdest == os.path.realpath ( source ):
+ self.info ( message + "already set up.\n" )
+ return True
+
+ elif link != linkdest:
+ # symlink or link was relative
+ self.error ( message + "is a link to another file.\n" )
+ else:
+ self.error ( message + "exists, but is not a link.\n" )
+
+ return None
+ else:
+ return self.setup_env.private_file.symlink ( source, link )
+ # --- end of _link_hook (...) ---
+
+ def link_hooks_v ( self, event_name, hooks ):
+ success = False
+
+ if self.writable and self.user_hook_root:
+ destdir = self.user_hook_root + os.sep + event_name
+ self.setup_env.private_dir.dodir ( destdir )
+
+ to_link = []
+ for script in hooks:
+ script.set_priority_from_generator ( self._prio_gen )
+ to_link.append (
+ ( script.fspath, destdir + os.sep + script.get_dest_name() )
+ )
+
+ success = True
+ for source, link_name in to_link:
+ if self._link_hook ( source, link_name ) is False:
+ success = False
+ # -- end if
+
+ return success
+ # --- end of link_hooks_v (...) ---
+
+ def enable_defaults ( self ):
+ # not strict: missing hooks are ignored
+ success = False
+ if self.hook_root:
+ success = True
+ default_hooks = self.hook_root.get_default_scripts()
+ for event, hooks in default_hooks.items():
+ if not self.link_hooks_v ( event, hooks ):
+ success = False
+ # -- end if
+
+ return success
+ # --- end of enable_defaults (...) ---
+
+
+# --- end of SetupHookEnvironment ---
+
+
+def setup_main():
+ env = SetupEnvironment()
+ env.setup()
+
+ if env.wants_command ( "mkconfig" ):
+ env.write_config_file ( env.options ['output'] )
+ elif env.wants_command ( "init" ):
+ env.get_init_env().run()
+
+
+# --- end of setup_main (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-11 10:19 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-11 10:19 UTC (permalink / raw
To: gentoo-commits
commit: b403b6a3793ff4cca02700da1da0d2b78505956b
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Sep 11 08:18:15 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Sep 11 08:18:15 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b403b6a3
remove setupdirs command from roverlay.py
It's now part of the roverlay setup script.
---
roverlay/argparser.py | 25 ++------------------
roverlay/defaultscript.py | 60 +----------------------------------------------
2 files changed, 3 insertions(+), 82 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index a08cf00..1304874 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -684,7 +684,7 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParser ):
SETUP_TARGETS = (
'version', 'actions', 'config', 'overlay', 'remote',
- 'overlay_creation', 'setupdirs', 'additional_actions', 'misc',
+ 'overlay_creation', 'additional_actions', 'misc',
)
PARSE_TARGETS = ( 'actions', 'config', )
@@ -704,7 +704,6 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParser ):
'apply_rules',
'apply package rules verbosely and exit afterwards'
),
- ( 'setupdirs', 'create configured directories etc.' ),
( 'distmap_rebuild', 'regenerate distmap' ),
))
@@ -716,7 +715,7 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParser ):
if command == 'nop':
roverlay.core.die ( "Nothing to do!", roverlay.core.DIE.NOP )
- elif command in { 'setupdirs', 'distmap_rebuild' }:
+ elif command in { 'distmap_rebuild', }:
self.parsed ['want_logging'] = False
self.parsed ['load_main_only'] = True
@@ -735,26 +734,6 @@ class RoverlayMainArgumentParser ( RoverlayArgumentParser ):
self.command = command
# --- end of parse_actions (...) ---
- def setup_setupdirs ( self ):
- arg = self.add_argument_group (
- 'setupdirs', title='setupdirs options',
- )
-
- arg (
- '--target-uid', dest='target_uid', default=os.getuid(),
- metavar='<uid>', type=is_uid, flags=self.ARG_WITH_DEFAULT,
- help='uid of the user that will run roverlay',
- )
- arg (
- '--target-gid', dest='target_gid', default=os.getgid(),
- metavar='<gid>', type=is_gid, flags=self.ARG_WITH_DEFAULT,
- help='gid of the user that will run roverlay',
- )
-
-
- return arg
- # --- end of setup_setupdirs (...) ---
-
def setup_additional_actions ( self ):
arg = self.add_argument_group (
"additional_actions", title='additional actions',
diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
index 5f47e39..ad87520 100644
--- a/roverlay/defaultscript.py
+++ b/roverlay/defaultscript.py
@@ -40,10 +40,7 @@ def main ( installed, *args, **kw ):
main_env = roverlay.runtime.RuntimeEnvironment ( installed, *args, **kw )
main_env.setup()
- if main_env.want_command ( 'setupdirs' ):
- sys.exit ( run_setupdirs ( main_env ) )
-
- elif run_early_commands ( main_env ):
+ if run_early_commands ( main_env ):
sys.exit ( os.EX_OK )
elif (
@@ -145,61 +142,6 @@ def run_early_commands ( env ):
# --- end of run_early_commands (...) ---
-def run_setupdirs ( env ):
- config = env.config
- target_uid = env.options ['target_uid']
- target_gid = env.options ['target_gid' ]
-
- dodir = roverlay.util.dodir
- find_config_path = roverlay.config.entryutil.find_config_path
-
- dirmode_private = stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP
- #clear_mode = ~(stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
- #get_mode = lambda old, want_mode: ( old & clear_mode ) | want_mode
-
- WANT_USERDIR = roverlay.config.entrymap.WANT_USERDIR
- WANT_PRIVATE = roverlay.config.entrymap.WANT_PRIVATE
- WANT_FILEDIR = roverlay.config.entrymap.WANT_FILEDIR
-
- listlike = lambda a: hasattr(a, '__iter__') and not isinstance(a, str)
- iter_values = lambda b: () if b is None else (b if listlike(b) else ( b, ))
-
- my_uid = os.getuid()
- my_gid = os.getgid()
- should_chown = my_uid != target_uid or my_gid != target_gid
-
- # it's not necessary to create all of the listed dirs because some of
- # them are automatically created at runtime, but doing so results in
- # a (mostly) complete filesystem layout
- #
- for config_key, entry in roverlay.config.entrymap.CONFIG_ENTRY_MAP.items():
- if isinstance ( entry, dict ) and 'want_dir_create' in entry:
- for value in iter_values (
- config.get ( find_config_path ( config_key ), None )
- ):
- dirmask = entry ['want_dir_create']
- dirpath = (
- os.path.dirname ( value.rstrip ( os.sep ) )
- if dirmask & WANT_FILEDIR else value.rstrip ( os.sep )
- )
-
- if dirpath:
- if os.path.islink ( dirpath ):
- sys.stdout.write (
- '{!r} is a symlink - skipping setupdir '
- 'actions.\n'.format ( dirpath )
- )
- else:
- #elif dodir ( dirpath ):
- dodir ( dirpath )
- if dirmask & WANT_PRIVATE:
- os.chmod ( dirpath, dirmode_private )
- if dirmask & WANT_USERDIR and should_chown:
- os.chown ( dirpath, target_uid, target_gid )
-
- return os.EX_OK
-# --- end of run_setupdirs (...) ---
-
def run_distmap_rebuild ( env ):
if env.action_done ( 'distmap_rebuild' ):
return os.EX_OK
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-11 11:14 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-11 11:14 UTC (permalink / raw
To: gentoo-commits
commit: 95937f273a0c6cb15e0c9cc0bd33731cf62444db
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Sep 11 10:40:48 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Sep 11 10:40:48 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=95937f27
runtime: create private _info, _error functions
---
roverlay/runtime.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/roverlay/runtime.py b/roverlay/runtime.py
index 3e251b9..5ef540d 100644
--- a/roverlay/runtime.py
+++ b/roverlay/runtime.py
@@ -284,8 +284,10 @@ class IndependentRuntimeEnvironment ( MinimalRuntimeEnvironment ):
self.stdout = stdout if stdout is not None else sys.stdout
self.stderr = stderr if stderr is not None else sys.stderr
- self.info = self.stdout.write
- self.error = self.stderr.write
+ self._info = self.stdout.write
+ self._error = self.stderr.write
+ self.info = self._info
+ self.error = self._error
if installed:
self.INSTALLINFO = self.access_constant ( 'INSTALLINFO' )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-12 16:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-12 16:36 UTC (permalink / raw
To: gentoo-commits
commit: 6d952e4954d4e1d2aaf76bc66e704ec76b608e34
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 12 16:28:10 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 12 16:28:10 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6d952e49
roverlay/argutil, dirstr(): return abspath
---
roverlay/argutil.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 198ccda..90444a3 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -120,7 +120,7 @@ def dirstr ( value ):
if value[0] == '~':
return value.rstrip ( os.path.sep )
else:
- return os.path.sep + value.strip ( os.path.sep )
+ return os.path.abspath ( value )
else:
raise argparse.ArgumentTypeError (
"cannot create dir-string for {!r}".format ( value )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-12 16:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-12 16:36 UTC (permalink / raw
To: gentoo-commits
commit: 054be945040e7418fa0c100002b7d1bf81b0a25a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 12 16:28:27 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 12 16:28:27 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=054be945
roverlay/argparser: --usage action
---
roverlay/argparser.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 1304874..561951e 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -23,6 +23,17 @@ from roverlay.argutil import \
ArgumentParserProxy
+
+class UsageAction ( argparse.Action ):
+
+ def __call__ ( self, parser, namespace, values, option_string=None ):
+ parser.print_usage()
+ parser.exit()
+ # --- end of __call__ (...) ---
+
+# --- end of UsageAction ---
+
+
class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
DESCRIPTION_TEMPLATE = None
@@ -192,8 +203,16 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
'-V', '--version', action='version',
version=self.defaults.get ( "version", roverlay.core.version )
)
+ return self
# --- end of setup_version (...) ---
+ def setup_usage ( self ):
+ self.arg (
+ '--usage', action=UsageAction, help="print usage", nargs=0,
+ )
+ return self
+ # --- end of setup_usage (...) ---
+
def setup_config_minimal ( self ):
config_arg = self.add_argument_group (
'config', title='config file options'
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-12 16:36 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-12 16:36 UTC (permalink / raw
To: gentoo-commits
commit: f67be36918f6105b692360e1eb186617620eb26d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 12 16:29:15 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 12 16:29:15 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f67be369
roverlay/fsutil: get fs dict from os.walk()
---
roverlay/fsutil.py | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 11 deletions(-)
diff --git a/roverlay/fsutil.py b/roverlay/fsutil.py
index 5efac20..515f214 100644
--- a/roverlay/fsutil.py
+++ b/roverlay/fsutil.py
@@ -5,6 +5,7 @@
# either version 2 of the License, or (at your option) any later version.
import errno
+import functools
import os
import pwd
import stat
@@ -17,17 +18,47 @@ _OS_CHOWN = getattr ( os, 'lchown', os.chown )
_OS_CHMOD = getattr ( os, 'lchmod', os.chmod )
-def readlink_f ( fspath ):
- try:
- f = os.readlink ( fspath )
- except OSError as oserr:
- if oserr.errno in { errno.ENOENT, errno.EINVAL }:
- f = fspath
- else:
- raise
-
- return os.path.abspath ( f )
-# --- end of readlink_f (...) ---
+def get_fs_dict (
+ initial_root, create_item=None, dict_cls=dict,
+ dirname_filter=None, filename_filter=None,
+ include_root=False, prune_empty=False,
+):
+ # http://code.activestate.com/recipes/577879-create-a-nested-dictionary-from-oswalk/
+ fsdict = dict_cls()
+ my_root = os.path.abspath ( initial_root )
+
+ dictpath_begin = (
+ 1 + ( my_root.rfind ( os.sep ) if include_root else len ( my_root ) )
+ )
+
+ for root, dirnames, filenames in os.walk ( initial_root ):
+ if dirname_filter:
+ dirnames[:] = [ d for d in dirnames if dirname_filter ( d ) ]
+
+ if filename_filter:
+ filenames[:] = [ f for f in filenames if filename_filter ( f ) ]
+
+ if not prune_empty or filenames or dirnames:
+ dict_relpath = root[dictpath_begin:]
+
+ if dict_relpath:
+ dictpath = dict_relpath.split ( os.sep )
+ parent = functools.reduce ( dict_cls.get, dictpath[:-1], fsdict )
+
+ if create_item is None:
+ parent [dictpath[-1]] = dict_cls.fromkeys ( filenames )
+ else:
+ parent [dictpath[-1]] = dict_cls (
+ (
+ fname,
+ create_item ( ( root + os.sep + fname ), fname, root )
+ )
+ for fname in filenames
+ )
+ # -- end for
+
+ return fsdict
+# --- end of get_fs_dict (...) ---
def create_subdir_check ( parent, fs_sep=os.sep ):
PARENT_PATH = parent.rstrip ( fs_sep ).split ( fs_sep )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-13 15:10 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-13 15:10 UTC (permalink / raw
To: gentoo-commits
commit: 817a11df3094d960dea9b1b46b17fcdd9e803be5
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 13 14:58:35 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 13 14:58:35 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=817a11df
fsutil: walk_up()
Generator that walks a filesystem path upwards, e.g.
"/a/b/c/d" -> [ "/a/b/c/d", "/a/b/c", "/a/b", "/a" ]
---
roverlay/fsutil.py | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/roverlay/fsutil.py b/roverlay/fsutil.py
index 515f214..7f3296a 100644
--- a/roverlay/fsutil.py
+++ b/roverlay/fsutil.py
@@ -18,6 +18,27 @@ _OS_CHOWN = getattr ( os, 'lchown', os.chown )
_OS_CHMOD = getattr ( os, 'lchmod', os.chmod )
+def walk_up ( dirpath, topdown=False, max_iter=None ):
+ path_elements = os.path.normpath ( dirpath ).split ( os.sep )
+
+ if path_elements:
+ p_start = 0 if path_elements[0] else 1
+
+ if max_iter is None:
+ high = len ( path_elements )
+ else:
+ high = min ( max_iter + p_start, len ( path_elements ) )
+
+
+ if topdown:
+ for k in range ( p_start+1, high+1 ):
+ yield os.sep.join ( path_elements[:k] )
+ else:
+ for k in range ( high, p_start, -1 ):
+ yield os.sep.join ( path_elements[:k] )
+
+# --- end of walk_up (...) ---
+
def get_fs_dict (
initial_root, create_item=None, dict_cls=dict,
dirname_filter=None, filename_filter=None,
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-16 13:43 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-16 13:43 UTC (permalink / raw
To: gentoo-commits
commit: d741cd6327b979d68dcdedba7d051f1faebc19d2
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep 16 10:29:08 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep 16 10:29:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d741cd63
roverlay/core, locate_config_file(): prefer .local
if not installed:
(try to) use R-overlay.conf.local as default config file
and fall back to R-overlay.conf
---
roverlay/core.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/roverlay/core.py b/roverlay/core.py
index 2872c48..1a5ac5c 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -148,6 +148,9 @@ def locate_config_file (
if os.path.isfile ( cfg ):
return cfg
+ elif os.path.exists ( CONFIG_FILE_NAME + '.local' ):
+ return CONFIG_FILE_NAME + '.local'
+
elif os.path.exists ( CONFIG_FILE_NAME ):
return CONFIG_FILE_NAME
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-17 16:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-17 16:40 UTC (permalink / raw
To: gentoo-commits
commit: 653293a8f68cff4c4c4ec24dd416877e2eec1f6a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 17 15:50:43 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 17 15:59:14 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=653293a8
argparser: setup subparsers
---
roverlay/argparser.py | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 5a59dd5..81b3300 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -631,12 +631,18 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
# (required for proper help=...%(default)s, though)
#self.parser.set_defaults ( command=self.default_command )
- subparsers = [
- self.add_subparser ( command )
- for command in self.COMMAND_DESCRIPTION
- ]
- return subparsers
+ subparsers = []
+
+ for command in self.COMMAND_DESCRIPTION:
+ subparser = self.add_subparser (
+ command, proxy_cls=self.__class__.COMMAND_SUBPARSERS[command]
+ )
+ if hasattr ( subparser, 'setup' ):
+ subparser.setup()
+ subparsers.append ( subparser )
+ # -- end if
+ return subparsers
else:
raise AssertionError (
"multiple commands with subparsers is not supported."
@@ -644,7 +650,6 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
# --- end of setup_actions (...) ---
def parse_actions ( self ):
- print ( self.parsed )
self.command = self.parsed ['command']
# --- end of parse_actions (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-17 16:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-17 16:40 UTC (permalink / raw
To: gentoo-commits
commit: f2caad3d9b949a0a0ca52219d467fbdc8c75499d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 17 15:26:08 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 17 15:26:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f2caad3d
argparser,argutil: support subparsers
---
roverlay/argparser.py | 54 +++++++++++++++++++++++++++++++++++-----------
roverlay/argutil.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 100 insertions(+), 14 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 5b28d0f..d52a1e2 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -6,6 +6,7 @@
import argparse
import collections
+import sys
import roverlay.core
import roverlay.argutil
@@ -566,6 +567,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
MULTIPLE_COMMANDS = False
+ COMMAND_SUBPARSERS = None
COMMAND_DESCRIPTION = None
DEFAULT_COMMAND = None
@@ -582,6 +584,18 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
assert self.default_command in self.COMMAND_DESCRIPTION
# --- end of __init__ (...) ---
+ def get_args_to_parse ( self ):
+ if self.__class__.COMMAND_SUBPARSERS is None:
+ return sys.argv[1:]
+ else:
+ args = sys.argv[1:]
+
+ if any ( command in args for command in self.COMMAND_DESCRIPTION ):
+ return args
+ else:
+ return args + [ self.default_command ]
+ # --- end of get_args_to_parse (...) ---
+
def get_commands ( self ):
if self.MULTIPLE_COMMANDS:
return self.command
@@ -590,23 +604,39 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
# --- end of get_commands (...) ---
def setup_actions ( self ):
- arg = self.add_argument_group (
- "actions", title="actions",
- description=self.format_command_map ( self.COMMAND_DESCRIPTION ),
- )
+ if self.__class__.COMMAND_SUBPARSERS is None:
+ arg = self.add_argument_group (
+ "actions", title="actions",
+ description=self.format_command_map ( self.COMMAND_DESCRIPTION ),
+ )
- arg (
- 'command', default=self.default_command, metavar='<action>',
- nargs=( "*" if self.MULTIPLE_COMMANDS else "?" ),
- choices=self.COMMAND_DESCRIPTION.keys(),
- flags=self.ARG_HELP_DEFAULT,
- help="action to perform"
- )
+ arg (
+ 'command', default=self.default_command, metavar='<action>',
+ nargs=( "*" if self.MULTIPLE_COMMANDS else "?" ),
+ choices=self.COMMAND_DESCRIPTION.keys(),
+ flags=self.ARG_HELP_DEFAULT,
+ help="action to perform"
+ )
- return arg
+ return arg
+ else:
+ self.add_subparsers (
+ title="commands",
+ description=self.format_command_map ( self.COMMAND_DESCRIPTION ),
+ dest="command",
+ help="action to perform [%(default)s]",
+ )
+ # set_defaults() not necessary due to get_args_to_parse()
+ self.parser.set_defaults ( command=self.default_command )
+
+ for command in self.COMMAND_DESCRIPTION:
+ subparser = self.add_subparser ( command )
+
+ return None
# --- end of setup_actions (...) ---
def parse_actions ( self ):
+ print ( self.parsed )
self.command = self.parsed ['command']
# --- end of parse_actions (...) ---
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index c3981e5..7c36980 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -8,6 +8,7 @@ import os
import argparse
import pwd
import grp
+import sys
from roverlay.config.entryutil import deref_entry_safe
@@ -158,6 +159,9 @@ class ArgumentParserError ( Exception ):
class ArgumentGroupExists ( ArgumentParserError ):
pass
+class SubparserExists ( ArgumentParserError ):
+ pass
+
class ArgumentFlagException ( ArgumentParserError ):
pass
@@ -207,10 +211,54 @@ class ArgumentParserProxy ( object ):
self.defaults = dict ( defaults )
self._argument_groups = dict()
+ self._subparsers = dict()
+ self._subparser_ctrl = None
self.parsed = None
# --- end of __init__ (...) ---
+ def add_subparsers ( self, ignore_exist=False, **kwargs ):
+ if self._subparser_ctrl is None:
+ self._subparser_ctrl = self.parser.add_subparsers ( **kwargs )
+ elif not ignore_exist:
+ raise AssertionError ( "add_subparsers() already called!" )
+
+ return self._subparser_ctrl
+ # --- end of add_subparsers (...) ---
+
+ def add_subparser ( self,
+ command, defaults=True, proxy_cls=None, **parser_kwargs
+ ):
+ if command in self._subparsers:
+ raise SubparserExists ( command )
+ else:
+ if proxy_cls is None:
+ get_proxy = ArgumentParserProxy.wrap
+ elif proxy_cls is True:
+ get_proxy = self.__class__.wrap
+ elif hasattr ( proxy_cls, 'wrap' ):
+ get_proxy = proxy_cls.wrap
+ else:
+ get_proxy = proxy_cls
+
+ parser = (
+ self.add_subparsers ( ignore_exist=True ).add_parser (
+ command, **parser_kwargs
+ )
+ )
+
+ proxy = get_proxy (
+ parser,
+ defaults = ( self.defaults if defaults is True else defaults )
+ )
+ self._subparsers [command] = proxy
+ return proxy
+ # --- end of add_subparser (...) ---
+
+ def get_subparser ( self, name ):
+ return self._subparsers [name]
+ # --- end of get_subparser (...) ---
+
def get_options ( self ):
return self.parsed
# --- end of get_options (...) ---
@@ -331,12 +379,20 @@ class ArgumentParserProxy ( object ):
)
# --- end of group_arg (...) ---
- def parse_args ( self, *args, **kwargs ):
- self.parsed = self.parser.parse_args ( *args, **kwargs )
+ def get_args_to_parse ( self ):
+ return sys.argv[1:]
+ # --- end of get_args_to_parse (...) ---
+
+ def parse_args ( self, args=None, namespace=None ):
+ self.parsed = self.parser.parse_args (
+ args = ( self.get_args_to_parse() if args is None else args ),
+ namespace = namespace,
+ )
return self.parsed
# --- end of parse_args (...) ---
def parse ( self, *args, **kwargs ):
+ print ( "ArgumentParserProxy.parse() is deprecated. Use parse_args()." )
return self.parse_args ( *args, **kwargs )
# --- end of parse (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-17 16:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-17 16:40 UTC (permalink / raw
To: gentoo-commits
commit: 43c0ad633946458d8d185e8a456a6379e55dbb82
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 17 16:40:32 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 17 16:40:32 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=43c0ad63
argparser: subparse_parsed()
---
roverlay/argparser.py | 18 +++++++++++++++++-
roverlay/argutil.py | 4 ++--
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index 81b3300..04feff8 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -123,6 +123,17 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
def parse ( self, *args, **kwargs ):
self.parse_args ( *args, **kwargs )
parsed = vars ( self.parsed )
+ return self.parse_parsed ( parsed )
+ # --- end of parse (...) ---
+
+ def subparse_parsed ( self, parsed ):
+ self.parsed = parsed
+ if hasattr ( self.__class__, 'PARSE_TARGETS' ):
+ for attr in self.__class__.PARSE_TARGETS:
+ getattr ( self, 'parse_' + attr )()
+ # --- end of subparse_parsed (...) ---
+
+ def parse_parsed ( self, parsed ):
self.parsed = parsed
self.extra_conf = dict()
@@ -189,7 +200,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
if hasattr ( self.__class__, 'PARSE_TARGETS' ):
for attr in self.__class__.PARSE_TARGETS:
getattr ( self, 'parse_' + attr )()
- # --- end of parse (...) ---
+ # --- end of parse_parsed (...) ---
def setup ( self ):
if hasattr ( self.__class__, 'SETUP_TARGETS' ):
@@ -651,6 +662,11 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
def parse_actions ( self ):
self.command = self.parsed ['command']
+
+ if self.__class__.COMMAND_SUBPARSERS:
+ subparser = self.get_subparser ( self.command )
+ if hasattr ( subparser, 'subparse_parsed' ):
+ subparser.subparse_parsed ( self.parsed )
# --- end of parse_actions (...) ---
# --- end of RoverlayArgumentParser ---
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 7c36980..b8f8363 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -314,7 +314,7 @@ class ArgumentParserProxy ( object ):
if default is argparse.SUPPRESS:
default_str = self.STR_SUPPRESS
- elif default in { True, False }:
+ elif default is True or default is False:
if flags & self.ARG_INVERSE:
default_str = self.STR_FALSE if default else self.STR_TRUE
else:
@@ -392,7 +392,7 @@ class ArgumentParserProxy ( object ):
# --- end of parse_args (...) ---
def parse ( self, *args, **kwargs ):
- print ( "ArgumentParserProxy.parse() is deprecated. Use parse_args()." )
+ # likely overridden by derived classes
return self.parse_args ( *args, **kwargs )
# --- end of parse (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-17 16:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-17 16:40 UTC (permalink / raw
To: gentoo-commits
commit: 121aa5600cb23ef787fe0ede4d360158bbed8b52
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Sep 17 15:40:14 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Sep 17 15:40:14 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=121aa560
argparser: forbid "multiple commands + subparsers"
---
roverlay/argparser.py | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/roverlay/argparser.py b/roverlay/argparser.py
index d52a1e2..5a59dd5 100644
--- a/roverlay/argparser.py
+++ b/roverlay/argparser.py
@@ -619,7 +619,8 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
)
return arg
- else:
+
+ elif not self.MULTIPLE_COMMANDS:
self.add_subparsers (
title="commands",
description=self.format_command_map ( self.COMMAND_DESCRIPTION ),
@@ -627,12 +628,19 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ):
help="action to perform [%(default)s]",
)
# set_defaults() not necessary due to get_args_to_parse()
- self.parser.set_defaults ( command=self.default_command )
+ # (required for proper help=...%(default)s, though)
+ #self.parser.set_defaults ( command=self.default_command )
- for command in self.COMMAND_DESCRIPTION:
- subparser = self.add_subparser ( command )
+ subparsers = [
+ self.add_subparser ( command )
+ for command in self.COMMAND_DESCRIPTION
+ ]
+ return subparsers
- return None
+ else:
+ raise AssertionError (
+ "multiple commands with subparsers is not supported."
+ )
# --- end of setup_actions (...) ---
def parse_actions ( self ):
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-19 15:00 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-19 15:00 UTC (permalink / raw
To: gentoo-commits
commit: ff58bf49699682c31786b05072e7fe65bb3bb50e
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 19 14:59:23 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 19 14:59:23 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ff58bf49
fsutil: accept file_key function
---
roverlay/fsutil.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/roverlay/fsutil.py b/roverlay/fsutil.py
index b8a69ab..7fede96 100644
--- a/roverlay/fsutil.py
+++ b/roverlay/fsutil.py
@@ -44,12 +44,14 @@ def walk_up ( dirpath, topdown=False, max_iter=None ):
def get_fs_dict (
initial_root, create_item=None, dict_cls=dict,
dirname_filter=None, filename_filter=None,
- include_root=False, prune_empty=False,
+ include_root=False, prune_empty=False, file_key=None,
):
# http://code.activestate.com/recipes/577879-create-a-nested-dictionary-from-oswalk/
fsdict = dict_cls()
my_root = os.path.abspath ( initial_root )
+ get_file_key = ( lambda x: x ) if file_key is None else file_key
+
dictpath_begin = (
1 + ( my_root.rfind ( os.sep ) if include_root else len ( my_root ) )
)
@@ -69,11 +71,13 @@ def get_fs_dict (
parent = functools.reduce ( dict_cls.get, dictpath[:-1], fsdict )
if create_item is None:
- parent [dictpath[-1]] = dict_cls.fromkeys ( filenames )
+ parent [dictpath[-1]] = dict_cls.fromkeys (
+ map ( get_file_key, filenames )
+ )
else:
parent [dictpath[-1]] = dict_cls (
(
- fname,
+ get_file_key ( fname ),
create_item ( ( root + os.sep + fname ), fname, root )
)
for fname in filenames
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-20 15:57 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-20 15:57 UTC (permalink / raw
To: gentoo-commits
commit: b26619285c74e85a7db260834da7cdda3bab0e2d
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 20 14:47:41 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 20 14:47:41 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b2661928
roverlay/fsutil: comments, cleanup
Also contains some fixes, e.g. handle "/" properly in walk_up().
---
roverlay/fsutil.py | 668 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 565 insertions(+), 103 deletions(-)
diff --git a/roverlay/fsutil.py b/roverlay/fsutil.py
index 7fede96..309aadc 100644
--- a/roverlay/fsutil.py
+++ b/roverlay/fsutil.py
@@ -4,6 +4,7 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
+import abc
import errno
import functools
import itertools
@@ -21,24 +22,54 @@ _OS_CHMOD = getattr ( os, 'lchmod', os.chmod )
def walk_up ( dirpath, topdown=False, max_iter=None ):
- path_elements = os.path.normpath ( dirpath ).split ( os.sep )
+ """Generator that yields all (partial..full) filesystem paths contained
+ in dirpath.
- if path_elements:
- p_start = 0 if path_elements[0] else 1
+ Examples:
+ walk_up (
+ "/a/b/c/d", topdown=False, max_iter=None
+ ) -> ( "/a/b/c/d", "/a/b/c", "/a/b", "/a", "/" )
- if max_iter is None:
- high = len ( path_elements )
- else:
- high = min ( max_iter + p_start, len ( path_elements ) )
+ walk_up ( "/" ) -> ( "/" )
+ walk_up ( "/b", topdown=True ) -> ( "/", "/b" )
- if topdown:
- for k in range ( p_start+1, high+1 ):
- yield os.sep.join ( path_elements[:k] )
- else:
- for k in range ( high, p_start, -1 ):
- yield os.sep.join ( path_elements[:k] )
+ arguments:
+ * topdown -- Defaults to False.
+ * max_iter -- max number of paths to generate (None for unlimited)
+ Defaults to None.
+ """
+ def iter_partial_paths ( _join_path=os.sep.join ):
+ fspath = os.path.normpath ( dirpath ).rstrip ( os.sep )
+ path_elements = fspath.split ( os.sep )
+
+ if path_elements:
+ p_start = 0 if path_elements[0] else 1
+ high = len ( path_elements )
+
+ if topdown:
+ if not path_elements[0]:
+ yield os.sep
+
+ for k in range ( p_start+1, high+1 ):
+ yield _join_path ( path_elements[:k] )
+ else:
+ for k in range ( high, p_start, -1 ):
+ yield _join_path ( path_elements[:k] )
+
+ if not path_elements[0]:
+ yield os.sep
+ # --- end of iter_partial_paths (...) ---
+ if max_iter is None:
+ for path in iter_partial_paths():
+ yield path
+ else:
+ for n, path in enumerate ( iter_partial_paths() ):
+ if n < max_iter:
+ yield path
+ else:
+ return
# --- end of walk_up (...) ---
def get_fs_dict (
@@ -46,7 +77,40 @@ def get_fs_dict (
dirname_filter=None, filename_filter=None,
include_root=False, prune_empty=False, file_key=None,
):
- # http://code.activestate.com/recipes/577879-create-a-nested-dictionary-from-oswalk/
+ """Creates a dictionary-like object representing the filesystem structure
+ starting at the given root directory.
+
+ arguments:
+ * initial_root -- root directory where os.walk should start
+ * create_item -- Either a function that accepts 3 args (absolute file-
+ system path, filename, absolute dirpath) and returns
+ an object representing a file entry or None (resulting
+ in None being the object). Defaults to None.
+ * dict_cls -- dictionary class. Defaults to dict.
+ Has to have a constructor accepting an iterable
+ of 2-tuples (key,file entry or dict_cls object)
+ if create_item is set, or a .fromkeys() method
+ accepting an iterable of keys.
+ Additionally, has to provide a __setitem__ method.
+ * dirname_filter -- Either a function that returns True if a directory
+ name is allowed and False if not, or None (do not
+ restrict dirnames). Defaults to None.
+ This also affects which directory paths are traversed.
+ * filename_filter -- Similar to dirname_filter, but can be used to ignore
+ files. Defaults to None.
+ * include_root -- Whether to make initial_root the dict root (False)
+ or an item in the dict (True). In other words,
+ controls whether the return value should be a dict
+ starting at initial_root or a dict containing the
+ initial_root dict. Defaults to False.
+ * prune_empty -- Whether to remove directory entries without any items.
+ Defaults to False.
+ * file_key -- Either a function that returns the dict key for a
+ file name or None (idendity, key==filename).
+
+ Inspired by http://code.activestate.com/recipes/577879-create-a-nested-dictionary-from-oswalk/
+ """
+ # TODO(could-do): max_depth=N
fsdict = dict_cls()
my_root = os.path.abspath ( initial_root )
@@ -88,15 +152,38 @@ def get_fs_dict (
# --- end of get_fs_dict (...) ---
def create_subdir_check ( parent, fs_sep=os.sep ):
+ """Returns a function that checks whether a given filesystem path is a
+ subpath of parent (where parent is a subpath of itself).
+
+ arguments:
+ * parent -- parent filesystem path for which a subdir_check should be
+ created
+ * fs_sep -- defaults to os.sep
+ """
PARENT_PATH = parent.rstrip ( fs_sep ).split ( fs_sep )
- def is_subdir ( dirpath ):
- return all (
- this == expect for this, expect in zip (
- dirpath.rstrip ( fs_sep ).split ( fs_sep ),
- PARENT_PATH
+ def is_subdir ( dirpath,
+ _path_el=PARENT_PATH, _path_len=len( PARENT_PATH ), _fs_sep=fs_sep
+ ):
+ """Returns True if the given filesystem path is a subpath of the
+ (predefined) parent path, else False.
+
+ arguments:
+ * dirpath -- filesystem path to be checked
+ * _path_el -- local variable containing information about the parent
+ path. Shouldn't be set manually.
+ * _path_len -- local variable containing information about the length
+ of the parent path. Shouldn't be set manually.
+ * _fs_sep -- local variable that is a copy of fs_sep.
+ Shouldn't be set manually.
+ """
+ dirpath_el = dirpath.rstrip ( _fs_sep ).split ( _fs_sep )
+ if len ( dirpath_el ) < _path_len:
+ return False
+ else:
+ return all (
+ this == expect for this, expect in zip ( dirpath_el, _path_el )
)
- )
# --- end of is_subdir (...) ---
return is_subdir
@@ -104,6 +191,15 @@ def create_subdir_check ( parent, fs_sep=os.sep ):
def pwd_expanduser ( fspath, uid ):
+ """Expands "~" in a filesystem path to the given user's home directory.
+ Uses pwd to get that directory.
+
+ Returns: expanded path
+
+ arguments:
+ * fspath --
+ * uid --
+ """
if not fspath or fspath[0] != '~':
return fspath
elif len ( fspath ) < 2:
@@ -115,6 +211,32 @@ def pwd_expanduser ( fspath, uid ):
# --- end of pwd_expanduser (...) ---
def walk_copy_tree ( source, dest, subdir_root=False, **walk_kwargs ):
+ """Generator that iterates over the content of a filesystem tree starting
+ at source and compares it to the filesystem tree starting at dest (which
+ doesn't have to exist). The subdir_root can be used to control whether
+ source should be a subdir of dest or not (which means that
+ walk_copy_tree (source, dest, subdir_root=True) is identical to
+ walk_copy_tree (source, dest + os.sep + os.path.basename(source),
+ subdir_root=False)).
+
+ The items are 6-tuples (absolute path to the source directory,
+ absolute path to the dest dir, dir path relative to the source root,
+ list of directories, list of files, list of dirnames).
+
+ The dirnames list can be modified (slice assignment) in order to affect
+ the directories visited by os.walk().
+
+ The directories/files lists are lists of 2x2-tuples (
+ (abspath in source, stat in source), (abspath in dest, stat in dest)
+ ).
+
+ arguments:
+ * source -- absolute path to the source root
+ * dest -- absolute path to the dest root
+ * subdir_root -- whether source should be a subdir of dest root or not
+ Defaults to False.
+ * **walk_kwargs -- additional keyword arguments for os.walk()
+ """
source_path = os.path.abspath ( source )
dest_path = os.path.abspath ( dest )
relpath_begin = 1 + (
@@ -139,9 +261,21 @@ def walk_copy_tree ( source, dest, subdir_root=False, **walk_kwargs ):
# --- end of walk_copy_tree (...) ---
class RWX ( object ):
+ """An object representing read/write/execute permissions."""
@classmethod
def from_str ( cls, s, strict=False ):
+ """Parses the given string and returns a new RWX object.
+
+ arguments:
+ * s -- a string, e.g. "rwx" or "r-x"
+ * strict -- if True: expect that is a string with length >= 3, where
+ read/write/executable is set to True if the
+ first/second/third char is r/w/x and False
+ otherwise.
+ else : set read/write/executable to True if s contains
+ r/w/x and False otherwise
+ """
readable, writable, executable = False, False, False
if strict:
@@ -166,12 +300,27 @@ class RWX ( object ):
@classmethod
def from_bitmask ( cls, mode, rwx_bits ):
+ """Compares the given mode with a list of r/w/x bits and creates a
+ RWX object for it.
+
+ arguments:
+ * mode -- integer containing r/w/x (and possible other) bits
+ * rwx_bits -- a list/tuple with at least three elements, where the
+ first/second/third element is the read/write/executable bit
+ """
return cls (
mode & rwx_bits[0], mode & rwx_bits[1], mode & rwx_bits[2],
)
# --- end of from_bitmask (...) ---
def __init__ ( self, readable, writable, executable ):
+ """RWX Constructor.
+
+ arguments:
+ * readable -- bool
+ * writable -- bool
+ * executable -- bool
+ """
super ( RWX, self ).__init__()
self.readable = bool ( readable )
self.writable = bool ( writable )
@@ -179,6 +328,7 @@ class RWX ( object ):
# --- end of __init__ (...) ---
def __hash__ ( self ):
+ # could be removed (or replaced by a more proper __hash__ func)
return id ( self )
# --- end of __hash__ (...) ---
@@ -190,17 +340,30 @@ class RWX ( object ):
)
# --- end of __repr__ (...) ---
- def get_str ( self, fillchar='-' ):
+ def get_str ( self, fillchar='-', rwx_chars="rwx" ):
+ """Returns a string similar to what ls would show ("rwx","r--",...).
+
+ arguments:
+ * fillchar -- char that is used to express absense of read/write/exe
+ Defaults to "-".
+ * rwx_chars -- a sequence of at least three chars. Defaults to "rwx."
+
+ """
return (
- ( 'r' if self.readable else fillchar ) +
- ( 'w' if self.writable else fillchar ) +
- ( 'x' if self.executable else fillchar )
+ ( rwx_chars[0] if self.readable else fillchar ) +
+ ( rwx_chars[1] if self.writable else fillchar ) +
+ ( rwx_chars[2] if self.executable else fillchar )
)
# --- end of get_str (...) ---
__str__ = get_str
def get_bitmask ( self, rwx_bits ):
+ """Returns an integer representing the rwx mode for the given rwx bits.
+
+ arguments:
+ * rwx_bits -- a list/tuple with at least three elements (r,w,x)
+ """
ret = 0
if self.readable:
ret |= rwx_bits[0]
@@ -218,6 +381,8 @@ class RWX ( object ):
class FsPermissions ( object ):
+ """An object representing read/write/execute permissions for users, groups
+ and others."""
USR_BITS = ( stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR )
GRP_BITS = ( stat.S_IRGRP, stat.S_IWGRP, stat.S_IXGRP )
@@ -225,6 +390,13 @@ class FsPermissions ( object ):
@classmethod
def from_str ( cls, s, strict=False ):
+ """Returns a new permissions object for the given string.
+
+ arguments:
+ * s -- the string, e.g. "rwxr-x---" or "r---x---w"
+ * strict -- affects how strings are parsed.
+ see RWX.from_str() for details. Defaults to False.
+ """
rwx_user = RWX.from_str ( s[0:3], strict=strict )
rwx_group = RWX.from_str ( s[3:6], strict=strict )
rwx_others = RWX.from_str ( s[6:9], strict=strict )
@@ -233,6 +405,11 @@ class FsPermissions ( object ):
@classmethod
def from_stat_mode ( cls, stat_mode ):
+ """Creates a permissions object for the given stat mode.
+
+ arguments:
+ * stat_mode -- stat mode as its returned by os.stat() (and others)
+ """
return cls (
RWX.from_bitmask ( stat_mode, cls.USR_BITS ),
RWX.from_bitmask ( stat_mode, cls.GRP_BITS ),
@@ -241,6 +418,13 @@ class FsPermissions ( object ):
# --- end of from_stat_mode (...) ---
def __init__ ( self, rwx_user, rwx_group, rwx_others ):
+ """FsPermissions constructor.
+
+ arguments:
+ * rwx_user -- RWX object
+ * rwx_group -- RWX object
+ * rwx_others -- RWX object
+ """
super ( FsPermissions, self ).__init__()
self.user = rwx_user
self.group = rwx_group
@@ -256,6 +440,11 @@ class FsPermissions ( object ):
# --- end of __repr__ (...) ---
def get_str ( self, fillchar='-' ):
+ """Returns an ls-like string.
+
+ arguments:
+ * fillchar -- defaults to "-"
+ """
return "".join (
rwx.get_str ( fillchar=fillchar )
for rwx in ( self.user, self.group, self.others )
@@ -265,6 +454,7 @@ class FsPermissions ( object ):
__str__ = get_str
def get_stat_mode ( self ):
+ """Returns an integer that can be used for os.[l]chmod()."""
return (
self.user.get_bitmask ( self.USR_BITS ) |
self.group.get_bitmask ( self.GRP_BITS ) |
@@ -278,12 +468,29 @@ class FsPermissions ( object ):
# --- end of FsPermissions ---
def get_stat_mode ( mode_str ):
+ """Converts a permissions string into an integer.
+
+ arguments:
+ * mode_str -- "rwx------" etc.
+ """
return FsPermissions.from_str ( mode_str ).get_stat_mode()
# --- end of get_stat_mode (...) ---
class ChownChmod ( object ):
+ """An object for chown()/chmod() operations."""
+ # COULDFIX: remove / merge with AbstractFsOperations
+ # this allows to recursively chmod files and dirs
def __init__ ( self, uid=None, gid=None, mode=None, pretend=False ):
+ """ChownChmod constructor.
+
+ arguments:
+ * uid -- uid for chown() or None (keep uid). Defaults to None.
+ * gid -- gid for chown() or None (keep gid). Defaults to None.
+ * mode -- int mode for chmod() or None (keep mode). Defaults to None.
+ * pretend -- whether to actually chown/chmod (False) or just print
+ what would be done (True). Defaults to False.
+ """
super ( ChownChmod, self ).__init__()
self.pretend = bool ( pretend )
@@ -324,17 +531,37 @@ class ChownChmod ( object ):
# --- end of __init__ (...) ---
def _nullfunc ( self, fspath ):
+ """No-op replacement for chown()/chmod().
+
+ arguments:
+ * fspath -- ignore
+ """
return None
def _do_chown ( self, fspath, _chown=_OS_CHOWN ):
+ """Calls chown(fspath)
+
+ arguments:
+ * fspath --
+ """
_chown ( fspath, self.uid, self.gid )
return self.chown_str.format ( fspath )
def _do_chmod ( self, fspath, _chmod=_OS_CHMOD ):
+ """Calls chmod(fspath).
+
+ arguments:
+ * fspath --
+ """
_chmod ( fspath, self.mode )
return self.chmod_str.format ( fspath )
def chown_chmod ( self, fspath ):
+ """Calls chmod(fspath) and chown(fspath).
+
+ arguments:
+ * fspath --
+ """
# should be renamed to chmod_chown()
return (
self.chmod ( fspath ),
@@ -342,48 +569,50 @@ class ChownChmod ( object ):
)
# --- end of chown_chmod (...) ---
- def chown_chmod_recursive ( self, root ):
- chown = self.chown
- chmod = self.chmod
-
- if os.path.isfile ( root ):
- yield chmod ( root )
- yield chown ( root )
-
- else:
- for current_root, dirnames, filenames in os.walk ( root ):
- yield chmod ( current_root )
- yield chown ( current_root )
-
- for filename in filenames:
- fpath = current_root + os.sep + filename
- yield chmod ( fpath )
- yield chown ( fpath )
- # --- end of chown_chmod_recursive (...) ---
-
# --- end of ChownChmod ---
-def chown_chmod ( root, uid=None, gid=None, mode=None, pretend=False ):
- return ChownChmod ( uid, gid, mode, pretend ).chown_chmod ( root )
-# --- end of chown_chmod (...) ---
+def chown_chmod ( fspath, uid=None, gid=None, mode=None, pretend=False ):
+ """Calls chmod(fspath) and chown(fspath) after creating an intermediate
+ ChownChmod instance.
-def chown_chmod_recursive (
- root, uid=None, gid=None, mode=None, pretend=False
-):
- return ChownChmod (
- uid, gid, mode, pretend ).chown_chmod_recursive ( root )
-# --- end of chown_chmod_recursive (...) ---
+ arguments:
+ * fspath --
+ * uid --
+ * gid --
+ * mode --
+ * pretend --
+ """
+ return ChownChmod ( uid, gid, mode, pretend ).chown_chmod ( fspath )
+# --- end of chown_chmod (...) ---
-class AbstractFsOperations ( object ):
+class AbstractFsOperations ( roverlay.util.objects.AbstractObject ):
+ """Base object for performing filesystem operations."""
- PRETEND = None
+ @abc.abstractproperty
+ def PRETEND ( self ):
+ """A bool that indicates whether fs operations should be fully virtual
+ (print what would be done) or not.
+ Needs to be set by derived classes (as class-wide attribute).
+ """
+ return None
def __init__ ( self,
stdout=None, stderr=None, uid=None, gid=None,
file_mode=None, dir_mode=None
):
+ """AbstractFsOperations constructor.
+
+ arguments:
+ * stdout -- stdout stream. Defaults to sys.stdout
+ * stderr -- stderr stream. Defaults to sys.stderr
+ * uid -- uid for chown(). Defaults to None (keep uid).
+ * gid -- gid for chown(). Defaults to None (keep gid).
+ * file_mode -- mode for chmod(<file>). Defaults to None (don't change
+ mode). Can also be an ls-like str, e.g. "rwxr-x---".
+ * dir_mode -- mode for chmod(<file>). Defaults to None.
+ """
if self.__class__.PRETEND is None:
raise AssertionError ( "derived classes have to set PRETEND." )
@@ -400,23 +629,42 @@ class AbstractFsOperations ( object ):
self.info = self._stdout.write
self.error = self._stderr.write
-
- self._setup()
# --- end of __init__ (...) ---
- def _setup ( self ):
- pass
- # --- end of _setup (...) ---
-
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def _dodir ( self, dirpath, mkdir_p ):
- pass
+ """Ensures that a directory exists, by creating it if necessary.
+ Also creates parent directories if mkdir_p evaluates to True.
+
+ Returns: success (True/False)
- @roverlay.util.objects.abstractmethod
+ arguments:
+ * dirpath
+ * mkdir_p
+ """
+ return
+
+ @abc.abstractmethod
def do_touch ( self, fspath ):
- pass
+ """Similar to "touch <fspath>".
+
+ Returns: success (True/False)
+
+ Raises: IOError, OSError
+ """
+ return
def chown ( self, fspath ):
+ """Calls chown_dir(fspath) or chown_file(fspath), depending on whether
+ fspath is a directory or not.
+
+ Returns: success (passed from chown_dir()/chown_file())
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
if os.path.isdir ( fspath ):
return self.chown_dir ( fspath )
else:
@@ -424,21 +672,60 @@ class AbstractFsOperations ( object ):
# --- end of chown (...) ---
def chown_stat ( self, fspath, mode ):
+ """Similar to chown(fspath), but checks the given mode in order to
+ decide whether fspath is a dir.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ * mode -- stat mode
+ """
if stat.S_ISDIR ( mode ):
return self.chown_dir ( fspath )
else:
return self.chown_file ( fspath )
# --- end of chown_stat (...) ---
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def chown_dir ( self, fspath ):
- pass
+ """Changes the owner of a directory.
+
+ Returns: success (True/False)
- @roverlay.util.objects.abstractmethod
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
+ return
+
+ @abc.abstractmethod
def chown_file ( self, fspath ):
- pass
+ """Changes the owner of a file.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
+ return
def chmod ( self, fspath ):
+ """Calls chmod_dir(fspath) or chmod_file(fspath), depending on whether
+ fspath is a directory or not.
+
+ Returns: success (passed from chmod_dir()/chmod_file())
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
if os.path.isdir ( fspath ):
return self.chmod_dir ( fspath )
else:
@@ -446,25 +733,59 @@ class AbstractFsOperations ( object ):
# --- end of chmod (...) ---
def chmod_stat ( self, fspath, mode ):
+ """Similar to chmod(fspath), but checks the given mode in order to
+ decide whether fspath is a dir.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ * mode -- stat mode
+ """
if stat.S_ISDIR ( mode ):
return self.chmod_dir ( fspath )
else:
return self.chmod_file ( fspath )
# --- end of chmod_stat (...) ---
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def chmod_dir ( self, fspath ):
- pass
+ """Changes the mode of a directory.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
+ return
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def chmod_file ( self, fspath ):
- pass
+ """Changes the mode of a file.
- def chmod_chown ( self, fspath ):
- self.chmod ( fspath )
- self.chown ( fspath )
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
+ return
def chmod_chown ( self, fspath ):
+ """Performs both chmod(fspath) and chown(fspath).
+
+ Returns: 2-tuple ( chmod_success, chown_success )
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ """
if os.path.isdir ( fspath ):
return (
self.chmod_dir ( fspath ), self.chown_dir ( fspath )
@@ -476,6 +797,17 @@ class AbstractFsOperations ( object ):
# --- end of chmod (...) ---
def chmod_chown_stat ( self, fspath, mode ):
+ """Similar to chmod_chown(), but checks mode in order to decide whether
+ fspath is a dir.
+
+ Returns: 2-tuple ( chmod_success, chown_success )
+
+ Raises: OSError
+
+ arguments:
+ * fspath --
+ * mode -- stat mode
+ """
if stat.S_ISDIR ( mode ):
return (
self.chmod_dir ( fspath ), self.chown_dir ( fspath )
@@ -486,16 +818,37 @@ class AbstractFsOperations ( object ):
)
# --- end of chmod_stat (...) ---
- @roverlay.util.objects.abstractmethod
- def chmod_chown_recursive ( self, root ):
- pass
-
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def _copy_file ( self, source, dest ):
- pass
+ """Copies a file from source to dest.
+
+ Returns: success (True/False)
+
+ Raises: undefined, IOError/OSError are likely
+
+ arguments:
+ * source --
+ * dest --
+ """
+ return
# --- end of _copy_file (...) ---
def copy_file ( self, source, dest, chown=True, chmod=True ):
+ """Copies a file from source to dest and calls chmod(),chown()
+ afterwards.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * source --
+ * dest --
+ * chown -- bool that controls whether chown() should be called.
+ Defaults to True.
+ * chmod -- bool that controls whether chmod() should be called.
+ Defaults to True.
+ """
if self._copy_file ( source, dest ):
if chmod:
self.chmod_file ( dest )
@@ -508,6 +861,23 @@ class AbstractFsOperations ( object ):
# --- end of copy_file (...) ---
def dodir ( self, dirpath, mkdir_p=True, chown=True, chmod=True ):
+ """Ensures that a directory exists by creating it if necessary.
+ Also calls chmod(), chown() afterwards.
+
+ Returns: success (True/False)
+
+ Raises: OSError
+
+ arguments:
+ * dirpath --
+ * mkdir_p -- whether to create parent directories as well (if necessary)
+ Defaults to True.
+ * chown -- bool that controls whether chown() should be called.
+ Defaults to True.
+ * chmod -- bool that controls whether chmod() should be called.
+ Defaults to True.
+ """
+
if self._dodir ( dirpath, mkdir_p=mkdir_p ):
if chmod:
self.chmod_dir ( dirpath )
@@ -520,30 +890,80 @@ class AbstractFsOperations ( object ):
# --- end of dodir (...) ---
def dodirs ( self, *dirs, **kwargs ):
+ """Calls dodir(dir) for each dir in dirs.
+
+ arguments:
+ * *dirs --
+ * **kwargs -- keyword arguments for dodir()
+ """
for dirpath in dirs:
self.dodir ( dirpath, **kwargs )
# --- end of dodirs (...) ---
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def rmdir ( self, dirpath ):
- pass
+ """Removes an empty directory.
+
+ Returns: success (True/False)
+
+ arguments:
+ * dirpath --
+ """
+ return
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def unlink ( self, fspath ):
- pass
+ """Removes a file (or link).
+
+ Returns: success (True/False)
+
+ arguments:
+ * fspath --
+ """
+ return
def wipe ( self, fspath ):
+ """Removes fspath if it is an empty directory or a file (or link).
+
+ Returns: success (True/False)
+
+ arguments:
+ * fspath --
+ """
return self.rmdir ( fspath ) or self.unlink ( fspath )
- @roverlay.util.objects.abstractmethod
+ @abc.abstractmethod
def symlink ( self, source, link_name ):
- pass
+ """Creates a symlink.
+
+ Returns: success (True/False)
+
+ arguments:
+ * source --
+ * link_name --
+ """
+ return
def check_writable ( self,
fspath, mkdir_chown=False, mkdir_chmod=False, mkdir_p=True
):
"""Checks whether fspath can be written. This creates all necessary
- directories."""
+ directories and creates fspath as empty file.
+
+ Returns: success (True/False)
+
+ Raises: passes IOError,OSError unless its error code is related to
+ missing write permissions
+
+ arguments:
+ * fspath --
+ * mkdir_chown -- bool that controls whether created directories should
+ be chown()-ed. Defaults to False.
+ * mkdir_chmod -- bool that controls whether created directories should
+ be chmod()-ed. Defaults to False.
+ * mkdir_p -- whether dodir() should create parent dirs as well.
+ Defaults to True.
+ """
success = False
ERRNOS_IGNORE = { errno.EACCES, }
@@ -595,6 +1015,21 @@ class AbstractFsOperations ( object ):
def copy_tree ( self,
source_root, dest_root, overwrite=True, followlinks=False
):
+ """Recursively copies files from source_root to dest_root (while keeping
+ its directory structure). Ownership and permissions are not preserved,
+ instead copied files and created dirs will have to permissions set
+ during initialization of this object.
+
+ Returns: None (implicit)
+
+ arguments:
+ * source_root -- directory from which files should be copied
+ * dest_root -- directory to which files should be copied
+ * overwrite -- whether to overwrite files that already exist in
+ dest_root. Defaults to True(!).
+ * followlinks -- whether to follow symbolic links in os.walk().
+ Defaults to False.
+ """
dodir = self.dodir
copy_file = self.copy_file
@@ -629,6 +1064,18 @@ class AbstractFsOperations ( object ):
def copy_dirlink_tree ( self,
source_root, dest_root, overwrite=False, followlinks=False
):
+ """Creates symlinks to source_root's content in dest_root.
+
+ Returns: None (implicit)
+
+ arguments:
+ * source_root --
+ * dest_root --
+ * overwrite --
+ * followlinks --
+ """
+
+ unlink = self.unlink
symlink = self.symlink
source, dest, relpath, dirs, files, dirnames = next (
@@ -641,6 +1088,8 @@ class AbstractFsOperations ( object ):
for ( my_source, my_source_stat ), ( my_dest, my_dest_stat ) in (
itertools.chain ( dirs, files )
):
+ if my_dest_stat is not None:
+ unlink ( my_dest )
symlink ( my_source, my_dest )
else:
for ( my_source, my_source_stat ), ( my_dest, my_dest_stat ) in (
@@ -653,7 +1102,17 @@ class AbstractFsOperations ( object ):
def copy_filelink_tree ( self,
source_root, dest_root, overwrite=False, followlinks=False
):
- dodir = self.dodir
+ """Like copy_tree(), but creates symlinks to files in source_root
+ instead of copying them.
+
+ arguments:
+ * source_root --
+ * dest_root --
+ * overwrite --
+ * followlinks --
+ """
+ dodir = self.dodir
+ unlink = self.unlink
symlink = self.symlink
if overwrite:
@@ -667,6 +1126,8 @@ class AbstractFsOperations ( object ):
if followlinks and stat.S_ISLINK ( source_stat ):
dodir ( dest_file )
else:
+ if dest_stat is not None:
+ unlink ( dest_file )
symlink ( source_file, dest_file )
else:
for source, dest, relpath, dirs, files, dirnames in (
@@ -684,19 +1145,27 @@ class AbstractFsOperations ( object ):
symlink ( source_file, dest_file )
# --- end of copy_filelink_tree (...) ---
-
# --- end of AbstractFsOperations ---
+
class FsOperations ( AbstractFsOperations ):
PRETEND = False
- def _setup ( self ):
+ # this is necessary because the abstract are overridden during __init__()
+ # (which doesn't get recognized by @abc.abstractmethod)
+ chmod_file = None
+ chown_file = None
+ chmod_dir = None
+ chown_dir = None
+
+ def __init__ ( self, *args, **kwargs ):
+ super ( FsOperations, self ).__init__ ( *args, **kwargs )
self.chmod_file = self.perm_env_file.chmod
self.chown_file = self.perm_env_file.chown
self.chmod_dir = self.perm_env_dir.chmod
self.chown_dir = self.perm_env_dir.chown
- # --- end of _setup (...) ---
+ # --- end of __init__ (...) ---
def _copy_file ( self, source, dest ):
shutil.copyfile ( source, dest )
@@ -709,11 +1178,6 @@ class FsOperations ( AbstractFsOperations ):
)
# --- end of _dodir (...) ---
- def chmod_chown_recursive ( self, root ):
- raise Exception("broken.")
- for ret in self.perm_env.chown_chmod_recursive ( root ):
- pass
-
def rmdir ( self, dirpath ):
try:
os.rmdir ( dirpath )
@@ -767,27 +1231,25 @@ class VirtualFsOperations ( AbstractFsOperations ):
ret = self.perm_env_file.chown ( fspath )
if ret is not None:
self.info ( ret + "\n" )
+ return True
def chown_dir ( self, fspath ):
ret = self.perm_env_dir.chown ( fspath )
if ret is not None:
self.info ( ret + "\n" )
+ return True
def chmod_file ( self, fspath ):
ret = self.perm_env_file.chmod ( fspath )
if ret is not None:
self.info ( ret + "\n" )
+ return True
def chmod_dir ( self, fspath ):
ret = self.perm_env_dir.chmod ( fspath )
if ret is not None:
self.info ( ret + "\n" )
-
- def chmod_chown_recursive ( self, root ):
- raise Exception("BROKEN.")
- for word in self.perm_env.chown_chmod_recursive ( root ):
- if word is not None:
- self.info ( word + "\n" )
+ return True
def unlink ( self, fspath ):
self.info ( "rm {!r}\n".format ( fspath ) )
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-09-23 15:30 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-09-23 15:30 UTC (permalink / raw
To: gentoo-commits
commit: 0e40ceb1def1dfb66aac5545a53eea27e82f9fe6
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep 23 13:11:44 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep 23 13:11:44 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0e40ceb1
roverlay-status: do not fail if db is missing
---
roverlay/status.py | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/roverlay/status.py b/roverlay/status.py
index cb25edb..9ab00a3 100644
--- a/roverlay/status.py
+++ b/roverlay/status.py
@@ -322,18 +322,19 @@ class StatusRuntimeEnvironment ( roverlay.runtime.RuntimeEnvironmentBase ):
# rrd_db=self.stats_db,
# )
-
- # transfer db cache to template_vars
- # * copy lastupdate
- # * import values
- #
- self.set_template_vars (
- self.stats_db.cache ['values'],
- lastupdate=self.stats_db.cache ['lastupdate'],
- STATS_DB_FILE=stats_db_file,
- STATS_DB=DBStats ( self.stats_db.cache ),
- )
-
+ if self.stats_db.cache:
+ # transfer db cache to template_vars
+ # * copy lastupdate
+ # * import values
+ #
+ self.set_template_vars (
+ self.stats_db.cache ['values'],
+ lastupdate=self.stats_db.cache ['lastupdate'],
+ STATS_DB_FILE=stats_db_file,
+ STATS_DB=DBStats ( self.stats_db.cache ),
+ )
+ else:
+ self.stats_db = None
# -- end if
self.do_setup_mako()
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-12-11 18:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-12-11 18:40 UTC (permalink / raw
To: gentoo-commits
commit: b6c99cf154217ce3afac99e38bb6417154de6b38
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Dec 11 17:56:53 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Dec 11 17:56:53 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b6c99cf1
roverlay/strutil: foreach_str()
---
roverlay/strutil.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index 10a4360..7569523 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -7,7 +7,7 @@
"""provides utility functions for string manipulation"""
__all__ = [ 'ascii_filter', 'bytes_try_decode', 'fix_ebuild_name',
- 'pipe_lines', 'shorten_str', 'unquote',
+ 'pipe_lines', 'shorten_str', 'unquote', 'foreach_str',
]
import re
@@ -151,3 +151,10 @@ def bytes_try_decode (
else:
return byte_str
# --- end of bytes_try_decode() ---
+
+def foreach_str ( func, _str ):
+ if isinstance ( _str, str ) or not hasattr ( _str, '__iter__' ):
+ return func ( str ( _str ) )
+ else:
+ return [ func(str(s)) for s in _str ]
+# --- end of foreach_str (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2013-12-11 18:40 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2013-12-11 18:40 UTC (permalink / raw
To: gentoo-commits
commit: c656c3a2e0c76b61e30ada38d7e88020358bfcee
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Dec 11 16:05:46 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Dec 11 16:05:46 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c656c3a2
log version on startup
---
roverlay/core.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/roverlay/core.py b/roverlay/core.py
index 01066c8..7a30867 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -121,6 +121,7 @@ def load_config_file (
if setup_logger:
roverlay.recipe.easylogger.setup ( roverlay_config )
+ logging.getLogger().debug ( "roverlay version " + version )
if not load_main_only:
confloader.load_field_definition (
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2014-01-25 18:14 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2014-01-25 18:14 UTC (permalink / raw
To: gentoo-commits
commit: 6e862b4bc55db2053d797963c7589eb803b2bc11
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Jan 25 17:53:18 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Jan 25 17:53:18 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6e862b4b
roverlay/core, default_helper_setup(): fix log_to_console
False == 0, so check whether log_to_console is False
(-> don't enforce console logging) or 0 (-> set log level to 0).
---
roverlay/core.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/roverlay/core.py b/roverlay/core.py
index 7a30867..414e705 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -171,7 +171,9 @@ def default_helper_setup ( ROVERLAY_INSTALLED, log_to_console=True ):
roverlay.recipe.easylogger.force_console_logging (
log_level=logging.WARNING
)
- elif log_to_console or log_to_console == 0:
+ elif log_to_console or (
+ log_to_console == 0 and log_to_console is not False
+ ):
roverlay.recipe.easylogger.force_console_logging (
log_level=log_to_console
)
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2014-02-15 19:49 André Erdmann
0 siblings, 0 replies; 159+ messages in thread
From: André Erdmann @ 2014-02-15 19:49 UTC (permalink / raw
To: gentoo-commits
commit: c220255d727063935f654df552f0b3767f504216
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Feb 15 18:54:37 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Feb 15 18:54:37 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=c220255d
roverlay/strutil.py, unquote(): fix keep_going
unquote() needs to call itself with keep_going=True when operating recursively.
---
roverlay/strutil.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/roverlay/strutil.py b/roverlay/strutil.py
index 7569523..9799477 100644
--- a/roverlay/strutil.py
+++ b/roverlay/strutil.py
@@ -100,7 +100,7 @@ def unquote ( _str, keep_going=False ):
chars = '\"\''
if _str [0] == _str [-1] and _str [0] in chars:
- return unquote ( _str[1:-1] ) if keep_going else _str[1:-1]
+ return unquote ( _str[1:-1], True ) if keep_going else _str[1:-1]
return _str
# --- end of unquote (...) ---
^ permalink raw reply related [flat|nested] 159+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/
@ 2014-02-15 19:49 An