* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/tools/, roverlay/, roverlay/overlay/pkgdir/, roverlay/overlay/
2013-06-13 16:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/tools/, roverlay/, roverlay/overlay/pkgdir/, roverlay/overlay/ André Erdmann
@ 2013-06-12 21:10 ` André Erdmann
0 siblings, 0 replies; 2+ messages in thread
From: André Erdmann @ 2013-06-12 21:10 UTC (permalink / raw
To: gentoo-commits
commit: fe217214d62189a5157188c9f7ddfafa607f26c3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 12 20:59:47 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 12 20:59:47 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=fe217214
additions dir: code comments/fixup
Besides other changes, this commit makes the "import hand-written ebuilds"
feature available. Note that this (currently) only works with the (default)
ebuildmanifest pkg dir implementation.
Other changes include:
* additions dir:
** more lenient regex in _EbuildAdditionsView
** handle ambiguous patch file names (where version could be patchno)
* pkgdir_base
** fetch src of imported ebuilds
* packageinfo
** update(): put unknown keys in quotes
** get_create(): get an info key by creating it, if necessary
---
roverlay/overlay/additionsdir.py | 170 ++++++++++++++++++---
roverlay/overlay/category.py | 19 +++
roverlay/overlay/pkgdir/__init__.py | 2 +
roverlay/overlay/pkgdir/packagedir_base.py | 87 +++++++----
.../overlay/pkgdir/packagedir_ebuildmanifest.py | 115 ++++++++------
.../overlay/pkgdir/packagedir_portagemanifest.py | 14 +-
roverlay/overlay/root.py | 129 ++++++++++------
roverlay/packageinfo.py | 51 ++++++-
roverlay/tools/ebuild.py | 1 +
roverlay/tools/ebuildenv.py | 8 +-
10 files changed, 458 insertions(+), 138 deletions(-)
diff --git a/roverlay/overlay/additionsdir.py b/roverlay/overlay/additionsdir.py
index f0a6be4..3031a69 100644
--- a/roverlay/overlay/additionsdir.py
+++ b/roverlay/overlay/additionsdir.py
@@ -9,8 +9,10 @@ import re
EMPTY_TUPLE = ()
-
class AdditionsDir ( object ):
+ """AdditionsDir represents a filesystem directory (that does not need
+ to exist).
+ """
def __init__ ( self, fspath, name=None, parent=None ):
self.root = str ( fspath ) if fspath else None
@@ -24,7 +26,38 @@ class AdditionsDir ( object ):
__bool__ = exists
+ def iter_entries ( self ):
+ """Generator that yields the directory content of this dir."""
+ if self.exists():
+ for name in os.listdir ( self.root ):
+ yield ( name, ( self.root + os.sep + name ) )
+ # --- end of iter_entries (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_entries() )
+ # --- end of __iter__ (...) ---
+
+ def get_child ( self, fspath, name ):
+ """Returns a new instance with the given fspath/name and this object
+ as parent.
+ arguments:
+
+ * fspath --
+ * name --
+ """
+ return self.__class__ (
+ fspath = fspath,
+ name = name,
+ parent = self
+ )
+ # --- end of get_child (...) ---
+
def get_subdir ( self, relpath ):
+ """Returns a new instance which represents a subdirectory of this dir.
+
+ arguments:
+ * relpath -- path of the new instance, relative to the root of this dir
+ """
if self.root:
return self.__class__ (
fspath = ( self.root + os.sep + relpath ),
@@ -36,6 +69,11 @@ class AdditionsDir ( object ):
# --- end of get_subdir (...) ---
def get_obj_subdir ( self, obj ):
+ """Like get_obj_subdir(), but uses obj.name as relpath.
+
+ arguments:
+ * obj --
+ """
return self.get_subdir ( obj.name )
# --- end of get_obj_subdir (...) ---
@@ -43,8 +81,11 @@ class AdditionsDir ( object ):
return self.root or ""
# --- end of __str__ (...) ---
+# --- end of AdditionsDir ---
+
class _AdditionsDirView ( object ):
+ """view objects implement AdditionsDir actions, e.g. find certain files."""
def __init__ ( self, additions_dir ):
self._additions_dir = additions_dir
@@ -54,48 +95,72 @@ class _AdditionsDirView ( object ):
return bool ( self._additions_dir )
# --- end of __bool__ (...) ---
+ @property
+ def name ( self ):
+ return self._additions_dir.name
+ # --- end of name (...) ---
+
+ def _fs_iter_regex ( self, regex ):
+ """Iterates over the content of the additions dir and yields
+ 3-tuples ( match, path, name ) for each name that matches the given
+ regex.
+
+ arguments:
+ * regex --
+ """
+ fre = re.compile ( regex )
+
+ for name, fspath in self._additions_dir:
+ fmatch = fre.match ( name )
+ if fmatch:
+ yield ( fmatch, fspath, name )
+ # --- end of _fs_iter_regex (...) ---
+
+# --- end of _AdditionsDirView ---
+
class _EbuildAdditionsView ( _AdditionsDirView ):
# with leading '-'
- RE_PVR = '[-](?P<pvr>[0-9.]+([-]r[0-9]+)?)'
+ RE_PVR = '[-](?P<pvr>[0-9].*?([-]r[0-9]+)?)'
def __init__ ( self, additions_dir ):
+ """Ebuild additions dir view constructor.
+ Also calls prepare() if declared.
+
+ arguments:
+ * additions_dir --
+ """
super ( _EbuildAdditionsView, self ).__init__ (
additions_dir=additions_dir
)
- if hasattr ( self, 'prepare' ):
- self.prepare()
+ if hasattr ( self, 'prepare' ): self.prepare()
# --- end of __init__ (...) ---
- def _fs_iter_regex ( self, regex ):
- fre = re.compile ( regex )
-
- root = self._additions_dir.root
- for fname in os.listdir ( root ):
- fmatch = fre.match ( fname )
- if fmatch:
- yield ( fmatch, ( root + os.sep + fname ), fname )
- # --- end of _fs_iter_regex (...) ---
+# --- end of _EbuildAdditionsView ---
class EbuildView ( _EbuildAdditionsView ):
+ """View object for finding/importing ebuilds."""
RE_EBUILD_SUFFIX = '[.]ebuild'
def has_ebuilds ( self ):
+ """Returns True if there are any ebuilds that could be imported."""
return bool ( getattr ( self, '_ebuilds', None ) )
# --- end of has_ebuilds (...) ---
def get_ebuilds ( self ):
+ """Returns all ebuilds as list of 3-tuples ( pvr, path, name )."""
return self._ebuilds
# --- end of get_ebuilds (...) ---
def __iter__ ( self ):
- return iter ( self.get_ebuilds )
+ return iter ( self.get_ebuilds() )
# --- end of __iter__ (...) ---
- def _prepare ( self ):
+ def prepare ( self ):
+ """Searches for ebuilds and create self._ebuilds."""
if self._additions_dir.exists():
ebuilds = list()
@@ -104,21 +169,72 @@ class EbuildView ( _EbuildAdditionsView ):
):
# deref symlinks
ebuilds.append (
- fmatch.group ( 'pvr' ), os.path.abspath ( fpath ), fname
+ ( fmatch.group ( 'pvr' ), os.path.abspath ( fpath ), fname )
+ )
+
+ self._ebuilds = ebuilds
+ # --- end of prepare (...) --
+
+# --- end of EbuildView ---
+
+
+class CategoryView ( _AdditionsDirView ):
+ """View object that creates EbuildView objects."""
+
+ def iter_packages ( self ):
+ for name, fspath in self._additions_dir:
+ if os.path.isdir ( fspath ):
+ yield EbuildView (
+ self._additions_dir.get_child ( fspath, name )
+ )
+ # --- end of iter_packages (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_packages() )
+ # --- end of __iter__ (...) ---
+
+# --- end of CategoryView ---
+
+
+class CategoryRootView ( _AdditionsDirView ):
+ """View object that creates CategoryView objects."""
+
+ def iter_categories ( self ):
+ for name, fspath in self._additions_dir:
+ if os.path.isdir ( fspath ) and (
+ '-' in name or name == 'virtual'
+ ):
+ yield CategoryView (
+ self._additions_dir.get_child ( fspath, name )
)
- # --- end of _prepare (...) --
+ # --- end of iter_categories (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_categories() )
+ # --- end of __iter__ (...) ---
+# --- end of CategoryRootView ---
class PatchView ( _EbuildAdditionsView ):
+ """View object for finding ebuild patches."""
RE_PATCH_SUFFIX = '(?P<patchno>[0-9]{4})?[.]patch'
def has_patches ( self ):
+ """Returns True if one or more patches are available."""
return bool ( getattr ( self, '_patches', None ) )
# --- end of has_patches (...) ---
def get_patches ( self, pvr, fallback_to_default=True ):
+ """Returns a list of patches that should be applied to the ebuild
+ referenced by pvr.
+
+ arguments:
+ * pvr -- $PVR of the ebuild
+ * fallback_to_default -- return default patches if no version-specific
+ ones are available (defaults to True)
+ """
patches = self._patches.get ( pvr, None )
if patches:
return patches
@@ -129,10 +245,12 @@ class PatchView ( _EbuildAdditionsView ):
# --- end of get_patches (...) ---
def get_default_patches ( self ):
+ """Returns the default patches."""
return getattr ( self, '_default_patches', EMPTY_TUPLE )
# --- end of get_default_patches (...) ---
def prepare ( self ):
+ """Searches for ebuild patch files."""
def patchno_sort ( iterable ):
return list (
v[1] for v in sorted ( iterable, key=lambda k: k[0] )
@@ -170,11 +288,23 @@ class PatchView ( _EbuildAdditionsView ):
):
patchno = fmatch.group ( 'patchno' )
- default_patches.append (
- ( ( -1 if patchno is None else int ( patchno ) ), fpath )
- )
+ if patchno in self._patches:
+ if len ( self._patches [patchno] ) < 2:
+
+ del self._patches [patchno]
+ default_patches.append (
+ ( ( -1 if patchno is None else int ( patchno ) ), fpath )
+ )
+ else:
+ pass
+ else:
+ default_patches.append (
+ ( ( -1 if patchno is None else int ( patchno ) ), fpath )
+ )
# -- end for;
if default_patches:
self._default_patches = patchno_sort ( default_patches )
# --- end of prepare (...) ---
+
+# --- end of PatchView ---
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index 0e33fc7..558aa71 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -91,6 +91,11 @@ class Category ( object ):
# --- end of add (...) ---
def drop_package ( self, name ):
+ """Removes a package and its fs content from this category.
+
+ arguments:
+ * name -- name of the package
+ """
p = self._subdirs [name]
del self._subdirs [name]
p.fs_destroy()
@@ -117,6 +122,20 @@ class Category ( object ):
return os.path.isdir ( self.physical_location + os.sep + _dir )
# --- end of has_category (...) ---
+ def import_ebuilds ( self, catview, *args, **kwargs ):
+ """Imports ebuilds into this category.
+
+ arguments:
+ * catview -- view object that creates EbuildView objects
+ * *args, **kwargs -- (keyword) arguments that will be passed to
+ package dirs
+ """
+ for eview in catview:
+ self._get_package_dir ( eview.name ).import_ebuilds (
+ eview, *args, **kwargs
+ )
+ # --- end of import_ebuilds (...) ---
+
def list_package_names ( self ):
for name, subdir in self._subdirs.items():
if not subdir.empty():
diff --git a/roverlay/overlay/pkgdir/__init__.py b/roverlay/overlay/pkgdir/__init__.py
index baf4eea..d33ced2 100644
--- a/roverlay/overlay/pkgdir/__init__.py
+++ b/roverlay/overlay/pkgdir/__init__.py
@@ -59,6 +59,8 @@ def _configure():
if hasattr ( _package_dir_class, 'init_cls' ):
_package_dir_class.init_cls()
+ else:
+ _package_dir_class.init_base_cls()
logging.getLogger ('pkgdir').debug (
'Using {!r} as manifest implementation.'.format ( mf_impl )
diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py
index e2f0f09..e5c0558 100644
--- a/roverlay/overlay/pkgdir/packagedir_base.py
+++ b/roverlay/overlay/pkgdir/packagedir_base.py
@@ -15,24 +15,33 @@ Each PackageDir instance represents one package name (e.g. "seewave").
__all__ = [ 'PackageDirBase', ]
+
import os
+import shutil
import sys
import threading
-import shutil
-import roverlay.overlay.additionsdir
+import roverlay.config
+import roverlay.packageinfo
+import roverlay.util
+
+import roverlay.tools.ebuild
+import roverlay.tools.ebuildenv
import roverlay.tools.patch
-from roverlay import util
-from roverlay.packageinfo import PackageInfo
-from roverlay.overlay.pkgdir.metadata import MetadataJob
+import roverlay.overlay.additionsdir
+
+import roverlay.overlay.pkgdir.distroot.static
+import roverlay.overlay.pkgdir.metadata
class PackageDirBase ( object ):
"""The PackageDir base class that implements most functionality except
for Manifest file creation."""
+ #DISTROOT =
EBUILD_SUFFIX = '.ebuild'
+ #FETCHENV =
SUPPRESS_EXCEPTIONS = True
# MANIFEST_THREADSAFE (tri-state)
@@ -42,6 +51,20 @@ class PackageDirBase ( object ):
#
MANIFEST_THREADSAFE = None
+ @classmethod
+ def init_base_cls ( cls ):
+ # env for calling "ebuild <ebuild file> fetch"
+ fetch_env = roverlay.tools.ebuildenv.FetchEnv()
+ fetch_env.add_overlay_dir (
+ roverlay.config.get_or_fail ( 'OVERLAY.dir' )
+ )
+
+ cls.DISTROOT = (
+ roverlay.overlay.pkgdir.distroot.static.get_configured ( static=True )
+ )
+ cls.FETCHENV = fetch_env
+ # --- end of init_cls (...) ---
+
def __init__ ( self,
name, logger, directory, get_header, runtime_incremental, parent
):
@@ -73,15 +96,16 @@ class PackageDirBase ( object ):
self.get_header = get_header
self.runtime_incremental = runtime_incremental
- self._metadata = MetadataJob (
+ self._metadata = roverlay.overlay.pkgdir.metadata.MetadataJob (
filepath = self.physical_location + os.sep + 'metadata.xml',
logger = self.logger
)
# <dir>/<PN>-<PVR>.ebuild
- self.ebuild_filepath_format = \
- self.physical_location + os.sep + \
- self.name + "-{PVR}" + self.__class__.EBUILD_SUFFIX
+ self.ebuild_filepath_format = (
+ self.physical_location + os.sep
+ + self.name + "-{PVR}" + self.__class__.EBUILD_SUFFIX
+ )
# used to track changes for this package dir
self.modified = False
@@ -115,7 +139,7 @@ class PackageDirBase ( object ):
* efile -- full path to the ebuild file
* pvr -- version ($PVR) of the ebuild
"""
- p = PackageInfo (
+ p = roverlay.packageinfo.PackageInfo (
physical_only=True, pvr=pvr, ebuild_file=efile
)
self._packages [ p ['ebuild_verstr'] ] = p
@@ -253,7 +277,7 @@ class PackageDirBase ( object ):
def has_ebuilds ( self ):
"""Returns True if this PackageDir has any ebuild files (filesystem)."""
for p in self._packages.values():
- if p ['physical_only'] or p.has ( 'ebuild' ):
+ if p ['physical_only'] or p.has ( 'ebuild' ) or p ['imported']:
return True
return False
# --- end of has_ebuilds (...) ---
@@ -361,6 +385,7 @@ class PackageDirBase ( object ):
# --- end of purge_package (...) ---
def fs_destroy ( self ):
+ """Destroys the filesystem content of this package dir."""
pvr_list = list ( self._packages.keys() )
for pvr in pvr_list:
self.purge_package ( pvr )
@@ -534,12 +559,13 @@ class PackageDirBase ( object ):
return success
# --- end of write (...) ---
- def import_extra_ebuilds ( self, overwrite, additions_dir ):
+ def import_ebuilds ( self, eview, overwrite, nosync=False ):
"""Imports ebuilds from an additions dir into this package dir.
arguments:
- * overwrite -- whether to overwrite existing ebuilds or not
- * additions_dir -- additions dir for this package dir
+ * eview -- additions dir ebuild view
+ * overwrite -- whether to overwrite existing ebuilds or not
+ * nosync -- if True: don't fetch src files (defaults to False)
"""
def import_ebuild_efile ( pvr, efile_src, fname ):
@@ -568,17 +594,22 @@ class PackageDirBase ( object ):
shutil.copyfile ( efile_src, efile_dest )
# create PackageInfo and register it
- p = PackageInfo (
- imported=True, pvr=pvr, ebuild_file=efile
+ p = roverlay.packageinfo.PackageInfo (
+ imported=True, pvr=pvr, ebuild_file=efile_dest
)
self._packages [ p ['ebuild_verstr'] ] = p
-
# manifest needs to be rewritten
self._need_manifest = True
- # fetch SRC_URI?
- # ebuild <ebuild> fetch?
+ # fetch SRC_URI using ebuild(1)
+ if not nosync and not roverlay.tools.ebuild.doebuild_fetch (
+ efile_dest, self.logger,
+ self.FETCHENV.get_env (
+ self.DISTROOT.get_distdir ( self.name ).get_root()
+ )
+ ):
+ raise Exception ( "doebuild_fetch() failed." )
# imported ebuilds cannot be used for generating metadata.xml
##self._need_metadata = True
@@ -602,14 +633,12 @@ class PackageDirBase ( object ):
raise
# --- end of import_ebuild_efile (...) ---
- eview = roverlay.overlay.additionsdir.EbuildView ( additions_dir )
-
if not self.physical_location:
raise Exception (
- "import_extra_ebuilds() needs a non-virtual package dir!"
+ "import_ebuilds() needs a non-virtual package dir!"
)
elif eview.has_ebuilds():
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
if not self._packages:
for pvr, efile, fname in eview.get_ebuilds():
@@ -625,7 +654,7 @@ class PackageDirBase ( object ):
for pvr, efile, fname in eview.get_ebuilds():
if pvr not in self._packages:
import_ebuild_efile ( pvr, efile, fname )
- # --- end of import_extra_ebuilds (...) ---
+ # --- end of import_ebuilds (...) ---
def write_ebuilds ( self, overwrite, additions_dir, shared_fh=None ):
"""Writes all ebuilds.
@@ -744,7 +773,7 @@ class PackageDirBase ( object ):
for pvr, efile, p_info in list ( ebuilds_to_write() ):
if not hasdir:
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
hasdir = True
if (
@@ -823,6 +852,12 @@ class PackageDirBase ( object ):
return True
else:
return False
+ elif (
+ hasattr ( self, '_write_import_manifest' )
+ and self._write_import_manifest()
+ ):
+ self._need_manifest = False
+ return True
elif ignore_empty:
return True
else:
@@ -843,7 +878,7 @@ class PackageDirBase ( object ):
self.generate_metadata ( skip_if_existent=True )
if shared_fh is None:
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
if self._metadata.write():
self._need_metadata = False
self._need_manifest = True
diff --git a/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py b/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
index c9e3d84..5217f6a 100644
--- a/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
+++ b/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
@@ -6,81 +6,106 @@
__all__ = [ 'PackageDir', ]
+import os
import threading
+
import roverlay.config
import roverlay.tools.ebuild
import roverlay.tools.ebuildenv
+
import roverlay.overlay.pkgdir.packagedir_base
-import roverlay.overlay.pkgdir.distroot.static
class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
"""
PackageDir class that uses the ebuild executable for Manifest writing.
"""
- #DISTROOT = None
#MANIFEST_ENV = None
- MANIFEST_LOCK = threading.Lock()
MANIFEST_THREADSAFE = False
@classmethod
def init_cls ( cls ):
+ cls.init_base_cls()
+
env = roverlay.tools.ebuildenv.ManifestEnv()
env.add_overlay_dir ( roverlay.config.get_or_fail ( 'OVERLAY.dir' ) )
-
- cls.DISTROOT = (
- roverlay.overlay.pkgdir.distroot.static.get_configured ( static=True )
- )
-
cls.MANIFEST_ENV = env
# --- end of init_cls (...) ---
- def _write_manifest ( self, pkgs_for_manifest ):
- """Generates and writes the Manifest file for this package.
+ def _do_ebuildmanifest ( self, ebuild_file, distdir=None ):
+ """Calls doebuild_manifest().
+ Returns True on success, else False. Also handles result logging.
- expects: called after writing metadata/ebuilds
-
- returns: success (True/False)
+ arguments:
+ * ebuild_file -- ebuild file that should be used for the doebuild call
+ * distdir -- distdir object (optional)
"""
try:
- self.MANIFEST_LOCK.acquire()
-
- # choosing one ebuild for calling "ebuild <ebuild>" is sufficient
- ebuild_file = pkgs_for_manifest [0] ['ebuild_file']
-
- distdir = self.DISTROOT.get_distdir ( pkgs_for_manifest [0] ['name'] )
-
- # add hardlinks to DISTROOT (replacing existing files/links)
- for p in pkgs_for_manifest:
- # TODO: optimize this further?
- # -> "not has physical_only?"
- # (should be covered by "has package_file")
- distdir.add ( p ['package_file'], p ['package_src_destpath'] )
-
-
- if roverlay.tools.ebuild.doebuild_manifest (
+ call = roverlay.tools.ebuild.doebuild_manifest (
ebuild_file, self.logger,
- self.MANIFEST_ENV.get_env ( distdir.get_root() )
- ):
- self.logger.debug ( "Manifest written." )
- ret = True
-
- else:
- self.logger.error (
- 'Couldn\'t create Manifest for {ebuild}! '
- 'Return code was {ret}.'.format (
- ebuild=ebuild_file, ret=ebuild_call.returncode
+ self.MANIFEST_ENV.get_env (
+ distdir.get_root() if distdir is not None else (
+ self.DISTROOT.get_distdir ( self.name ).get_root()
)
- )
- ret = False
-
+ ),
+ return_success=False
+ )
except Exception as err:
self.logger.exception ( err )
raise
+ # -- end try
+
+ if call.returncode == os.EX_OK:
+ self.logger.debug ( "Manifest written." )
+ return True
+ else:
+ self.logger.error (
+ 'Couldn\'t create Manifest for {ebuild}! '
+ 'Return code was {ret}.'.format ( ebuild=ebuild_file, ret=ret )
+ )
+ return False
+ # --- end of _do_ebuildmanifest (...) ---
+
+ def _write_import_manifest ( self ):
+ """Writes a Manifest file if this package has any imported ebuilds.
+
+ Returns True if a Manifest has been written, else False.
+ """
+ try:
+ pkg = next (
+ p for p in self._packages.values()
+ if p.has ( 'imported', 'ebuild_file' )
+ )
+ except StopIteration:
+ # no imported ebuilds
+ return False
+ # -- end try
+
+ self.logger.debug ( "Writing (import-)Manifest" )
+ return self._do_ebuildmanifest ( pkg ['ebuild_file'] )
+ # --- end of _write_import_manifest (...) ---
+
+ def _write_manifest ( self, pkgs_for_manifest ):
+ """Generates and writes the Manifest file for this package.
- finally:
- self.MANIFEST_LOCK.release()
+ expects: called after writing metadata/ebuilds
- return ret
+ returns: success (True/False)
+ """
+ # choosing one ebuild for calling "ebuild <ebuild>" is sufficient
+ ebuild_file = pkgs_for_manifest [0] ['ebuild_file']
+ distdir = self.DISTROOT.get_distdir ( self.name )
+
+ # add hardlinks to DISTROOT (replacing existing files/links)
+ for p in pkgs_for_manifest:
+ # TODO: optimize this further?
+ # -> "not has physical_only?"
+ # (should be covered by "has package_file")
+ distdir.add ( p ['package_file'], p ['package_src_destpath'] )
+ # -- end for;
+
+ return self._do_ebuildmanifest ( ebuild_file, distdir )
# --- end of write_manifest (...) ---
+
+# --- end of PackageDir #ebuildmanifest ---
diff --git a/roverlay/overlay/pkgdir/packagedir_portagemanifest.py b/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
index 3c4d728..6596dec 100644
--- a/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
+++ b/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
@@ -13,7 +13,9 @@ import portage.manifest
import portage.exception
import logging
-logging.getLogger ( __name__ ).warning ( "experimental code" )
+logging.getLogger ( __name__ ).warning (
+ "experimental code, importing ebuilds doesn't work!"
+)
del logging
import roverlay.config
@@ -23,9 +25,17 @@ import roverlay.overlay.pkgdir.packagedir_base
import roverlay.overlay.pkgdir.distroot
class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
+ # FIXME: portagemanifest is broken, it cannot create Manifest files for
+ # package dirs with imported ebuilds
MANIFEST_THREADSAFE = True
+ def import_ebuilds ( self, *args, **kwargs ):
+ raise NotImplementedError (
+ "ebuild imports not supported by portagemanifest!"
+ )
+ # --- end of import_ebuilds (...) ---
+
def _scan_add_package ( self, efile, pvr ):
"""Called for each ebuild that is found during scan().
Creates a PackageInfo for the ebuild and adds it to self._packages.
@@ -107,7 +117,7 @@ class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
# * ...
#
- distdir = roverlay.overlay.pkgdir.distroot.get_distdir ( self.name )
+ distdir = self.DISTROOT.get_distdir ( self.name )
# allow_missing=True -- don't write empty Manifest files
manifest = portage.manifest.Manifest (
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index ca71b81..a9d16c4 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -17,24 +17,24 @@ due do double-linkage between PackageInfo and PackageDir.
__all__ = [ 'Overlay', ]
-import threading
import logging
-import shutil
import os
+import shutil
+import threading
-from roverlay import config, util
-
-from roverlay.overlay.category import Category
-from roverlay.overlay.header import EbuildHeader
-
+import roverlay.config
+import roverlay.util
import roverlay.overlay.additionsdir
+import roverlay.overlay.category
+import roverlay.overlay.header
+
class Overlay ( object ):
- DEFAULT_USE_DESC = '\n'.join ( (
- 'byte-compile - enable byte compiling',
+ DEFAULT_USE_DESC = (
+ 'byte-compile - enable byte compiling\n'
'R_suggests - install recommended packages'
- ) )
+ )
@classmethod
def new_configured ( cls,
@@ -51,23 +51,24 @@ class Overlay ( object ):
* write_allowed --
* skip_manifest --
* runtime_incremental --
- * readonly -- see Overlay.__init__
"""
- name = config.get_or_fail ( 'OVERLAY.name' )
+ optional = roverlay.config.get
+ mandatory = roverlay.config.get_or_fail
+
return cls (
- name = name,
- logger = (
- logger or logging.getLogger ( 'Overlay:' + name )
- ),
- directory = config.get_or_fail ( 'OVERLAY.dir' ),
- default_category = config.get_or_fail ( 'OVERLAY.category' ),
- eclass_files = config.get ( 'OVERLAY.eclass_files', None ),
- ebuild_header = config.get ( 'EBUILD.default_header', None ),
- incremental = incremental,
+ name = mandatory ( 'OVERLAY.name' ),
+ logger = logger,
+ directory = mandatory ( 'OVERLAY.dir' ),
+ default_category = mandatory ( 'OVERLAY.category' ),
+ eclass_files = optional ( 'OVERLAY.eclass_files' ),
+ ebuild_header = optional ( 'EBUILD.default_header' ),
write_allowed = write_allowed,
+ incremental = incremental,
skip_manifest = skip_manifest,
- additions_dir = config.get_or_fail ( 'OVERLAY.additions_dir' ),
+ additions_dir = optional ( 'OVERLAY.additions_dir' ),
+ use_desc = optional ( 'OVERLAY.use_desc' ),
runtime_incremental = runtime_incremental,
+ keep_n_ebuilds = optional ( 'OVERLAY.keep_nth_latest' ),
)
# --- end of new_configured (...) ---
@@ -83,7 +84,9 @@ class Overlay ( object ):
incremental,
skip_manifest,
additions_dir,
- runtime_incremental=False
+ use_desc=None,
+ runtime_incremental=False,
+ keep_n_ebuilds=None
):
"""Initializes an overlay.
@@ -108,9 +111,11 @@ class Overlay ( object ):
patches. The directory has to exist (it will
be checked here).
A value of None or "" disables additions.
+ * use_desc -- text for profiles/use.desc
* runtime_incremental -- see package.py:PackageDir.__init__ (...),
Defaults to False (saves memory but costs time)
-
+ * keep_n_ebuilds -- number of ebuilds to keep (per package),
+ any "false" Value (None, 0, ...) disables this
"""
self.name = name
self.logger = logger.getChild ( 'overlay' )
@@ -126,17 +131,31 @@ class Overlay ( object ):
self._profiles_dir = self.physical_location + os.sep + 'profiles'
self._catlock = threading.Lock()
self._categories = dict()
- self._header = EbuildHeader ( ebuild_header )
self.skip_manifest = skip_manifest
+ self._header = roverlay.overlay.header.EbuildHeader ( ebuild_header )
+ self._use_desc = (
+ use_desc.rstrip() if use_desc is not None else self.DEFAULT_USE_DESC
+ )
+
+ if keep_n_ebuilds:
+ self.keep_n_ebuilds = keep_n_ebuilds
+
if additions_dir:
if os.path.isdir ( additions_dir ):
- self.additions_dirpath = os.path.abspath ( additions_dir )
+ additions_dirpath = os.path.abspath ( additions_dir )
else:
raise ValueError (
"additions dir {} does not exist!".format ( additions_dir )
)
+ else:
+ additions_dirpath = None
+ # -- end if
+
+ self.additions_dir = (
+ roverlay.overlay.additionsdir.AdditionsDir ( additions_dirpath )
+ )
# calculating eclass names twice,
# once here and another time when calling _init_overlay
@@ -150,6 +169,8 @@ class Overlay ( object ):
# incremental writing, which writes ebuilds as soon as they're
# ready)
self.scan()
+
+ self.import_ebuilds ( overwrite=( not incremental ) )
# --- end of __init__ (...) ---
def _get_category ( self, category ):
@@ -162,7 +183,7 @@ class Overlay ( object ):
self._catlock.acquire()
try:
if not category in self._categories:
- newcat = Category (
+ newcat = roverlay.overlay.category.Category (
category,
self.logger,
self.physical_location + os.sep + category,
@@ -218,7 +239,7 @@ class Overlay ( object ):
eclass_dir = self.physical_location + os.sep + 'eclass'
try:
eclass_names = list()
- util.dodir ( eclass_dir )
+ roverlay.util.dodir ( eclass_dir )
for destname, eclass in self._get_eclass_import_info ( False ):
dest = eclass_dir + os.sep + destname + '.eclass'
@@ -271,7 +292,7 @@ class Overlay ( object ):
self._get_category ( self.default_category )
# profiles/
- util.dodir ( self._profiles_dir )
+ roverlay.util.dodir ( self._profiles_dir )
# profiless/repo_name
write_profiles_file ( 'repo_name', self.name + '\n' )
@@ -284,17 +305,13 @@ class Overlay ( object ):
write_profiles_file ( 'categories', cats + '\n' )
# profiles/use.desc
- use_desc = config.get (
- 'OVERLAY.use_desc',
- fallback_value=self.__class__.DEFAULT_USE_DESC
- )
- if use_desc:
- write_profiles_file ( 'use.desc', use_desc + '\n' )
+ if self._use_desc:
+ write_profiles_file ( 'use.desc', self._use_desc + '\n' )
# --- end of write_profiles_dir (...) ---
try:
# mkdir overlay root
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
self._import_eclass ( reimport_eclass )
@@ -340,13 +357,19 @@ class Overlay ( object ):
# --- end of has_category (...) ---
def find_duplicate_packages ( self, _default_category=None ):
+ """Searches for packages that exist in the default category and
+ another one and returns a set of package names.
+
+ arguments:
+ * _default_category -- category object
+ """
default_category = (
_default_category if _default_category is None
else self._categories.get ( self.default_category, None )
)
if default_category:
- duplicate_pkg = set()
+ duplicate_pkg = set()
for category in self._categories.values():
if category is not default_category:
@@ -361,6 +384,13 @@ class Overlay ( object ):
# --- end of find_duplicate_packages (...) ---
def remove_duplicate_ebuilds ( self, reverse ):
+ """Searcges for packages that exist in the default category and
+ another one and removes them from either one, depending on whether
+ reverse if True (other will be removed) or False (default category).
+
+ arguments:
+ * reverse
+ """
default_category = self._categories.get ( self.default_category, None )
if default_category:
if reverse:
@@ -398,6 +428,7 @@ class Overlay ( object ):
# --- end of remove_duplicate_ebuilds (...) ---
def remove_empty_categories ( self ):
+ """Removes empty categories."""
catlist = self._categories.items()
for cat in catlist:
cat[1].remove_empty()
@@ -430,6 +461,21 @@ class Overlay ( object ):
return not self._writeable
# --- end of readonly (...) ---
+ def import_ebuilds ( self, overwrite, nosync=False ):
+ """Imports ebuilds from the additions dir.
+
+ arguments:
+ * overwrite -- whether to overwrite existing ebuilds
+ * nosync -- if True: don't fetch src files (defaults to False)
+ """
+ for catview in (
+ roverlay.overlay.additionsdir.CategoryRootView ( self.additions_dir )
+ ):
+ self._get_category ( catview.name ).import_ebuilds (
+ catview, overwrite=overwrite
+ )
+ # --- end of import_ebuilds (...) ---
+
def scan ( self, **kw ):
def scan_categories():
for x in os.listdir ( self.physical_location ):
@@ -478,20 +524,17 @@ class Overlay ( object ):
Note: This is not thread-safe, it's expected to be called when
ebuild creation is done.
"""
+
if self._writeable:
self._init_overlay ( reimport_eclass=True )
- additions_dir = roverlay.overlay.additionsdir.AdditionsDir (
- getattr ( self, 'additions_dirpath', None )
- )
-
for cat in self._categories.values():
cat.write (
overwrite_ebuilds = False,
- keep_n_ebuilds = config.get ( 'OVERLAY.keep_nth_latest', None ),
+ keep_n_ebuilds = getattr ( self, 'keep_n_ebuilds', None ),
cautious = True,
write_manifest = not self.skip_manifest,
- additions_dir = additions_dir.get_obj_subdir ( cat ),
+ additions_dir = self.additions_dir.get_obj_subdir ( cat ),
)
else:
# FIXME debug print
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 84a7d45..90b4250 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -98,6 +98,7 @@ class PackageInfo ( object ):
'origin',
'ebuild',
'ebuild_file',
+ 'imported',
'physical_only',
'src_uri',
))
@@ -341,6 +342,10 @@ class PackageInfo ( object ):
# 'physical_only' not in self._info -> assume False
return False
+ elif key_low == 'imported':
+ # 'imported' not in self._info -> assume False
+ return False
+
elif key_low == 'src_uri':
if 'src_uri_base' in self._info:
return \
@@ -386,6 +391,50 @@ class PackageInfo ( object ):
raise KeyError ( key )
# --- end of get (...) ---
+ def get_create (
+ self, key, newtype, convert=False, check_type=True, create_kw=None
+ ):
+ """Tries to get a value from the info dict. Creates it as newtype if
+ necessary.
+
+ Note: This operation is "unsafe". No locks will be acquired etc.
+
+ arguments:
+ * key -- info key
+ * newtype -- "expected type", also used for creating new values
+ * convert -- if True: convert existing value (defaults to False)
+ * check_type -- if True: check whether the type of existing value is
+ a (sub-)type of newtype (defaults to True)
+ This arg can also be a type.
+ Has no effect if convert is set to True
+ * create_kw -- either None or a dict that will used as keyword args
+ when creating newtype
+ """
+ v = self.get ( key, do_fallback=True )
+ if v is None:
+ newv = newtype ( **create_kw ) if create_kw else newtype()
+ self._info [key] = newv
+ return newv
+ elif convert:
+ return newtype ( v )
+ elif check_type:
+ want_type = (
+ check_type if ( type ( check_type ) is type ) else newtype
+ )
+
+ #if type ( v ) is want_type:
+ if isinstance ( v, want_type ):
+ return v
+ else:
+ raise TypeError (
+ "key {k} should have type {t0}, but is a {t1}!".format (
+ k=key, t0=want_type, t1=type(v)
+ )
+ )
+ else:
+ return v
+ # --- end of get_create (...) ---
+
def get_desc_data ( self ):
"""Returns the DESCRIPTION data for this PackageInfo (by reading the
R package file if necessary).
@@ -557,7 +606,7 @@ class PackageInfo ( object ):
else:
self.logger.error (
- "in _update(): unknown info key {}!".format ( key )
+ "in _update(): unknown info key {!r}!".format ( key )
)
# -- end for;
diff --git a/roverlay/tools/ebuild.py b/roverlay/tools/ebuild.py
index d9f4e9a..e8f7e37 100644
--- a/roverlay/tools/ebuild.py
+++ b/roverlay/tools/ebuild.py
@@ -20,6 +20,7 @@ _EBUILD_CMDV = (
def doebuild (
ebuild_file, command, logger, env=None, opts=(), return_success=True
):
+ logger.debug ( "doebuild: {c}, {e!r}".format ( e=ebuild_file, c=command ) )
return roverlay.tools.runcmd.run_command (
cmdv = ( _EBUILD_CMDV + opts + ( ebuild_file, command ) ),
env = env,
diff --git a/roverlay/tools/ebuildenv.py b/roverlay/tools/ebuildenv.py
index 40f6495..7c5accb 100644
--- a/roverlay/tools/ebuildenv.py
+++ b/roverlay/tools/ebuildenv.py
@@ -101,8 +101,14 @@ class EbuildEnv ( object ):
# --- end of EbuildEnv ---
+
class FetchEnv ( EbuildEnv ):
- pass
+ def _make_common_env ( self ):
+ super ( FetchEnv, self )._make_common_env()
+ # "Cannot chown a lockfile"
+ self._common_env ['FEATURES'] += " -distlocks"
+ # --- end of _make_common_env (...) ---
+
# --- end of FetchEnv ---
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/tools/, roverlay/, roverlay/overlay/pkgdir/, roverlay/overlay/
@ 2013-06-13 16:34 André Erdmann
2013-06-12 21:10 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
0 siblings, 1 reply; 2+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: fe217214d62189a5157188c9f7ddfafa607f26c3
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun 12 20:59:47 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun 12 20:59:47 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=fe217214
additions dir: code comments/fixup
Besides other changes, this commit makes the "import hand-written ebuilds"
feature available. Note that this (currently) only works with the (default)
ebuildmanifest pkg dir implementation.
Other changes include:
* additions dir:
** more lenient regex in _EbuildAdditionsView
** handle ambiguous patch file names (where version could be patchno)
* pkgdir_base
** fetch src of imported ebuilds
* packageinfo
** update(): put unknown keys in quotes
** get_create(): get an info key by creating it, if necessary
---
roverlay/overlay/additionsdir.py | 170 ++++++++++++++++++---
roverlay/overlay/category.py | 19 +++
roverlay/overlay/pkgdir/__init__.py | 2 +
roverlay/overlay/pkgdir/packagedir_base.py | 87 +++++++----
.../overlay/pkgdir/packagedir_ebuildmanifest.py | 115 ++++++++------
.../overlay/pkgdir/packagedir_portagemanifest.py | 14 +-
roverlay/overlay/root.py | 129 ++++++++++------
roverlay/packageinfo.py | 51 ++++++-
roverlay/tools/ebuild.py | 1 +
roverlay/tools/ebuildenv.py | 8 +-
10 files changed, 458 insertions(+), 138 deletions(-)
diff --git a/roverlay/overlay/additionsdir.py b/roverlay/overlay/additionsdir.py
index f0a6be4..3031a69 100644
--- a/roverlay/overlay/additionsdir.py
+++ b/roverlay/overlay/additionsdir.py
@@ -9,8 +9,10 @@ import re
EMPTY_TUPLE = ()
-
class AdditionsDir ( object ):
+ """AdditionsDir represents a filesystem directory (that does not need
+ to exist).
+ """
def __init__ ( self, fspath, name=None, parent=None ):
self.root = str ( fspath ) if fspath else None
@@ -24,7 +26,38 @@ class AdditionsDir ( object ):
__bool__ = exists
+ def iter_entries ( self ):
+ """Generator that yields the directory content of this dir."""
+ if self.exists():
+ for name in os.listdir ( self.root ):
+ yield ( name, ( self.root + os.sep + name ) )
+ # --- end of iter_entries (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_entries() )
+ # --- end of __iter__ (...) ---
+
+ def get_child ( self, fspath, name ):
+ """Returns a new instance with the given fspath/name and this object
+ as parent.
+ arguments:
+
+ * fspath --
+ * name --
+ """
+ return self.__class__ (
+ fspath = fspath,
+ name = name,
+ parent = self
+ )
+ # --- end of get_child (...) ---
+
def get_subdir ( self, relpath ):
+ """Returns a new instance which represents a subdirectory of this dir.
+
+ arguments:
+ * relpath -- path of the new instance, relative to the root of this dir
+ """
if self.root:
return self.__class__ (
fspath = ( self.root + os.sep + relpath ),
@@ -36,6 +69,11 @@ class AdditionsDir ( object ):
# --- end of get_subdir (...) ---
def get_obj_subdir ( self, obj ):
+ """Like get_obj_subdir(), but uses obj.name as relpath.
+
+ arguments:
+ * obj --
+ """
return self.get_subdir ( obj.name )
# --- end of get_obj_subdir (...) ---
@@ -43,8 +81,11 @@ class AdditionsDir ( object ):
return self.root or ""
# --- end of __str__ (...) ---
+# --- end of AdditionsDir ---
+
class _AdditionsDirView ( object ):
+ """view objects implement AdditionsDir actions, e.g. find certain files."""
def __init__ ( self, additions_dir ):
self._additions_dir = additions_dir
@@ -54,48 +95,72 @@ class _AdditionsDirView ( object ):
return bool ( self._additions_dir )
# --- end of __bool__ (...) ---
+ @property
+ def name ( self ):
+ return self._additions_dir.name
+ # --- end of name (...) ---
+
+ def _fs_iter_regex ( self, regex ):
+ """Iterates over the content of the additions dir and yields
+ 3-tuples ( match, path, name ) for each name that matches the given
+ regex.
+
+ arguments:
+ * regex --
+ """
+ fre = re.compile ( regex )
+
+ for name, fspath in self._additions_dir:
+ fmatch = fre.match ( name )
+ if fmatch:
+ yield ( fmatch, fspath, name )
+ # --- end of _fs_iter_regex (...) ---
+
+# --- end of _AdditionsDirView ---
+
class _EbuildAdditionsView ( _AdditionsDirView ):
# with leading '-'
- RE_PVR = '[-](?P<pvr>[0-9.]+([-]r[0-9]+)?)'
+ RE_PVR = '[-](?P<pvr>[0-9].*?([-]r[0-9]+)?)'
def __init__ ( self, additions_dir ):
+ """Ebuild additions dir view constructor.
+ Also calls prepare() if declared.
+
+ arguments:
+ * additions_dir --
+ """
super ( _EbuildAdditionsView, self ).__init__ (
additions_dir=additions_dir
)
- if hasattr ( self, 'prepare' ):
- self.prepare()
+ if hasattr ( self, 'prepare' ): self.prepare()
# --- end of __init__ (...) ---
- def _fs_iter_regex ( self, regex ):
- fre = re.compile ( regex )
-
- root = self._additions_dir.root
- for fname in os.listdir ( root ):
- fmatch = fre.match ( fname )
- if fmatch:
- yield ( fmatch, ( root + os.sep + fname ), fname )
- # --- end of _fs_iter_regex (...) ---
+# --- end of _EbuildAdditionsView ---
class EbuildView ( _EbuildAdditionsView ):
+ """View object for finding/importing ebuilds."""
RE_EBUILD_SUFFIX = '[.]ebuild'
def has_ebuilds ( self ):
+ """Returns True if there are any ebuilds that could be imported."""
return bool ( getattr ( self, '_ebuilds', None ) )
# --- end of has_ebuilds (...) ---
def get_ebuilds ( self ):
+ """Returns all ebuilds as list of 3-tuples ( pvr, path, name )."""
return self._ebuilds
# --- end of get_ebuilds (...) ---
def __iter__ ( self ):
- return iter ( self.get_ebuilds )
+ return iter ( self.get_ebuilds() )
# --- end of __iter__ (...) ---
- def _prepare ( self ):
+ def prepare ( self ):
+ """Searches for ebuilds and create self._ebuilds."""
if self._additions_dir.exists():
ebuilds = list()
@@ -104,21 +169,72 @@ class EbuildView ( _EbuildAdditionsView ):
):
# deref symlinks
ebuilds.append (
- fmatch.group ( 'pvr' ), os.path.abspath ( fpath ), fname
+ ( fmatch.group ( 'pvr' ), os.path.abspath ( fpath ), fname )
+ )
+
+ self._ebuilds = ebuilds
+ # --- end of prepare (...) --
+
+# --- end of EbuildView ---
+
+
+class CategoryView ( _AdditionsDirView ):
+ """View object that creates EbuildView objects."""
+
+ def iter_packages ( self ):
+ for name, fspath in self._additions_dir:
+ if os.path.isdir ( fspath ):
+ yield EbuildView (
+ self._additions_dir.get_child ( fspath, name )
+ )
+ # --- end of iter_packages (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_packages() )
+ # --- end of __iter__ (...) ---
+
+# --- end of CategoryView ---
+
+
+class CategoryRootView ( _AdditionsDirView ):
+ """View object that creates CategoryView objects."""
+
+ def iter_categories ( self ):
+ for name, fspath in self._additions_dir:
+ if os.path.isdir ( fspath ) and (
+ '-' in name or name == 'virtual'
+ ):
+ yield CategoryView (
+ self._additions_dir.get_child ( fspath, name )
)
- # --- end of _prepare (...) --
+ # --- end of iter_categories (...) ---
+
+ def __iter__ ( self ):
+ return iter ( self.iter_categories() )
+ # --- end of __iter__ (...) ---
+# --- end of CategoryRootView ---
class PatchView ( _EbuildAdditionsView ):
+ """View object for finding ebuild patches."""
RE_PATCH_SUFFIX = '(?P<patchno>[0-9]{4})?[.]patch'
def has_patches ( self ):
+ """Returns True if one or more patches are available."""
return bool ( getattr ( self, '_patches', None ) )
# --- end of has_patches (...) ---
def get_patches ( self, pvr, fallback_to_default=True ):
+ """Returns a list of patches that should be applied to the ebuild
+ referenced by pvr.
+
+ arguments:
+ * pvr -- $PVR of the ebuild
+ * fallback_to_default -- return default patches if no version-specific
+ ones are available (defaults to True)
+ """
patches = self._patches.get ( pvr, None )
if patches:
return patches
@@ -129,10 +245,12 @@ class PatchView ( _EbuildAdditionsView ):
# --- end of get_patches (...) ---
def get_default_patches ( self ):
+ """Returns the default patches."""
return getattr ( self, '_default_patches', EMPTY_TUPLE )
# --- end of get_default_patches (...) ---
def prepare ( self ):
+ """Searches for ebuild patch files."""
def patchno_sort ( iterable ):
return list (
v[1] for v in sorted ( iterable, key=lambda k: k[0] )
@@ -170,11 +288,23 @@ class PatchView ( _EbuildAdditionsView ):
):
patchno = fmatch.group ( 'patchno' )
- default_patches.append (
- ( ( -1 if patchno is None else int ( patchno ) ), fpath )
- )
+ if patchno in self._patches:
+ if len ( self._patches [patchno] ) < 2:
+
+ del self._patches [patchno]
+ default_patches.append (
+ ( ( -1 if patchno is None else int ( patchno ) ), fpath )
+ )
+ else:
+ pass
+ else:
+ default_patches.append (
+ ( ( -1 if patchno is None else int ( patchno ) ), fpath )
+ )
# -- end for;
if default_patches:
self._default_patches = patchno_sort ( default_patches )
# --- end of prepare (...) ---
+
+# --- end of PatchView ---
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index 0e33fc7..558aa71 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -91,6 +91,11 @@ class Category ( object ):
# --- end of add (...) ---
def drop_package ( self, name ):
+ """Removes a package and its fs content from this category.
+
+ arguments:
+ * name -- name of the package
+ """
p = self._subdirs [name]
del self._subdirs [name]
p.fs_destroy()
@@ -117,6 +122,20 @@ class Category ( object ):
return os.path.isdir ( self.physical_location + os.sep + _dir )
# --- end of has_category (...) ---
+ def import_ebuilds ( self, catview, *args, **kwargs ):
+ """Imports ebuilds into this category.
+
+ arguments:
+ * catview -- view object that creates EbuildView objects
+ * *args, **kwargs -- (keyword) arguments that will be passed to
+ package dirs
+ """
+ for eview in catview:
+ self._get_package_dir ( eview.name ).import_ebuilds (
+ eview, *args, **kwargs
+ )
+ # --- end of import_ebuilds (...) ---
+
def list_package_names ( self ):
for name, subdir in self._subdirs.items():
if not subdir.empty():
diff --git a/roverlay/overlay/pkgdir/__init__.py b/roverlay/overlay/pkgdir/__init__.py
index baf4eea..d33ced2 100644
--- a/roverlay/overlay/pkgdir/__init__.py
+++ b/roverlay/overlay/pkgdir/__init__.py
@@ -59,6 +59,8 @@ def _configure():
if hasattr ( _package_dir_class, 'init_cls' ):
_package_dir_class.init_cls()
+ else:
+ _package_dir_class.init_base_cls()
logging.getLogger ('pkgdir').debug (
'Using {!r} as manifest implementation.'.format ( mf_impl )
diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py
index e2f0f09..e5c0558 100644
--- a/roverlay/overlay/pkgdir/packagedir_base.py
+++ b/roverlay/overlay/pkgdir/packagedir_base.py
@@ -15,24 +15,33 @@ Each PackageDir instance represents one package name (e.g. "seewave").
__all__ = [ 'PackageDirBase', ]
+
import os
+import shutil
import sys
import threading
-import shutil
-import roverlay.overlay.additionsdir
+import roverlay.config
+import roverlay.packageinfo
+import roverlay.util
+
+import roverlay.tools.ebuild
+import roverlay.tools.ebuildenv
import roverlay.tools.patch
-from roverlay import util
-from roverlay.packageinfo import PackageInfo
-from roverlay.overlay.pkgdir.metadata import MetadataJob
+import roverlay.overlay.additionsdir
+
+import roverlay.overlay.pkgdir.distroot.static
+import roverlay.overlay.pkgdir.metadata
class PackageDirBase ( object ):
"""The PackageDir base class that implements most functionality except
for Manifest file creation."""
+ #DISTROOT =
EBUILD_SUFFIX = '.ebuild'
+ #FETCHENV =
SUPPRESS_EXCEPTIONS = True
# MANIFEST_THREADSAFE (tri-state)
@@ -42,6 +51,20 @@ class PackageDirBase ( object ):
#
MANIFEST_THREADSAFE = None
+ @classmethod
+ def init_base_cls ( cls ):
+ # env for calling "ebuild <ebuild file> fetch"
+ fetch_env = roverlay.tools.ebuildenv.FetchEnv()
+ fetch_env.add_overlay_dir (
+ roverlay.config.get_or_fail ( 'OVERLAY.dir' )
+ )
+
+ cls.DISTROOT = (
+ roverlay.overlay.pkgdir.distroot.static.get_configured ( static=True )
+ )
+ cls.FETCHENV = fetch_env
+ # --- end of init_cls (...) ---
+
def __init__ ( self,
name, logger, directory, get_header, runtime_incremental, parent
):
@@ -73,15 +96,16 @@ class PackageDirBase ( object ):
self.get_header = get_header
self.runtime_incremental = runtime_incremental
- self._metadata = MetadataJob (
+ self._metadata = roverlay.overlay.pkgdir.metadata.MetadataJob (
filepath = self.physical_location + os.sep + 'metadata.xml',
logger = self.logger
)
# <dir>/<PN>-<PVR>.ebuild
- self.ebuild_filepath_format = \
- self.physical_location + os.sep + \
- self.name + "-{PVR}" + self.__class__.EBUILD_SUFFIX
+ self.ebuild_filepath_format = (
+ self.physical_location + os.sep
+ + self.name + "-{PVR}" + self.__class__.EBUILD_SUFFIX
+ )
# used to track changes for this package dir
self.modified = False
@@ -115,7 +139,7 @@ class PackageDirBase ( object ):
* efile -- full path to the ebuild file
* pvr -- version ($PVR) of the ebuild
"""
- p = PackageInfo (
+ p = roverlay.packageinfo.PackageInfo (
physical_only=True, pvr=pvr, ebuild_file=efile
)
self._packages [ p ['ebuild_verstr'] ] = p
@@ -253,7 +277,7 @@ class PackageDirBase ( object ):
def has_ebuilds ( self ):
"""Returns True if this PackageDir has any ebuild files (filesystem)."""
for p in self._packages.values():
- if p ['physical_only'] or p.has ( 'ebuild' ):
+ if p ['physical_only'] or p.has ( 'ebuild' ) or p ['imported']:
return True
return False
# --- end of has_ebuilds (...) ---
@@ -361,6 +385,7 @@ class PackageDirBase ( object ):
# --- end of purge_package (...) ---
def fs_destroy ( self ):
+ """Destroys the filesystem content of this package dir."""
pvr_list = list ( self._packages.keys() )
for pvr in pvr_list:
self.purge_package ( pvr )
@@ -534,12 +559,13 @@ class PackageDirBase ( object ):
return success
# --- end of write (...) ---
- def import_extra_ebuilds ( self, overwrite, additions_dir ):
+ def import_ebuilds ( self, eview, overwrite, nosync=False ):
"""Imports ebuilds from an additions dir into this package dir.
arguments:
- * overwrite -- whether to overwrite existing ebuilds or not
- * additions_dir -- additions dir for this package dir
+ * eview -- additions dir ebuild view
+ * overwrite -- whether to overwrite existing ebuilds or not
+ * nosync -- if True: don't fetch src files (defaults to False)
"""
def import_ebuild_efile ( pvr, efile_src, fname ):
@@ -568,17 +594,22 @@ class PackageDirBase ( object ):
shutil.copyfile ( efile_src, efile_dest )
# create PackageInfo and register it
- p = PackageInfo (
- imported=True, pvr=pvr, ebuild_file=efile
+ p = roverlay.packageinfo.PackageInfo (
+ imported=True, pvr=pvr, ebuild_file=efile_dest
)
self._packages [ p ['ebuild_verstr'] ] = p
-
# manifest needs to be rewritten
self._need_manifest = True
- # fetch SRC_URI?
- # ebuild <ebuild> fetch?
+ # fetch SRC_URI using ebuild(1)
+ if not nosync and not roverlay.tools.ebuild.doebuild_fetch (
+ efile_dest, self.logger,
+ self.FETCHENV.get_env (
+ self.DISTROOT.get_distdir ( self.name ).get_root()
+ )
+ ):
+ raise Exception ( "doebuild_fetch() failed." )
# imported ebuilds cannot be used for generating metadata.xml
##self._need_metadata = True
@@ -602,14 +633,12 @@ class PackageDirBase ( object ):
raise
# --- end of import_ebuild_efile (...) ---
- eview = roverlay.overlay.additionsdir.EbuildView ( additions_dir )
-
if not self.physical_location:
raise Exception (
- "import_extra_ebuilds() needs a non-virtual package dir!"
+ "import_ebuilds() needs a non-virtual package dir!"
)
elif eview.has_ebuilds():
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
if not self._packages:
for pvr, efile, fname in eview.get_ebuilds():
@@ -625,7 +654,7 @@ class PackageDirBase ( object ):
for pvr, efile, fname in eview.get_ebuilds():
if pvr not in self._packages:
import_ebuild_efile ( pvr, efile, fname )
- # --- end of import_extra_ebuilds (...) ---
+ # --- end of import_ebuilds (...) ---
def write_ebuilds ( self, overwrite, additions_dir, shared_fh=None ):
"""Writes all ebuilds.
@@ -744,7 +773,7 @@ class PackageDirBase ( object ):
for pvr, efile, p_info in list ( ebuilds_to_write() ):
if not hasdir:
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
hasdir = True
if (
@@ -823,6 +852,12 @@ class PackageDirBase ( object ):
return True
else:
return False
+ elif (
+ hasattr ( self, '_write_import_manifest' )
+ and self._write_import_manifest()
+ ):
+ self._need_manifest = False
+ return True
elif ignore_empty:
return True
else:
@@ -843,7 +878,7 @@ class PackageDirBase ( object ):
self.generate_metadata ( skip_if_existent=True )
if shared_fh is None:
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
if self._metadata.write():
self._need_metadata = False
self._need_manifest = True
diff --git a/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py b/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
index c9e3d84..5217f6a 100644
--- a/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
+++ b/roverlay/overlay/pkgdir/packagedir_ebuildmanifest.py
@@ -6,81 +6,106 @@
__all__ = [ 'PackageDir', ]
+import os
import threading
+
import roverlay.config
import roverlay.tools.ebuild
import roverlay.tools.ebuildenv
+
import roverlay.overlay.pkgdir.packagedir_base
-import roverlay.overlay.pkgdir.distroot.static
class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
"""
PackageDir class that uses the ebuild executable for Manifest writing.
"""
- #DISTROOT = None
#MANIFEST_ENV = None
- MANIFEST_LOCK = threading.Lock()
MANIFEST_THREADSAFE = False
@classmethod
def init_cls ( cls ):
+ cls.init_base_cls()
+
env = roverlay.tools.ebuildenv.ManifestEnv()
env.add_overlay_dir ( roverlay.config.get_or_fail ( 'OVERLAY.dir' ) )
-
- cls.DISTROOT = (
- roverlay.overlay.pkgdir.distroot.static.get_configured ( static=True )
- )
-
cls.MANIFEST_ENV = env
# --- end of init_cls (...) ---
- def _write_manifest ( self, pkgs_for_manifest ):
- """Generates and writes the Manifest file for this package.
+ def _do_ebuildmanifest ( self, ebuild_file, distdir=None ):
+ """Calls doebuild_manifest().
+ Returns True on success, else False. Also handles result logging.
- expects: called after writing metadata/ebuilds
-
- returns: success (True/False)
+ arguments:
+ * ebuild_file -- ebuild file that should be used for the doebuild call
+ * distdir -- distdir object (optional)
"""
try:
- self.MANIFEST_LOCK.acquire()
-
- # choosing one ebuild for calling "ebuild <ebuild>" is sufficient
- ebuild_file = pkgs_for_manifest [0] ['ebuild_file']
-
- distdir = self.DISTROOT.get_distdir ( pkgs_for_manifest [0] ['name'] )
-
- # add hardlinks to DISTROOT (replacing existing files/links)
- for p in pkgs_for_manifest:
- # TODO: optimize this further?
- # -> "not has physical_only?"
- # (should be covered by "has package_file")
- distdir.add ( p ['package_file'], p ['package_src_destpath'] )
-
-
- if roverlay.tools.ebuild.doebuild_manifest (
+ call = roverlay.tools.ebuild.doebuild_manifest (
ebuild_file, self.logger,
- self.MANIFEST_ENV.get_env ( distdir.get_root() )
- ):
- self.logger.debug ( "Manifest written." )
- ret = True
-
- else:
- self.logger.error (
- 'Couldn\'t create Manifest for {ebuild}! '
- 'Return code was {ret}.'.format (
- ebuild=ebuild_file, ret=ebuild_call.returncode
+ self.MANIFEST_ENV.get_env (
+ distdir.get_root() if distdir is not None else (
+ self.DISTROOT.get_distdir ( self.name ).get_root()
)
- )
- ret = False
-
+ ),
+ return_success=False
+ )
except Exception as err:
self.logger.exception ( err )
raise
+ # -- end try
+
+ if call.returncode == os.EX_OK:
+ self.logger.debug ( "Manifest written." )
+ return True
+ else:
+ self.logger.error (
+ 'Couldn\'t create Manifest for {ebuild}! '
+ 'Return code was {ret}.'.format ( ebuild=ebuild_file, ret=ret )
+ )
+ return False
+ # --- end of _do_ebuildmanifest (...) ---
+
+ def _write_import_manifest ( self ):
+ """Writes a Manifest file if this package has any imported ebuilds.
+
+ Returns True if a Manifest has been written, else False.
+ """
+ try:
+ pkg = next (
+ p for p in self._packages.values()
+ if p.has ( 'imported', 'ebuild_file' )
+ )
+ except StopIteration:
+ # no imported ebuilds
+ return False
+ # -- end try
+
+ self.logger.debug ( "Writing (import-)Manifest" )
+ return self._do_ebuildmanifest ( pkg ['ebuild_file'] )
+ # --- end of _write_import_manifest (...) ---
+
+ def _write_manifest ( self, pkgs_for_manifest ):
+ """Generates and writes the Manifest file for this package.
- finally:
- self.MANIFEST_LOCK.release()
+ expects: called after writing metadata/ebuilds
- return ret
+ returns: success (True/False)
+ """
+ # choosing one ebuild for calling "ebuild <ebuild>" is sufficient
+ ebuild_file = pkgs_for_manifest [0] ['ebuild_file']
+ distdir = self.DISTROOT.get_distdir ( self.name )
+
+ # add hardlinks to DISTROOT (replacing existing files/links)
+ for p in pkgs_for_manifest:
+ # TODO: optimize this further?
+ # -> "not has physical_only?"
+ # (should be covered by "has package_file")
+ distdir.add ( p ['package_file'], p ['package_src_destpath'] )
+ # -- end for;
+
+ return self._do_ebuildmanifest ( ebuild_file, distdir )
# --- end of write_manifest (...) ---
+
+# --- end of PackageDir #ebuildmanifest ---
diff --git a/roverlay/overlay/pkgdir/packagedir_portagemanifest.py b/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
index 3c4d728..6596dec 100644
--- a/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
+++ b/roverlay/overlay/pkgdir/packagedir_portagemanifest.py
@@ -13,7 +13,9 @@ import portage.manifest
import portage.exception
import logging
-logging.getLogger ( __name__ ).warning ( "experimental code" )
+logging.getLogger ( __name__ ).warning (
+ "experimental code, importing ebuilds doesn't work!"
+)
del logging
import roverlay.config
@@ -23,9 +25,17 @@ import roverlay.overlay.pkgdir.packagedir_base
import roverlay.overlay.pkgdir.distroot
class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
+ # FIXME: portagemanifest is broken, it cannot create Manifest files for
+ # package dirs with imported ebuilds
MANIFEST_THREADSAFE = True
+ def import_ebuilds ( self, *args, **kwargs ):
+ raise NotImplementedError (
+ "ebuild imports not supported by portagemanifest!"
+ )
+ # --- end of import_ebuilds (...) ---
+
def _scan_add_package ( self, efile, pvr ):
"""Called for each ebuild that is found during scan().
Creates a PackageInfo for the ebuild and adds it to self._packages.
@@ -107,7 +117,7 @@ class PackageDir ( roverlay.overlay.pkgdir.packagedir_base.PackageDirBase ):
# * ...
#
- distdir = roverlay.overlay.pkgdir.distroot.get_distdir ( self.name )
+ distdir = self.DISTROOT.get_distdir ( self.name )
# allow_missing=True -- don't write empty Manifest files
manifest = portage.manifest.Manifest (
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index ca71b81..a9d16c4 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -17,24 +17,24 @@ due do double-linkage between PackageInfo and PackageDir.
__all__ = [ 'Overlay', ]
-import threading
import logging
-import shutil
import os
+import shutil
+import threading
-from roverlay import config, util
-
-from roverlay.overlay.category import Category
-from roverlay.overlay.header import EbuildHeader
-
+import roverlay.config
+import roverlay.util
import roverlay.overlay.additionsdir
+import roverlay.overlay.category
+import roverlay.overlay.header
+
class Overlay ( object ):
- DEFAULT_USE_DESC = '\n'.join ( (
- 'byte-compile - enable byte compiling',
+ DEFAULT_USE_DESC = (
+ 'byte-compile - enable byte compiling\n'
'R_suggests - install recommended packages'
- ) )
+ )
@classmethod
def new_configured ( cls,
@@ -51,23 +51,24 @@ class Overlay ( object ):
* write_allowed --
* skip_manifest --
* runtime_incremental --
- * readonly -- see Overlay.__init__
"""
- name = config.get_or_fail ( 'OVERLAY.name' )
+ optional = roverlay.config.get
+ mandatory = roverlay.config.get_or_fail
+
return cls (
- name = name,
- logger = (
- logger or logging.getLogger ( 'Overlay:' + name )
- ),
- directory = config.get_or_fail ( 'OVERLAY.dir' ),
- default_category = config.get_or_fail ( 'OVERLAY.category' ),
- eclass_files = config.get ( 'OVERLAY.eclass_files', None ),
- ebuild_header = config.get ( 'EBUILD.default_header', None ),
- incremental = incremental,
+ name = mandatory ( 'OVERLAY.name' ),
+ logger = logger,
+ directory = mandatory ( 'OVERLAY.dir' ),
+ default_category = mandatory ( 'OVERLAY.category' ),
+ eclass_files = optional ( 'OVERLAY.eclass_files' ),
+ ebuild_header = optional ( 'EBUILD.default_header' ),
write_allowed = write_allowed,
+ incremental = incremental,
skip_manifest = skip_manifest,
- additions_dir = config.get_or_fail ( 'OVERLAY.additions_dir' ),
+ additions_dir = optional ( 'OVERLAY.additions_dir' ),
+ use_desc = optional ( 'OVERLAY.use_desc' ),
runtime_incremental = runtime_incremental,
+ keep_n_ebuilds = optional ( 'OVERLAY.keep_nth_latest' ),
)
# --- end of new_configured (...) ---
@@ -83,7 +84,9 @@ class Overlay ( object ):
incremental,
skip_manifest,
additions_dir,
- runtime_incremental=False
+ use_desc=None,
+ runtime_incremental=False,
+ keep_n_ebuilds=None
):
"""Initializes an overlay.
@@ -108,9 +111,11 @@ class Overlay ( object ):
patches. The directory has to exist (it will
be checked here).
A value of None or "" disables additions.
+ * use_desc -- text for profiles/use.desc
* runtime_incremental -- see package.py:PackageDir.__init__ (...),
Defaults to False (saves memory but costs time)
-
+ * keep_n_ebuilds -- number of ebuilds to keep (per package),
+ any "false" Value (None, 0, ...) disables this
"""
self.name = name
self.logger = logger.getChild ( 'overlay' )
@@ -126,17 +131,31 @@ class Overlay ( object ):
self._profiles_dir = self.physical_location + os.sep + 'profiles'
self._catlock = threading.Lock()
self._categories = dict()
- self._header = EbuildHeader ( ebuild_header )
self.skip_manifest = skip_manifest
+ self._header = roverlay.overlay.header.EbuildHeader ( ebuild_header )
+ self._use_desc = (
+ use_desc.rstrip() if use_desc is not None else self.DEFAULT_USE_DESC
+ )
+
+ if keep_n_ebuilds:
+ self.keep_n_ebuilds = keep_n_ebuilds
+
if additions_dir:
if os.path.isdir ( additions_dir ):
- self.additions_dirpath = os.path.abspath ( additions_dir )
+ additions_dirpath = os.path.abspath ( additions_dir )
else:
raise ValueError (
"additions dir {} does not exist!".format ( additions_dir )
)
+ else:
+ additions_dirpath = None
+ # -- end if
+
+ self.additions_dir = (
+ roverlay.overlay.additionsdir.AdditionsDir ( additions_dirpath )
+ )
# calculating eclass names twice,
# once here and another time when calling _init_overlay
@@ -150,6 +169,8 @@ class Overlay ( object ):
# incremental writing, which writes ebuilds as soon as they're
# ready)
self.scan()
+
+ self.import_ebuilds ( overwrite=( not incremental ) )
# --- end of __init__ (...) ---
def _get_category ( self, category ):
@@ -162,7 +183,7 @@ class Overlay ( object ):
self._catlock.acquire()
try:
if not category in self._categories:
- newcat = Category (
+ newcat = roverlay.overlay.category.Category (
category,
self.logger,
self.physical_location + os.sep + category,
@@ -218,7 +239,7 @@ class Overlay ( object ):
eclass_dir = self.physical_location + os.sep + 'eclass'
try:
eclass_names = list()
- util.dodir ( eclass_dir )
+ roverlay.util.dodir ( eclass_dir )
for destname, eclass in self._get_eclass_import_info ( False ):
dest = eclass_dir + os.sep + destname + '.eclass'
@@ -271,7 +292,7 @@ class Overlay ( object ):
self._get_category ( self.default_category )
# profiles/
- util.dodir ( self._profiles_dir )
+ roverlay.util.dodir ( self._profiles_dir )
# profiless/repo_name
write_profiles_file ( 'repo_name', self.name + '\n' )
@@ -284,17 +305,13 @@ class Overlay ( object ):
write_profiles_file ( 'categories', cats + '\n' )
# profiles/use.desc
- use_desc = config.get (
- 'OVERLAY.use_desc',
- fallback_value=self.__class__.DEFAULT_USE_DESC
- )
- if use_desc:
- write_profiles_file ( 'use.desc', use_desc + '\n' )
+ if self._use_desc:
+ write_profiles_file ( 'use.desc', self._use_desc + '\n' )
# --- end of write_profiles_dir (...) ---
try:
# mkdir overlay root
- util.dodir ( self.physical_location, mkdir_p=True )
+ roverlay.util.dodir ( self.physical_location, mkdir_p=True )
self._import_eclass ( reimport_eclass )
@@ -340,13 +357,19 @@ class Overlay ( object ):
# --- end of has_category (...) ---
def find_duplicate_packages ( self, _default_category=None ):
+ """Searches for packages that exist in the default category and
+ another one and returns a set of package names.
+
+ arguments:
+ * _default_category -- category object
+ """
default_category = (
_default_category if _default_category is None
else self._categories.get ( self.default_category, None )
)
if default_category:
- duplicate_pkg = set()
+ duplicate_pkg = set()
for category in self._categories.values():
if category is not default_category:
@@ -361,6 +384,13 @@ class Overlay ( object ):
# --- end of find_duplicate_packages (...) ---
def remove_duplicate_ebuilds ( self, reverse ):
+ """Searcges for packages that exist in the default category and
+ another one and removes them from either one, depending on whether
+ reverse if True (other will be removed) or False (default category).
+
+ arguments:
+ * reverse
+ """
default_category = self._categories.get ( self.default_category, None )
if default_category:
if reverse:
@@ -398,6 +428,7 @@ class Overlay ( object ):
# --- end of remove_duplicate_ebuilds (...) ---
def remove_empty_categories ( self ):
+ """Removes empty categories."""
catlist = self._categories.items()
for cat in catlist:
cat[1].remove_empty()
@@ -430,6 +461,21 @@ class Overlay ( object ):
return not self._writeable
# --- end of readonly (...) ---
+ def import_ebuilds ( self, overwrite, nosync=False ):
+ """Imports ebuilds from the additions dir.
+
+ arguments:
+ * overwrite -- whether to overwrite existing ebuilds
+ * nosync -- if True: don't fetch src files (defaults to False)
+ """
+ for catview in (
+ roverlay.overlay.additionsdir.CategoryRootView ( self.additions_dir )
+ ):
+ self._get_category ( catview.name ).import_ebuilds (
+ catview, overwrite=overwrite
+ )
+ # --- end of import_ebuilds (...) ---
+
def scan ( self, **kw ):
def scan_categories():
for x in os.listdir ( self.physical_location ):
@@ -478,20 +524,17 @@ class Overlay ( object ):
Note: This is not thread-safe, it's expected to be called when
ebuild creation is done.
"""
+
if self._writeable:
self._init_overlay ( reimport_eclass=True )
- additions_dir = roverlay.overlay.additionsdir.AdditionsDir (
- getattr ( self, 'additions_dirpath', None )
- )
-
for cat in self._categories.values():
cat.write (
overwrite_ebuilds = False,
- keep_n_ebuilds = config.get ( 'OVERLAY.keep_nth_latest', None ),
+ keep_n_ebuilds = getattr ( self, 'keep_n_ebuilds', None ),
cautious = True,
write_manifest = not self.skip_manifest,
- additions_dir = additions_dir.get_obj_subdir ( cat ),
+ additions_dir = self.additions_dir.get_obj_subdir ( cat ),
)
else:
# FIXME debug print
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index 84a7d45..90b4250 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -98,6 +98,7 @@ class PackageInfo ( object ):
'origin',
'ebuild',
'ebuild_file',
+ 'imported',
'physical_only',
'src_uri',
))
@@ -341,6 +342,10 @@ class PackageInfo ( object ):
# 'physical_only' not in self._info -> assume False
return False
+ elif key_low == 'imported':
+ # 'imported' not in self._info -> assume False
+ return False
+
elif key_low == 'src_uri':
if 'src_uri_base' in self._info:
return \
@@ -386,6 +391,50 @@ class PackageInfo ( object ):
raise KeyError ( key )
# --- end of get (...) ---
+ def get_create (
+ self, key, newtype, convert=False, check_type=True, create_kw=None
+ ):
+ """Tries to get a value from the info dict. Creates it as newtype if
+ necessary.
+
+ Note: This operation is "unsafe". No locks will be acquired etc.
+
+ arguments:
+ * key -- info key
+ * newtype -- "expected type", also used for creating new values
+ * convert -- if True: convert existing value (defaults to False)
+ * check_type -- if True: check whether the type of existing value is
+ a (sub-)type of newtype (defaults to True)
+ This arg can also be a type.
+ Has no effect if convert is set to True
+ * create_kw -- either None or a dict that will used as keyword args
+ when creating newtype
+ """
+ v = self.get ( key, do_fallback=True )
+ if v is None:
+ newv = newtype ( **create_kw ) if create_kw else newtype()
+ self._info [key] = newv
+ return newv
+ elif convert:
+ return newtype ( v )
+ elif check_type:
+ want_type = (
+ check_type if ( type ( check_type ) is type ) else newtype
+ )
+
+ #if type ( v ) is want_type:
+ if isinstance ( v, want_type ):
+ return v
+ else:
+ raise TypeError (
+ "key {k} should have type {t0}, but is a {t1}!".format (
+ k=key, t0=want_type, t1=type(v)
+ )
+ )
+ else:
+ return v
+ # --- end of get_create (...) ---
+
def get_desc_data ( self ):
"""Returns the DESCRIPTION data for this PackageInfo (by reading the
R package file if necessary).
@@ -557,7 +606,7 @@ class PackageInfo ( object ):
else:
self.logger.error (
- "in _update(): unknown info key {}!".format ( key )
+ "in _update(): unknown info key {!r}!".format ( key )
)
# -- end for;
diff --git a/roverlay/tools/ebuild.py b/roverlay/tools/ebuild.py
index d9f4e9a..e8f7e37 100644
--- a/roverlay/tools/ebuild.py
+++ b/roverlay/tools/ebuild.py
@@ -20,6 +20,7 @@ _EBUILD_CMDV = (
def doebuild (
ebuild_file, command, logger, env=None, opts=(), return_success=True
):
+ logger.debug ( "doebuild: {c}, {e!r}".format ( e=ebuild_file, c=command ) )
return roverlay.tools.runcmd.run_command (
cmdv = ( _EBUILD_CMDV + opts + ( ebuild_file, command ) ),
env = env,
diff --git a/roverlay/tools/ebuildenv.py b/roverlay/tools/ebuildenv.py
index 40f6495..7c5accb 100644
--- a/roverlay/tools/ebuildenv.py
+++ b/roverlay/tools/ebuildenv.py
@@ -101,8 +101,14 @@ class EbuildEnv ( object ):
# --- end of EbuildEnv ---
+
class FetchEnv ( EbuildEnv ):
- pass
+ def _make_common_env ( self ):
+ super ( FetchEnv, self )._make_common_env()
+ # "Cannot chown a lockfile"
+ self._common_env ['FEATURES'] += " -distlocks"
+ # --- end of _make_common_env (...) ---
+
# --- end of FetchEnv ---
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-06-13 16:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-13 16:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/tools/, roverlay/, roverlay/overlay/pkgdir/, roverlay/overlay/ André Erdmann
2013-06-12 21:10 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox