* [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/metadata/, roverlay/overlay/
@ 2012-07-30 8:52 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: 548e6ceede8e8ba8d75492656656275f13b20613
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul 19 16:53:08 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul 19 16:53:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=548e6cee
incremental overlay writing
prepare for OverlayCreator
geändert: roverlay/overlay/category.py
geändert: roverlay/overlay/creator.py
geändert: roverlay/overlay/metadata/__init__.py
geändert: roverlay/overlay/metadata/nodes.py
geändert: roverlay/overlay/package.py
geändert: roverlay/overlay/root.py
---
roverlay/overlay/category.py | 24 +-
roverlay/overlay/creator.py | 11 +-
roverlay/overlay/metadata/__init__.py | 84 ++++--
roverlay/overlay/metadata/nodes.py | 40 +--
roverlay/overlay/package.py | 535 +++++++++++++++------------------
roverlay/overlay/root.py | 23 +-
6 files changed, 354 insertions(+), 363 deletions(-)
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index afa2456..9cf8ad9 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -68,6 +68,13 @@ class Category ( object ):
not False in ( d.empty() for d in self._subdirs.values() )
# --- end of empty (...) ---
+ def finalize_write_incremental ( self ):
+ for subdir in self._subdirs.values():
+ if subdir.modified:
+ subdir.write_incremental()
+ subdir.finalize_write_incremental()
+ # --- end of finalize_write_incremental (...) ---
+
def _get_package_dir ( self, pkg_name ):
if not pkg_name in self._subdirs:
self._lock.acquire()
@@ -84,7 +91,7 @@ class Category ( object ):
return self._subdirs [pkg_name]
# --- end of _get_package_dir (...) ---
- def add ( self, package_info, write_after_add=False, header=None ):
+ def add ( self, package_info, **pkg_add_kw ):
"""Adds a package to this category.
arguments:
@@ -93,13 +100,7 @@ class Category ( object ):
returns: success
"""
subdir = self._get_package_dir ( package_info ['name'] )
- if subdir.add ( package_info ):
- if write_after_add:
- roverlay.util.dodir ( subdir.physical_location )
- subdir.write_incremental ( default_header=header )
- return True
- else:
- return False
+ return subdir.add ( package_info, **pkg_add_kw )
# --- end of add (...) ---
def generate_metadata ( self, **metadata_kw ):
@@ -164,9 +165,10 @@ class Category ( object ):
# so collect the list of package dirs before iterating over it
subdirs = tuple ( self._subdirs.values() )
- for package in subdirs:
- roverlay.util.dodir ( package.physical_location )
- package.write_incremental ( **write_kw )
+ for subdir in subdirs:
+ if subdir.modified:
+ roverlay.util.dodir ( subdir.physical_location )
+ subdir.write_incremental ( **write_kw )
except Exception as e:
self.logger.exception ( e )
# --- end of write_incremental (...) ---
diff --git a/roverlay/overlay/creator.py b/roverlay/overlay/creator.py
index 3a6e0ed..dd7c11e 100644
--- a/roverlay/overlay/creator.py
+++ b/roverlay/overlay/creator.py
@@ -214,15 +214,17 @@ class OverlayCreator ( object ):
def add_package_file ( self, package_file ):
"""Adds a single R package."""
+ raise Exception ( "to be removed" )
self._pkg_queue.put ( PackageInfo ( filepath=package_file ) )
self.package_added.inc()
- # --- end of add_package (...) ---
+ # --- end of add_package_file (...) ---
def add_package_files ( self, *package_files ):
"""Adds multiple R packages."""
+ raise Exception ( "to be removed" )
for p in package_files: self.add_package_file ( p )
self.package_added.inc()
- # --- end of add_packages (...) ---
+ # --- end of add_package_files (...) ---
def write_overlay ( self, incremental=False ):
"""Writes the overlay.
@@ -232,7 +234,10 @@ class OverlayCreator ( object ):
"""
if self.can_write_overlay:
start = time.time()
- self.overlay.write()
+ if incremental:
+ self.overlay.write_incremental()
+ else:
+ self.overlay.write()
self._timestamp ( "overlay written", start )
else:
self.logger.warning ( "Not allowed to write overlay!" )
diff --git a/roverlay/overlay/metadata/__init__.py b/roverlay/overlay/metadata/__init__.py
index e4938b5..58fc414 100644
--- a/roverlay/overlay/metadata/__init__.py
+++ b/roverlay/overlay/metadata/__init__.py
@@ -11,37 +11,53 @@ USE_FULL_DESCRIPTION = True
class MetadataJob ( object ):
"""R package description data -> metadata.xml interface."""
- def __init__ ( self, logger ):
+ def __init__ ( self, filepath, logger ):
"""Initializes a MetadataJob.
arguments:
- * logger -- parent logger to use
+ * filepath -- path where the metadata file will be written to
+ * logger -- parent logger to use
"""
- self.logger = logger.getChild ( 'metadata' )
- self._metadata = nodes.MetadataRoot()
- # reserved for future usage ("dominant ebuilds": when ebuildjobs
- # share one metadata instance etc.)
- self.package_info = None
- self.filename = 'metadata.xml'
+ self.logger = logger.getChild ( 'metadata' )
+ self._package_info = None
+ self.filepath = filepath
+ # no longer storing self._metadata, which will only be created twice
+ # when running show() (expected 1x write per PackageInfo instance)
# --- end of __init__ (...) ---
- def update ( self, package_info ):
- """Updates the metadata using the given description data.
+ def empty ( self ):
+ return self._package_info is None
+ # --- end of empty (...) ---
- It's expected that this method is called when Ebuild creation is done.
+ def update ( self, package_info ):
+ """Updates the metadata.
+ Actually, this won't create any metadata, it will only set the
+ PackageInfo object to be used for metadata creation.
arguments:
- * desc_data -- description data read from R package
- * package_info -- reserved for future usage
-
- returns: None (implicit)
+ * package_info --
"""
- data = package_info ['desc_data']
+ if package_info.has ( 'desc_data' ) and \
+ package_info.compare_version ( self._package_info ) > 0:
+ self._package_info = package_info
+ # --- end of update (...) ---
- mref = self._metadata
+ def update_using_iterable ( self, package_info_iter ):
+ for package_info in package_info_iter:
+ self.update ( package_info )
+ # --- end of update_using_iterable (...) ---
- max_textline_width = roverlay.config.get ( 'METADATA.linewidth', 65 )
+ def _create ( self ):
+ """Creates metadata (MetadataRoot) using the stored PackageInfo.
+
+ It's expected that this method is called when Ebuild creation is done.
+
+ returns: created metadata
+ """
+ mref = nodes.MetadataRoot()
+ data = self._package_info ['desc_data']
+ max_textline_width = roverlay.config.get ( 'METADATA.linewidth', 65 )
description = None
@@ -67,22 +83,38 @@ class MetadataJob ( object ):
#if package_info ['has_suggests']:
# mref.add_useflag ( 'R_suggests', 'install optional dependencies' )
+ return mref
# --- end of update (...) ---
- def write ( self, _file ):
+ def _write ( self, fh ):
"""Writes the metadata into a file.
arguments:
* _file -- file to write, either a file handle or string in which case
a file object will be created
- returns: True if writing succeeds, else False
+ returns: True if writing succeeds, else False
- raises: Exception if no metadata to write
- """
- if self._metadata.empty():
- raise Exception ( "not enough metadata to write!" )
- #return False
+ raises: Exception if no metadata to write
+ """
+ if self._create().write_file ( fh ):
+ return True
else:
- return self._metadata.write_file ( _file )
+ raise Exception ( "not enough metadata to write!" )
+ # --- end of _write (...) ---
+
+ show = _write
+
+ def write ( self ):
+ _success = False
+ try:
+ fh = open ( self.filepath, 'w' )
+ self._write ( fh )
+ _success = True
+ except any as e:
+ self.logger.exception ( e )
+ finally:
+ if 'fh' in locals() and fh: fh.close()
+
+ return _success
# --- end of write (...) ---
diff --git a/roverlay/overlay/metadata/nodes.py b/roverlay/overlay/metadata/nodes.py
index 6f27deb..02d5482 100644
--- a/roverlay/overlay/metadata/nodes.py
+++ b/roverlay/overlay/metadata/nodes.py
@@ -57,46 +57,24 @@ class MetadataRoot ( MetadataNodeNamedAccess ):
return use_node
# --- end of add_useflag (...) ---
- def write_file ( self, _file ):
+ def write_file ( self, fh ):
"""Writes the metadata to a file.
arguments:
- * _file -- either a File object or a string
+ * fh -- a File object
returns: success True/False
raises: *passes IOError
"""
- to_write = util.ascii_filter ( self.to_str() )
-
- own_fh = False
- fh = None
- success = False
-
- newline = '\n'
-
- try:
- if isinstance ( _file, str ):
- own_fh = True
- fh = open ( _file, 'w' )
- else:
- fh = _file
-
-
+ if not self.empty():
fh.write ( MetadataRoot.HEADER )
- fh.write ( newline )
- fh.write ( to_write )
- fh.write ( newline )
-
- success = True
-
- except IOError:
- # log this TODO
- pass
- finally:
- if own_fh and fh: fh.close()
-
- return success
+ fh.write ( '\n' )
+ fh.write ( util.ascii_filter ( self.to_str() ) )
+ fh.write ( '\n' )
+ return True
+ else:
+ return False
# --- end of write_file (...) ---
diff --git a/roverlay/overlay/package.py b/roverlay/overlay/package.py
index c0b4294..71b7ea9 100644
--- a/roverlay/overlay/package.py
+++ b/roverlay/overlay/package.py
@@ -1,20 +1,18 @@
-# R Overlay -- overlay module, package dir (subdir of category)
-# Copyright 2006-2012 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
+# replacement for package.py
-import threading
import os
import sys
+import threading
from roverlay import manifest
from roverlay.packageinfo import PackageInfo
from roverlay.overlay.metadata import MetadataJob
SUPPRESS_EXCEPTIONS = True
-EBUILD_SUFFIX = '.ebuild'
-class PackageDir ( object ):
+class PackageDir ( object ):
+ EBUILD_SUFFIX = '.ebuild'
def __init__ ( self, name, logger, directory ):
"""Initializes a PackageDir which contains ebuilds, metadata and
@@ -30,47 +28,131 @@ class PackageDir ( object ):
self._lock = threading.RLock()
# { <version> : <PackageInfo> }
self._packages = dict()
- self._metadata = None
self.physical_location = directory
- self._package_for_manifest = None
+ self._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
# used to track changes for this package dir
- self.modified = False
+ self.modified = False
+ self._manifest_package = None
+ self._need_manifest = False
+ self._need_metadata = False
# --- end of __init__ (...) ---
- def list_versions ( self ):
- return self._packages.keys()
- # --- end of list_versions (...) ---
+ def new_ebuild ( self ):
+ """Called when a new ebuild has been created for this PackageDir."""
+ self._need_manifest = True
+ self.modified = True
+ # --- end of new_ebuild (...) ---
- def has_manifest ( self ):
- return os.path.isfile (
- self.physical_location + os.sep + 'Manifest'
- )
- # --- end of has_manifest (...) ---
+ def add ( self, package_info, add_if_physical=False ):
+ """Adds a package to this PackageDir.
- def has_metadata ( self ):
- return os.path.isfile (
- self.physical_location + os.sep + 'metadata.xml'
- )
- # --- end of has_metadata (...) ---
+ arguments:
+ * package_info --
+ * add_if_physical -- add package even if it exists as ebuild file
+ (-> overwrite old ebuilds)
+
+ returns: success as bool
+
+ raises: Exception when ebuild already exists.
+ """
+ shortver = package_info ['ebuild_verstr']
+ _success = False
+ try:
+ self._lock.acquire()
+ if shortver in self._packages:
+ # package exists, check if it existed before script invocation
+ if self._packages [shortver] ['physical_only']:
+ if not skip_if_physical:
+ # ignore ebuilds that exist as file
+ self._packages [shortver] = package_info
+ _success = True
+ else:
+ self.logger.debug (
+ "'{PN}-{PVR}.ebuild' exists as file, skipping.".format (
+ PN=self.name, PVR=shortver
+ )
+ )
+ else:
+ # package has been added to this overlay before
+ self.logger.info (
+ "'{PN}-{PVR}.ebuild' already exists, cannot add it!".format (
+ PN=self.name, PVR=shortver
+ )
+ )
+ else:
+ self._packages [shortver] = package_info
+ _success = True
+
+ finally:
+ self._lock.release()
+
+ return _success
+ # --- end of add (...) ---
+
+ def empty ( self ):
+ """Returns True if no ebuilds stored, else False.
+ Note that "not empty" does not mean "have ebuilds to write".
+ """
+ return len ( self._packages ) == 0
+ # --- end of empty (...) ---
+
+ def finalize_write_incremental ( self ):
+ with self._lock:
+ if self._need_metadata:
+ self.write_metadata()
+ if self._need_manifest:
+ self.write_manifest()
+ # --- end of finalize_write_incremental (...) ---
+
+ def generate_metadata ( self, skip_if_existent, **ignored_kw ):
+ """Creates metadata for this package.
+
+ arguments:
+ * skip_if_existent -- do not create if metadata already exist
+ """
+ with self._lock:
+ if self._metadata.empty() or not skip_if_existent:
+ self._metadata.update_using_iterable ( self._packages.values() )
+ # --- end of generate_metadata (...) ---
- def get_ebuilds ( self ):
- for x in os.listdir ( self.physical_location ):
- if x.endswith ( EBUILD_SUFFIX ):
- yield self.physical_location + os.sep + x
- # --- end of get_ebuilds (...) ---
+ def list_versions ( self ):
+ return self._packages.keys()
+ # --- end of list_versions (...) ---
- def _scan_ebuilds ( self ):
- """Searches for ebuilds in self.physical_location."""
- elen = len ( EBUILD_SUFFIX )
+ def scan ( self, **kw ):
+ """Scans the filesystem location of this package for existing
+ ebuilds and adds them.
+ """
+ def scan_ebuilds():
+ """Searches for ebuilds in self.physical_location."""
+ elen = len ( self.__class__.EBUILD_SUFFIX )
+ def ebuild_split_pvr ( _file ):
+ if _file.endswith ( self.__class__.EBUILD_SUFFIX ):
+ return _file [ : - elen ].split ( '-', 1 )
+ else:
+ return ( None, None )
+ # --- end of is_ebuild (...) ---
- for f in os.listdir ( self.physical_location ):
- if f.endswith ( EBUILD_SUFFIX ):
+ # assuming that self.physical_location exists
+ # (should be verified by category.py:Category)
+ for f in os.listdir ( self.physical_location ):
try:
# filename without suffix ~= ${PF} := ${PN}-${PVR}
- pn, pvr = f [ : - elen ].split ( '-', 1 )
- if pn == self.name:
+ pn, pvr = ebuild_split_pvr ( f )
+ if pn is None:
+ # not an ebuild
+ pass
+ elif pn == self.name:
yield pvr
else:
# $PN does not match directory name, warn about that
@@ -78,298 +160,161 @@ class PackageDir ( object ):
"$PN does not match directory name, ignoring {!r}.".\
format ( f )
)
-
except:
self.logger.warning (
"ebuild {!r} has an invalid file name!".format ( f )
)
+ # --- end of scan_ebuilds (...) ---
- # --- end of _scan_ebuilds (...) ---
-
- def scan ( self, **kw ):
- """Scans the filesystem location of this package for existing
- ebuilds and adds them.
- """
- for pvr in self._scan_ebuilds():
+ for pvr in scan_ebuilds():
if pvr not in self._packages:
p = PackageInfo ( physical_only=True, pvr=pvr )
self._packages [ p ['ebuild_verstr'] ] = p
# --- end of scan (...) ---
- def empty ( self ):
- """Returns True if no ebuilds stored, else False."""
- return len ( self._packages ) == 0
- # --- end of empty (...) ---
-
- def _get_ebuild_filepath ( self, pvr ):
- """Returns the path to the ebuild file.
-
- arguments:
- * pvr -- version number with the revision (${PVR} in ebuilds)
- """
- return "{root}{sep}{PN}-{PVR}{EBUILD_SUFFIX}".format (
- root=self.physical_location, sep=os.sep,
- PN=self.name, PVR=pvr, EBUILD_SUFFIX=EBUILD_SUFFIX
- )
- # --- end of _get_ebuild_filepath (...) ---
-
- def write_incremental ( self, default_header ):
- self.write_ebuilds ( header=default_header, overwrite=False )
- # --- end of write_incremental (...) ---
-
- def write_metadata ( self, shared_fh=None ):
- """Writes metadata for this package."""
- try:
-
- self._regen_metadata()
-
- if shared_fh is None:
- fh = open (
- self.physical_location + os.sep + self._metadata.filename, 'w'
- )
- else:
- fh = shared_fh
-
- self._metadata.write ( fh )
-
- except IOError as e:
-
- self.logger.error (
- "Failed to write metadata file {}.".format ( mfile )
- )
- self.logger.exception ( e )
-
- finally:
- if shared_fh is None and 'fh' in locals() and fh:
- fh.close()
- # --- end of write_metadata (...) ---
-
- def write_ebuild ( self, efile, ebuild, header, shared_fh=None ):
- """Writes an ebuild.
+ def show ( self, stream=sys.stderr, default_header=None ):
+ """Prints this dir (the ebuilds and the metadata) into a stream.
arguments:
- * efile -- file to write
- * ebuild -- ebuild object to write (has to have a __str__ method)
- * header -- ebuild header to write (^)
- * shared_fh -- optional, see write_ebuilds()
- """
- _success = False
- try:
- fh = open ( efile, 'w' ) if shared_fh is None else shared_fh
- if header is not None:
- fh.write ( str ( header ) )
- fh.write ( '\n\n' )
- fh.write ( str ( ebuild ) )
- fh.write ( '\n' )
-
- # adjust owner/perm? TODO
- #if shared_fh is None:
- # chmod 0644 or 0444
- # chown 250.250
- _success = True
- except IOError as e:
- self.logger.exception ( e )
- finally:
- if shared_fh is None and 'fh' in locals() and fh:
- fh.close()
-
- return _success
- # --- end of write_ebuild (...) ---
+ * stream -- stream to use, defaults to sys.stderr
- def write_ebuilds ( self, header, shared_fh=None, overwrite=True ):
- """Writes all ebuilds.
+ returns: None (implicit)
- arguments:
- * header -- ebuild header
- * shared_fh -- if set and not None: don't use own file handles (i.e.
- write files), write everything into shared_fh
+ raises:
+ * IOError
"""
- for ver, p_info in self._packages.items():
- if not p_info ['physical_only'] and p_info ['ebuild']:
- efile = self._get_ebuild_filepath ( ver )
-
- if not overwrite and efile == p_info ['ebuild_file']:
- print ( efile + " exists, skipping write()." )
-
-
- elif self.write_ebuild (
- efile, p_info ['ebuild'], header, shared_fh
- ):
- if shared_fh is None:
- # this marks the package as 'written to fs'
- p_info.update_now (
- ebuild_file=efile,
- remove_auto='ebuild_written'
- )
-
- self._package_for_manifest = p_info
-
- self.logger.info ( "Wrote ebuild {}.".format ( efile ) )
- else:
- self.logger.error (
- "Couldn't write ebuild {}.".format ( efile )
- )
- # --- end of write_ebuilds (...) ---
+ return self.write ( default_header=default_header, shared_fh=stream )
+ # --- end of show (...) ---
def write ( self,
- default_header=None, write_manifest=True, shared_fh=None
+ default_header=None, shared_fh=None,
+ write_ebuilds=True, write_manifest=True, write_metadata=True,
+ overwrite_ebuilds=True
):
"""Writes this directory to its (existent!) filesystem location.
arguments:
* default_header -- ebuild header to write
- * write_manifest -- if set and False: don't write the Manifest file
+ * shared_fh -- if set and not None: write everyting into <fh>
+ * write_ebuilds -- if set and False: don't write ebuilds
+ * write_manifest -- if set and False: don't write the Manifest file
+ * write_metadata -- if set and False: don't write the metadata file
+ * overwrite_ebuilds -- if set and False: don't overwrite ebuilds
returns: None (implicit)
raises:
- * IOError
+ * IOError (?)
"""
- self._lock.acquire()
- try:
+ with self._lock:
# mkdir not required here, overlay.Category does this
# write ebuilds
- self.write_ebuilds ( header=default_header, shared_fh=shared_fh )
+ if write_ebuilds:
+ self.write_ebuilds (
+ default_header=default_header, shared_fh=shared_fh,
+ overwrite=overwrite_ebuilds
+ )
# write metadata
- self.write_metadata ( shared_fh=shared_fh )
+ if write_metadata:
+ self.write_metadata ( shared_fh=shared_fh )
- if write_manifest and shared_fh is not None:
+ # write manifest (only if shared_fh is None)
+ if write_manifest and shared_fh is None:
self.write_manifest()
-
- finally:
- self._lock.release()
# --- end of write (...) ---
- def show ( self, stream=sys.stderr, default_header=None ):
- """Prints this dir (the ebuilds and the metadata) into a stream.
-
- arguments:
- * stream -- stream to use, defaults to sys.stderr
-
- returns: None (implicit)
-
- raises:
- * IOError
- """
- self.write (
- default_header=default_header, shared_fh=stream, write_manifest=False
- )
- # --- end of show (...) ---
-
- def _latest_package ( self, pkg_filter=None, use_lock=False ):
- """Returns the package info with the highest version number.
-
- arguments:
- * pkg_filter -- either None or a callable,
- None: do not filter packages
- else: ignore package if it does not pass the filter
- * use_lock -- if True: hold lock while searching
- """
- first = True
- retver = None
- retpkg = None
-
- if use_lock: self._lock.acquire()
- try:
- for p in self._packages.values():
- if pkg_filter is None or pkg_filter ( p ):
- newver = p ['version']
- if first or newver > retver:
- retver = newver
- retpkg = p
- first = False
- finally:
- if use_lock: self._lock.release()
- return retpkg
- # --- end of _latest_package (...) ---
-
- def add ( self, package_info ):
- """Adds a package to this PackageDir.
+ def write_ebuilds ( self, default_header, overwrite, shared_fh=None ):
+ """Writes all ebuilds.
arguments:
- * package_info --
-
- returns: success as bool
-
- raises: Exception when ebuild already exists.
+ * default_header -- ebuild header
+ * shared_fh -- if set and not None: don't use own file handles
+ (i.e. write files), write everything into shared_fh
+ * overwrite -- write ebuilds that have been written before,
+ defaults to True
"""
- shortver = package_info ['ebuild_verstr']
-
- def already_exists ():
- if shortver in self._packages:
- self.logger.info (
- "'{PN}-{PVR}.ebuild' already exists, cannot add it!".format (
- PN=self.name, PVR=shortver
- )
- )
- return True
- else:
- return False
- # --- end of already_exists (...) ---
-
- _success = False
-
- if not already_exists():
+ def write_ebuild ( efile, ebuild ):
+ """Writes an ebuild.
+
+ arguments:
+ * efile -- file to write
+ * ebuild -- ebuild object to write (has to have a __str__ method)
+ * (default_header from write_ebuilds())
+ * (shared_fh from write_ebuilds())
+ """
+ _success = False
try:
- self._lock.acquire()
- if not already_exists():
- self._packages [shortver] = package_info
- self.modified = True
- _success = True
+ fh = open ( efile, 'w' ) if shared_fh is None else shared_fh
+ if default_header is not None:
+ fh.write ( str ( default_header ) )
+ fh.write ( '\n\n' )
+ fh.write ( str ( ebuild ) )
+ fh.write ( '\n' )
+
+ # adjust owner/perm? TODO
+ #if shared_fh is None:
+ # chmod 0644 or 0444
+ # chown 250.250
+ _success = True
+ except IOError as e:
+ self.logger.exception ( e )
finally:
- self._lock.release()
+ if shared_fh is None and 'fh' in locals() and fh:
+ fh.close()
- return _success
- # --- end of add (...) ---
+ return _success
+ # --- end of write_ebuild (...) ---
- def _regen_metadata ( self ):
- """Regenerates the metadata."""
- self.generate_metadata (
- skip_if_existent=True,
- use_all_packages=False,
- use_old_metadata=False
- )
- # --- end of _regen_metadata (...) ---
+ def ebuilds_to_write():
+ """Yields all ebuilds that are ready to be written."""
- def generate_metadata (
- self,
- skip_if_existent=False, use_all_packages=False, use_old_metadata=False
- ):
- """Creates metadata for this package.
+ for ver, p_info in self._packages.items():
+ if p_info.has ( 'ebuild' ) and not p_info ['physical_only']:
+ efile = self.ebuild_filepath_format.format ( PVR=ver )
- arguments:
- * skip_if_existent -- do not create if metadata already exist
- * use_all_packages -- TODO in metadata
- * use_old_metadata -- TODO in metadata
- """
- if use_old_metadata or use_all_packages:
- raise Exception ( "using >1 package for metadata.xml is TODO!" )
+ if efile != p_info ['ebuild_file'] or overwrite:
+ yield ( efile, p_info )
+ # else efile exists
+ # --- end of ebuilds_to_write (...) ---
- if skip_if_existent and not self._metadata is None: return
+ all_ebuilds_written = True
- self._lock.acquire()
- try:
+ for efile, p_info in ebuilds_to_write():
+ if write_ebuild ( efile, p_info ['ebuild'] ):
+ self._need_manifest = True
+
+ # update metadata for each successfully written ebuild
+ # (self._metadata knows how to handle this request)
+ self._metadata.update ( p_info )
- if self._metadata is None or not use_old_metadata:
- del self._metadata
- self._metadata = MetadataJob ( self.logger )
+ if shared_fh is None:
+ # this marks the package as 'written to fs'
+ p_info.update_now (
+ ebuild_file=efile,
+ remove_auto='ebuild_written'
+ )
- if use_all_packages:
- for p_info in self._packages:
- self._metadata.update ( p_info )
+ self.logger.info ( "Wrote ebuild {}.".format ( efile ) )
else:
- self._metadata.update ( self._latest_package() )
+ all_ebuilds_written = False
+ self.logger.error (
+ "Couldn't write ebuild {}.".format ( efile )
+ )
- finally:
- self._lock.release()
- # --- end of generate_metadata (...) ---
+ self.modified = not all_ebuilds_written
+ # --- end of write_ebuilds (...) ---
+
+ def write_incremental ( self, default_header ):
+ with self._lock:
+ self.write_ebuilds ( default_header=default_header, overwrite=False )
+ # --- end of write_incremental (...) ---
def write_manifest ( self ):
"""Generates and writes the Manifest file for this package.
- expects: called in self.write(), after writing metadata/ebuilds
+ expects: called after writing metadata/ebuilds
returns: None (implicit)
@@ -378,27 +323,47 @@ class PackageDir ( object ):
"""
# it should be sufficient to call create_manifest for one ebuild,
- # choosing the latest one here that exists in self.physical_location.
+ # choosing the latest one that exists in self.physical_location and
+ # has enough data (DISTDIR, EBUILD_FILE) for this task.
#
# metadata.xml's full path cannot be used for manifest creation here
# 'cause DISTDIR would be unknown
#
-# pkg_info_for_manifest = self._latest_package (
-# pkg_filter=lambda pkg : pkg ['ebuild_file'] is not None,
-# use_lock=True
-# )
- if self._package_for_manifest is None:
- # ? FIXME
+ if self._manifest_package is not None:
+ manifest.create_manifest ( self._manifest_package, nofail=False )
+ self._need_manifest = False
+ else:
raise Exception (
"No ebuild written so far! I really don't know what do to!"
)
- else:
- # TODO: manifest creation interface is single threaded,
- # may want to 'fix' this later
- manifest.create_manifest (
- self._package_for_manifest, nofail=False,
- #ebuild_file=...
+ # --- end of write_manifest (...) ---
+
+ def write_metadata ( self, shared_fh=None ):
+ """Writes metadata for this package."""
+ if self._manifest_package is None and not shared_fh:
+ self.logger.error (
+ 'write_metadata() requested, but no ebuild written so far! '
+ 'This will most likely result in a corrupt Manifest.'
)
- # --- end of write_manifest (...) ---
+ try:
+ self.generate_metadata ( skip_if_existent=True )
+
+ if self._metadata.write() \
+ if shared_fh is None else self._metadata.show ( shared_fh ) \
+ :
+ self._need_metadata = False
+ self._need_manifest = True
+ return True
+ else:
+ self.logger.error (
+ "Failed to write metadata file {}.".format (
+ self._metadata.filepath
+ )
+ )
+ return False
+ except:
+ # already logged
+ return False
+ # --- end of write_metadata (...) ---
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index 26be02a..e0446df 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -74,6 +74,8 @@ class Overlay ( object ):
self.default_category = default_category
self.eclass_files = eclass_files
+ self.ignore_existing_ebuilds = False
+
self._profiles_dir = self.physical_location + os.sep + 'profiles'
self._catlock = threading.Lock()
self._categories = dict()
@@ -143,7 +145,7 @@ class Overlay ( object ):
return self._categories [category]
# --- end of _get_category (...) ---
- def add ( self, package_info, write_after_add=False, category=None ):
+ def add ( self, package_info, category=None ):
"""Adds a package to this overlay.
arguments:
@@ -158,12 +160,9 @@ class Overlay ( object ):
)
if write_after_add:
- util.dodir ( cat.physical_location, mkdir_p=True )
- return cat.add (
- package_info, write_after_add=True, header = self._get_header()
- )
- else:
- return cat.add ( package_info, write_after_add=False )
+ raise Exception ( "add~write_after_add: to be removed." )
+
+ return cat.add ( package_info, write_after_add=False )
# --- end of add (...) ---
def show ( self, **show_kw ):
@@ -228,6 +227,16 @@ class Overlay ( object ):
self._incremental_write_lock.release()
# --- end of write_incremental (...) ---
+ def finalize_write_incremental ( self ):
+ """Writes metadata + Manifest for all packages."""
+ self._init_overlay ( reimport_eclass=True, make_profiles_dir=True )
+
+ for cat in self._categories.values():
+ cat.finalize_write_incremental()
+
+ self._write_categories ( only_active=True )
+ # --- end of finalize_incremental (...) ---
+
def generate_metadata ( self, **metadata_kw ):
"""Tells the overlay's categories to create metadata.
You don't have to call this before write()/show() unless you want to use
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/metadata/, roverlay/overlay/
2012-07-23 16:34 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
@ 2012-07-30 8:52 ` André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2012-07-30 8:52 UTC (permalink / raw
To: gentoo-commits
commit: b60d7f137f1f99f4b4afe85d1f82ace045d6b211
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 23 16:31:50 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 23 16:31:50 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b60d7f13
incremental overlay writing: keep n ebuilds
Added keep_nth_latest(n) which keeps the n-th latest ebuilds
of a PackageDir and removes all others.
Also added fs_cleanup() that removes "empty" (no ebuilds) package dirs from
the filesystem.
geändert: roverlay/overlay/category.py
geändert: roverlay/overlay/creator.py
geändert: roverlay/overlay/metadata/abstractnodes.py
geändert: roverlay/overlay/metadata/nodes.py
geändert: roverlay/overlay/package.py
geändert: roverlay/overlay/root.py
---
roverlay/overlay/category.py | 7 +
roverlay/overlay/creator.py | 1 +
roverlay/overlay/metadata/abstractnodes.py | 2 +-
roverlay/overlay/metadata/nodes.py | 3 +-
roverlay/overlay/package.py | 153 +++++++++-
roverlay/overlay/root.py | 428 +++++++++++++---------------
6 files changed, 352 insertions(+), 242 deletions(-)
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index 1d0bf97..33149c4 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -104,6 +104,13 @@ class Category ( object ):
return os.path.isdir ( self.physical_location + os.sep + _dir )
# --- end of has_category (...) ---
+ def keep_nth_latest ( self, *args, **kwargs ):
+ """See package.py:PackageDir:keep_nth_latest."""
+ for subdir in self._subdirs.values():
+ subdir.keep_nth_latest ( *args, **kwargs )
+ subdir.fs_cleanup()
+ # --- end of keep_nth_latest (...) ---
+
def list_packages ( self, for_deprules=False ):
"""Lists all packages in this category.
Yields <category>/<package name> or a dict (see for_deprules below).
diff --git a/roverlay/overlay/creator.py b/roverlay/overlay/creator.py
index 114f12d..9de063c 100644
--- a/roverlay/overlay/creator.py
+++ b/roverlay/overlay/creator.py
@@ -304,6 +304,7 @@ class OverlayCreator ( object ):
self._close_workers()
close_resolver()
+ self.overlay.keep_nth_latest ( n=1 )
self.closed = True
# --- end of close (...) ---
diff --git a/roverlay/overlay/metadata/abstractnodes.py b/roverlay/overlay/metadata/abstractnodes.py
index a344fc1..284ea20 100644
--- a/roverlay/overlay/metadata/abstractnodes.py
+++ b/roverlay/overlay/metadata/abstractnodes.py
@@ -242,7 +242,7 @@ class MetadataLeaf ( _MetadataBasicNode ):
self._do_verify()
if self.print_node_name:
return "{indent}<{name}{flags}>{value}</{name}>".format (
- indent=self._indent,
+ indent=self.indent,
name=self.name,
flags=self._flagstr(),
value=self._value_str(),
diff --git a/roverlay/overlay/metadata/nodes.py b/roverlay/overlay/metadata/nodes.py
index 02d5482..0002267 100644
--- a/roverlay/overlay/metadata/nodes.py
+++ b/roverlay/overlay/metadata/nodes.py
@@ -22,7 +22,8 @@ class MetadataRoot ( MetadataNodeNamedAccess ):
def __init__ ( self ):
super ( MetadataRoot, self ) . __init__ ( 'pkgmetadata' )
- self.priority = 0
+ self.priority = 0
+ self.allow_empty = True
# --- end of __init__ (...) ---
def empty ( self ):
diff --git a/roverlay/overlay/package.py b/roverlay/overlay/package.py
index 2ea4cb2..a2e4d9b 100644
--- a/roverlay/overlay/package.py
+++ b/roverlay/overlay/package.py
@@ -1,14 +1,15 @@
import os
import sys
import threading
+import shutil
+from roverlay import util
from roverlay.overlay import manifest
from roverlay.packageinfo import PackageInfo
from roverlay.overlay.metadata import MetadataJob
SUPPRESS_EXCEPTIONS = True
-
class PackageDir ( object ):
EBUILD_SUFFIX = '.ebuild'
@@ -48,6 +49,22 @@ class PackageDir ( object ):
self._need_metadata = False
# --- end of __init__ (...) ---
+ def _remove_ebuild_file ( self, pkg_info ):
+ """Removes the ebuild file of a pkg_info object.
+ Returns True on success, else False.
+ """
+ try:
+ efile = pkg_info ['ebuild_file']
+ if efile is not None:
+ os.unlink ( efile )
+ # Manifest file has to be updated
+ self._need_manifest = True
+ return True
+ except Exception as e:
+ self.logger.exception ( e )
+ return False
+ # --- end of remove_ebuild_file (...) ---
+
def add ( self, package_info, add_if_physical=False ):
"""Adds a package to this PackageDir.
@@ -105,19 +122,51 @@ class PackageDir ( object ):
def empty ( self ):
"""Returns True if no ebuilds stored, else False.
- Note that "not empty" does not mean "have ebuilds to write".
+ Note that "not empty" doesn't mean "has ebuilds to write" or "has
+ ebuilds written", use the modified attribute for the former, and the
+ has_ebuilds() function for the latter one.
"""
return len ( self._packages ) == 0
# --- end of empty (...) ---
def finalize_write_incremental ( self ):
+ """Method that finalizes incremental writing, i.e. write outstanding
+ ebuilds and write metadata.xml, Manifest.
+ """
with self._lock:
- if self._need_metadata:
- self.write_metadata()
- if self._need_manifest:
- self.write_manifest()
+ if self.has_ebuilds():
+ if self.modified:
+ self.write_ebuilds ( overwrite=False )
+ if self._need_metadata:
+ self.write_metadata()
+ if self._need_manifest:
+ self.write_manifest()
+ else:
+ self.logger.critical (
+ "<<todo>>: please clean up this dir: {}.".format (
+ self.physical_location
+ ) )
# --- end of finalize_write_incremental (...) ---
+ def fs_cleanup ( self ):
+ """Cleans up the filesystem location of this package dir.
+ To be called after keep_nth_latest, calls finalize_write_incremental().
+ """
+ def rmtree_error ( function, path, excinfo ):
+ """rmtree onerror function that simply logs the exception"""
+ self.logger.exception ( excinfo )
+ # --- end of rmtree_error (...) ---
+
+ with self._lock:
+ if self.has_ebuilds():
+ # !!! FIXME this doesn't work if no ebuilds written, but
+ # old ones removed -> DISTDIR unknown during Manifest creation
+ self.finalize_write_incremental()
+ elif os.path.isdir ( self.physical_location ):
+ # destroy self.physical_location
+ shutil.rmtree ( self.physical_location, onerror=rmtree_error )
+ # --- end of fs_cleanup (...) ---
+
def generate_metadata ( self, skip_if_existent, **ignored_kw ):
"""Creates metadata for this package.
@@ -129,6 +178,70 @@ class PackageDir ( object ):
self._metadata.update_using_iterable ( self._packages.values() )
# --- end of generate_metadata (...) ---
+ 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' ):
+ return True
+ return False
+ # --- end of has_ebuilds (...) ---
+
+ def keep_nth_latest ( self, n, cautious=True ):
+ """Keeps the n-th latest ebuild files, removing all other packages,
+ physically (filesystem) as well as from this PackageDir object.
+
+ arguments:
+ * n -- # of packages/ebuilds to keep
+ * cautious -- if True: be extra careful, verify that ebuilds exist
+ """
+
+ # create the list of packages to iterate over,
+ # * package has to have an ebuild_file
+ # * sort them by version in reverse order (latest package gets index 0)
+ packages = reversed ( sorted (
+ filter (
+ lambda p : p [1] ['ebuild_file'] is not None,
+ self._packages.items()
+ ),
+ key=lambda p : p [1] ['version']
+ ) )
+
+ kept = 0
+ ecount = 0
+ if not cautious:
+ # could use a slice here, too
+ for pvr, pkg in packages:
+ ecount += 1
+ if kept < n:
+ printself.logger.debug ( "Keeping {pvr}.".format ( pvr=pvr ) )
+ kept += 1
+ else:
+ self.logger.debug ( "Removing {pvr}.".format ( pvr=pvr ) )
+ self.purge_package ( pvr )
+ else:
+ for pvr, pkg in packages:
+ ecount += 1
+ if os.path.isfile ( pkg ['ebuild_file'] ):
+ if kept < n:
+ self.logger.debug ( "Keeping {pvr}.".format ( pvr=pvr ) )
+ kept += 1
+ else:
+ self.logger.debug ( "Removing {pvr}.".format ( pvr=pvr ) )
+ self.purge_package ( pvr )
+ else:
+ self.logger.error (
+ "{efile} is assumed to exist as file but doesn't!".format (
+ efile=pkg ['ebuild_file']
+ ) )
+
+ # FIXME/IGNORE: this doesn't count inexistent files as kept
+ self.logger.debug (
+ "Kept {kept}/{total} ebuilds.".format ( kept=kept, total=ecount )
+ )
+
+ # FIXME: Manifest is now invalid and dir could be "empty" (no ebuilds)
+ # --- end of keep_nth_latest (...) ---
+
def list_versions ( self ):
return self._packages.keys()
# --- end of list_versions (...) ---
@@ -144,6 +257,21 @@ class PackageDir ( object ):
return True
# --- end of new_ebuild (...) ---
+ def purge_package ( self, pvr ):
+ """Removes the PackageInfo with key pvr entirely from this PackageDir,
+ including its ebuild file.
+ Returns: removed PackageInfo object or None.
+ """
+ try:
+ p = self._packages [pvr]
+ del self._packages [pvr]
+ self._remove_ebuild_file ( p )
+ return p
+ except Exception as e:
+ self.logger.exception ( e )
+ return None
+ # --- end of purge_package (...) ---
+
def scan ( self, **kw ):
"""Scans the filesystem location of this package for existing
ebuilds and adds them.
@@ -168,7 +296,7 @@ class PackageDir ( object ):
# not an ebuild
pass
elif pn == self.name:
- yield pvr
+ yield ( pvr, self.physical_location + os.sep + f )
else:
# $PN does not match directory name, warn about that
self.logger.warning (
@@ -183,9 +311,11 @@ class PackageDir ( object ):
# ignore directories without a Manifest file
if os.path.isfile ( self.physical_location + os.sep + 'Manifest' ):
- for pvr in scan_ebuilds():
+ for pvr, efile in scan_ebuilds():
if pvr not in self._packages:
- p = PackageInfo ( physical_only=True, pvr=pvr )
+ p = PackageInfo (
+ physical_only=True, pvr=pvr, ebuild_file=efile
+ )
self._packages [ p ['ebuild_verstr'] ] = p
# --- end of scan (...) ---
@@ -260,6 +390,7 @@ class PackageDir ( object ):
"""
_success = False
try:
+ util.dodir ( self.physical_location )
fh = open ( efile, 'w' ) if shared_fh is None else shared_fh
if ebuild_header is not None:
fh.write ( str ( ebuild_header ) )
@@ -380,7 +511,7 @@ class PackageDir ( object ):
else:
self._metadata.show ( shared_fh )
return True
- except:
- # already logged
+ except Exception as e:
+ self.logger.exception ( e )
return False
# --- end of write_metadata (...) ---
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index 51239e2..363bdb5 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -27,11 +27,6 @@ class Overlay ( object ):
ebuild_header,
incremental
):
- if directory is None:
- raise Exception (
- "support for overlays without filesystem location has been dropped"
- )
-
self.name = name
self.logger = logger.getChild ( 'overlay' )
self.physical_location = directory
@@ -47,7 +42,7 @@ class Overlay ( object ):
# fixme or ignore: calculating eclass names twice,
# once here and another time when calling _init_overlay
- self._header.set_eclasses ( set (
+ self._header.set_eclasses ( frozenset (
self._get_eclass_import_info ( only_eclass_names=True )
) )
@@ -56,44 +51,10 @@ class Overlay ( object ):
self._incremental_write_lock = threading.Lock()
self.scan()
- self._init_overlay ( reimport_eclass=True, make_profiles_dir=True )
+ self._init_overlay ( reimport_eclass=True )
# --- end of __init__ (...) ---
- def scan ( self, **kw ):
- if os.path.isdir ( self.physical_location ):
- for cat in self._scan_categories():
- try:
- cat.scan ( **kw )
- except Exception as e:
- self.logger.exception ( e )
-# for package in sorted ( self.list_packages() ):
-# print ( package )
- # --- end of scan (...) ---
-
- def list_packages ( self, for_deprules=True ):
- for cat in self._categories.values():
- for package in cat.list_packages ( for_deprules=True ):
- yield package
- # --- end of list_packages (...) ---
-
- def list_rule_kwargs ( self ):
- for cat in self._categories.values():
- for kwargs in cat.list_packages ( for_deprules=True ):
- yield kwargs
- # --- end of list_rule_kwargs (...) ---
-
- def has_dir ( self, _dir ):
- return os.path.isdir ( self.physical_location + os.sep + _dir )
- # --- end of has_category (...) ---
-
- def _scan_categories ( self ):
- for x in os.listdir ( self.physical_location ):
- # FIXME could use a better check here
- if '-' in x and self.has_dir ( x ):
- yield self._get_category ( x )
- # --- end of _scan_categories (...) ---
-
def _get_category ( self, category ):
"""Returns a reference to the given category. Creates it if necessary.
@@ -120,191 +81,6 @@ class Overlay ( object ):
return self._categories [category]
# --- end of _get_category (...) ---
- def add ( self, package_info, category=None ):
- """Adds a package to this overlay.
-
- arguments:
- * package_info -- PackageInfo of the package to add
- * category -- category where the pkg should be put in, defaults to
- self.default_category
-
- returns: True if successfully added else False
- """
- cat = self._get_category (
- self.default_category if category is None else category
- )
- return cat.add ( package_info )
- # --- end of add (...) ---
-
- def show ( self, **show_kw ):
- """Presents the ebuilds/metadata stored in this overlay.
-
- arguments:
- * **show_kw -- keywords for package.PackageDir.show(...)
-
- returns: None (implicit)
- """
- if not self._header.eclasses: self._header.set_eclasses (
- tuple ( self._get_eclass_import_info ( only_eclass_names=True ) )
- )
- for cat in self._categories.values():
- cat.show ( **show_kw )
- # --- end of show (...) ---
-
- def write ( self, **write_kw ):
- """Writes the overlay to its physical location (filesystem), including
- metadata and Manifest files.
-
- arguments:
- * **write_kw -- keywords for package.PackageDir.write(...)
-
- returns: None (implicit)
-
- raises: IOError
-
- ! TODO/FIXME/DOC: This is not thread-safe, it's expected to be called
- when ebuild creation is done.
- """
- raise Exception ( "^,^" )
- # writing profiles/ here, rewriting categories/ later
- self._init_overlay ( reimport_eclass=True, make_profiles_dir=True )
-
- for cat in self._categories.values():
- if not cat.empty():
- util.dodir ( cat.physical_location )
- cat.write ( **write_kw )
-
- self._write_categories ( only_active=True )
- # --- end of write (...) ---
-
- def write_incremental ( self, **write_kw ):
- """Writes all ebuilds that have been added since the last
- write_incremental call.
- TODO:
- * This could be useful to save some mem by removing already written
- package infos.
- * This has to be thread safe
- """
- if not self._incremental_write_lock.acquire():
- # another incremental write is running, drop this request
- return
-
- try:
- util.dodir ( self.physical_location )
- cats = tuple ( self._categories.values() )
- for cat in cats:
- util.dodir ( cat.physical_location )
- cat.write_incremental ( **write_kw )
- finally:
- self._incremental_write_lock.release()
- # --- end of write_incremental (...) ---
-
- def finalize_write_incremental ( self ):
- """Writes metadata + Manifest for all packages."""
- self._write_categories ( only_active=True )
- for cat in self._categories.values():
- cat.finalize_write_incremental()
- # --- end of finalize_incremental (...) ---
-
- def generate_metadata ( self, **metadata_kw ):
- """Tells the overlay's categories to create metadata.
- You don't have to call this before write()/show() unless you want to use
- special metadata options.
-
- arguments:
- * **metadata_kw -- keywords for package.PackageDir.generate_metadata(...)
-
- returns: None (implicit)
- """
- for cat in self._categories.values():
- cat.generate_metadata ( **metadata_kw )
- # --- end of generate_metadata (...) ---
-
- def generate_manifest ( self, **manifest_kw ):
- """Generates Manifest files for all ebuilds in this overlay that exist
- physically/in filesystem.
- Manifest files are automatically created when calling write().
-
- arguments:
- * **manifest_kw -- see PackageDir.generate_manifest(...)
-
- returns: None (implicit)
- """
- for cat in self._categories.values():
- cat.generate_manifest ( **manifest_kw )
- # --- end of generate_manifest (...) ---
-
- def _write_profiles_dir ( self, only_active_categories=True ):
- """Creates and updates the profiles/ dir.
-
- arguments:
- * only_active_categories -- if True: do not list categories without
- ebuilds in profiles/categories
- """
- # profiles/
- util.dodir ( self._profiles_dir )
- self._write_repo_name()
- self._write_categories ( only_active=only_active_categories )
- self._write_usedesc()
- # --- end of _write_profiles_dir (...) ---
-
- def _write_profiles_file ( self, filename, to_write ):
- """Writes a file in profiles/.
-
- arguments:
- * filename -- name of the file to write (including file extension)
- * to_write -- string to write (don't forget newline at the end)
- """
- fh = None
- try:
- fh = open ( self._profiles_dir + os.sep + filename, 'w' )
- if to_write:
- # else touch file
- fh.write ( to_write )
- except IOError as e:
- self.logger.exception ( e )
- raise
- finally:
- if fh: fh.close()
- # --- end of _write_profiles_file (...) ---
-
- def _write_repo_name ( self ):
- """Writes profiles/repo_name."""
- self._write_profiles_file ( 'repo_name', self.name + '\n' )
- # --- end of _write_repo_name (...) ---
-
- def _write_categories ( self, only_active=True ):
- """Writes profiles/categories.
-
- arguments:
- * only_active -- exclude categories without ebuilds
- """
- cats = None
- if only_active:
- cats = [
- name for name, category
- in self._categories.items() if not category.empty()
- ]
- else:
- cats = list ( self._categories.keys() )
-
- if cats:
- self._write_profiles_file (
- 'categories',
- '\n'.join ( cats ) + '\n'
- )
- # --- end of _write_categories (...) ---
-
- def _write_usedesc ( self ):
- """Writes profiles/use.desc."""
- use_desc = config.get (
- 'OVERLAY.use_desc',
- fallback_value=DEFAULT_USE_DESC
- )
- if use_desc:
- self._write_profiles_file ( 'use.desc', use_desc + '\n' )
- # --- end of _write_usedesc (...) ---
-
def _get_eclass_import_info ( self, only_eclass_names=False ):
"""Yields eclass import information (eclass names and files).
@@ -363,7 +139,7 @@ class Overlay ( object ):
raise
# --- end of _import_eclass (...) ---
- def _init_overlay ( self, reimport_eclass, make_profiles_dir ):
+ def _init_overlay ( self, reimport_eclass ):
"""Initializes the overlay at its physical/filesystem location.
arguments:
@@ -374,14 +150,58 @@ class Overlay ( object ):
raises:
* IOError
"""
+ def write_profiles_dir():
+ """Creates and updates the profiles/ dir."""
+ def write_profiles_file ( filename, to_write ):
+ """Writes a file in profiles/.
+
+ arguments:
+ * filename -- name of the file to write (including file extension)
+ * to_write -- string to write (don't forget newline at the end)
+ """
+ fh = None
+ try:
+ fh = open ( self._profiles_dir + os.sep + filename, 'w' )
+ if to_write:
+ # else touch file
+ fh.write ( to_write )
+ except IOError as e:
+ self.logger.exception ( e )
+ raise
+ finally:
+ if fh: fh.close()
+ # --- end of write_profiles_file (...) ---
+
+ # always use the default category (+write it into profiles/categories)
+ self._get_category ( self.default_category )
+
+ # profiles/
+ util.dodir ( self._profiles_dir )
+
+ # profiless/repo_name
+ write_profiles_file ( 'repo_name', self.name + '\n' )
+
+ # profiles/categories
+ cats = '\n'.join ( self._categories.keys() )
+ if cats:
+ write_profiles_file ( 'categories', cats + '\n' )
+
+ # profiles/use.desc
+ use_desc = config.get (
+ 'OVERLAY.use_desc',
+ fallback_value=DEFAULT_USE_DESC
+ )
+ if use_desc:
+ write_profiles_file ( 'use.desc', use_desc + '\n' )
+ # --- end of write_profiles_dir (...) ---
+
try:
# mkdir overlay root
util.dodir ( self.physical_location, mkdir_p=True )
self._import_eclass ( reimport_eclass )
- if make_profiles_dir:
- self._write_profiles_dir ( only_active_categories=False )
+ write_profiles_dir()
except IOError as e:
@@ -389,3 +209,153 @@ class Overlay ( object ):
self.logger.critical ( "^failed to init overlay" )
raise
# --- end of _init_overlay (...) ---
+
+ def add ( self, package_info, category=None ):
+ """Adds a package to this overlay.
+
+ arguments:
+ * package_info -- PackageInfo of the package to add
+ * category -- category where the pkg should be put in, defaults to
+ self.default_category
+
+ returns: True if successfully added else False
+ """
+ cat = self._get_category (
+ self.default_category if category is None else category
+ )
+ return cat.add ( package_info )
+ # --- end of add (...) ---
+
+ def finalize_write_incremental ( self ):
+ """Writes metadata + Manifest for all packages."""
+ for cat in self._categories.values():
+ cat.finalize_write_incremental()
+ # --- end of finalize_incremental (...) ---
+
+ def generate_manifest ( self, **manifest_kw ):
+ """Generates Manifest files for all ebuilds in this overlay that exist
+ physically/in filesystem.
+ Manifest files are automatically created when calling write().
+
+ arguments:
+ * **manifest_kw -- see PackageDir.generate_manifest(...)
+
+ returns: None (implicit)
+ """
+ for cat in self._categories.values():
+ cat.generate_manifest ( **manifest_kw )
+ # --- end of generate_manifest (...) ---
+
+ def generate_metadata ( self, **metadata_kw ):
+ """Tells the overlay's categories to create metadata.
+ You don't have to call this before write()/show() unless you want to use
+ special metadata options.
+
+ arguments:
+ * **metadata_kw -- keywords for package.PackageDir.generate_metadata(...)
+
+ returns: None (implicit)
+ """
+ for cat in self._categories.values():
+ cat.generate_metadata ( **metadata_kw )
+ # --- end of generate_metadata (...) ---
+
+ def has_dir ( self, _dir ):
+ return os.path.isdir ( self.physical_location + os.sep + _dir )
+ # --- end of has_category (...) ---
+
+ def keep_nth_latest ( self, *args, **kwargs ):
+ """See package.py:PackageDir:keep_nth_latest."""
+ for cat in self._categories.values():
+ cat.keep_nth_latest ( *args, **kwargs )
+ # --- end of keep_nth_latest (...) ---
+
+ def list_packages ( self, for_deprules=True ):
+ for cat in self._categories.values():
+ for package in cat.list_packages ( for_deprules=True ):
+ yield package
+ # --- end of list_packages (...) ---
+
+ def list_rule_kwargs ( self ):
+ for cat in self._categories.values():
+ for kwargs in cat.list_packages ( for_deprules=True ):
+ yield kwargs
+ # --- end of list_rule_kwargs (...) ---
+
+ def scan ( self, **kw ):
+ def scan_categories():
+ for x in os.listdir ( self.physical_location ):
+ # FIXME could use a better check here
+ if '-' in x and self.has_dir ( x ):
+ yield self._get_category ( x )
+ # --- end of scan_categories (...) ---
+
+ if os.path.isdir ( self.physical_location ):
+ for cat in scan_categories():
+ try:
+ cat.scan ( **kw )
+ except Exception as e:
+ self.logger.exception ( e )
+ # --- end of scan (...) ---
+
+ def show ( self, **show_kw ):
+ """Presents the ebuilds/metadata stored in this overlay.
+
+ arguments:
+ * **show_kw -- keywords for package.PackageDir.show(...)
+
+ returns: None (implicit)
+ """
+ if not self._header.eclasses: self._header.set_eclasses (
+ tuple ( self._get_eclass_import_info ( only_eclass_names=True ) )
+ )
+ for cat in self._categories.values():
+ cat.show ( **show_kw )
+ # --- end of show (...) ---
+
+ def write ( self, **write_kw ):
+ """Writes the overlay to its physical location (filesystem), including
+ metadata and Manifest files.
+
+ arguments:
+ * **write_kw -- keywords for package.PackageDir.write(...)
+
+ returns: None (implicit)
+
+ raises: IOError
+
+ ! TODO/FIXME/DOC: This is not thread-safe, it's expected to be called
+ when ebuild creation is done.
+ """
+ raise Exception ( "to be removed/replaced" )
+ # writing profiles/ here, rewriting categories/ later
+ self._init_overlay ( reimport_eclass=True )
+
+ for cat in self._categories.values():
+ if not cat.empty():
+ util.dodir ( cat.physical_location )
+ cat.write ( **write_kw )
+ # --- end of write (...) ---
+
+ def write_incremental ( self, **write_kw ):
+ """Writes all ebuilds that have been modified since the last write call.
+ Note that there are currently two modes of incremental writing:
+ (a) per-PackageDir incremental writing triggered by the new_ebuild()
+ event method and (b) "batched" incremental writing (this method) which
+ writes all modified PackageDirs.
+ """
+ # FIXME merge with write(), making incremental writing the only option
+ # FIXME finalize_write_incremental?
+ if not self._incremental_write_lock.acquire():
+ # another incremental write is running, drop this request
+ return
+
+ try:
+ util.dodir ( self.physical_location )
+ cats = tuple ( self._categories.values() )
+ for cat in cats:
+ util.dodir ( cat.physical_location )
+ cat.write_incremental ( **write_kw )
+ finally:
+ self._incremental_write_lock.release()
+ # --- end of write_incremental (...) ---
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/metadata/, roverlay/overlay/
@ 2012-07-31 17:51 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2012-07-31 17:51 UTC (permalink / raw
To: gentoo-commits
commit: 3a7ca63ed7d8a57927835ce06b718354caa30b1a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 31 14:02:27 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 31 14:02:27 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=3a7ca63e
fix show_metadata
this fixes calling show_metadata with no metadata available
---
roverlay/overlay/metadata/__init__.py | 44 +++++++++++++++++++-------------
roverlay/overlay/package.py | 1 +
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/roverlay/overlay/metadata/__init__.py b/roverlay/overlay/metadata/__init__.py
index c07f7a2..36e775c 100644
--- a/roverlay/overlay/metadata/__init__.py
+++ b/roverlay/overlay/metadata/__init__.py
@@ -42,7 +42,9 @@ class MetadataJob ( object ):
self._package_info = package_info
# --- end of update (...) ---
- def update_using_iterable ( self, package_info_iter ):
+ def update_using_iterable ( self, package_info_iter, reset=True ):
+ if reset:
+ self._package_info = None
for package_info in package_info_iter:
self.update ( package_info )
# --- end of update_using_iterable (...) ---
@@ -101,24 +103,30 @@ class MetadataJob ( object ):
# --- end of _write (...) ---
def show ( self, stream ):
- return self._create().write_file ( stream )
+ if self._package_info is not None:
+ return self._create().write_file ( stream )
+ else:
+ return False
# --- end of show (...) ---
def write ( self ):
- _success = False
- try:
- # succeed if metadata empty or written
- mref = self._create()
- if mref.empty():
- _success = True
- else:
- fh = open ( self.filepath, 'w' )
- _success = self._write ( fh, mref )
-
- except Exception as e:
- self.logger.exception ( e )
- finally:
- if 'fh' in locals() and fh: fh.close()
-
- return _success
+ if self._package_info is not None:
+ _success = False
+ try:
+ # succeed if metadata empty or written
+ mref = self._create()
+ if mref.empty():
+ _success = True
+ else:
+ fh = open ( self.filepath, 'w' )
+ _success = self._write ( fh, mref )
+
+ except Exception as e:
+ self.logger.exception ( e )
+ finally:
+ if 'fh' in locals() and fh: fh.close()
+
+ return _success
+ else:
+ return False
# --- end of write (...) ---
diff --git a/roverlay/overlay/package.py b/roverlay/overlay/package.py
index cb5cf72..434b1b1 100644
--- a/roverlay/overlay/package.py
+++ b/roverlay/overlay/package.py
@@ -158,6 +158,7 @@ class PackageDir ( object ):
# FIXME debug print
print ( "removing {PVR} from {PN}".format ( PVR=pvr, PN=self.name ) )
del self._packages [pvr]
+ self.generate_metadata ( skip_if_existent=False )
except KeyError:
pass
finally:
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/metadata/, roverlay/overlay/
@ 2012-08-02 15:14 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2012-08-02 15:14 UTC (permalink / raw
To: gentoo-commits
commit: 041f770675b288ef3f6a04670b9c4e399e4e26f0
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 2 15:10:56 2012 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 2 15:10:56 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=041f7706
overlay: comments, string formatting and strutil
also readded RERAISE to category.py's threaded overlay writing
---
roverlay/overlay/category.py | 10 +++++---
roverlay/overlay/creator.py | 13 +----------
roverlay/overlay/metadata/abstractnodes.py | 30 +++++++++++++--------------
roverlay/overlay/metadata/nodes.py | 3 +-
roverlay/overlay/package.py | 28 +++++++++++--------------
roverlay/overlay/root.py | 23 +++++++++++++--------
6 files changed, 49 insertions(+), 58 deletions(-)
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index 3551b81..7bf93c8 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -158,10 +158,9 @@ class Category ( object ):
pkg.write ( write_manifest=False, **write_kw )
except queue.Empty:
break
- #except ( Exception, KeyboardInterrupt ) as e:
except Exception as e:
- # FIXME: reintroduce RERAISE
- self.logger.exception ( e )
+ #self.logger.exception ( e )
+ self.RERAISE = e
# --- end of run_write_queue (...) ---
if len ( self._subdirs ) == 0: return
@@ -177,7 +176,7 @@ class Category ( object ):
max_jobs = self.__class__.WRITE_JOBCOUNT
- # FIXME/TODO: what's an reasonable number of min package dirs to
+ # What's an reasonable number of min package dirs to
# start threaded writing?
# Ignoring it for now (and expecting enough pkg dirs)
if max_jobs > 1:
@@ -201,6 +200,9 @@ class Category ( object ):
for w in workers: w.start()
for w in workers: w.join()
+ if hasattr ( self, 'RERAISE' ) and self.RERAISE is not None:
+ raise self.RERAISE
+
self.remove_empty()
# write manifest files
diff --git a/roverlay/overlay/creator.py b/roverlay/overlay/creator.py
index 5f346fe..6b42867 100644
--- a/roverlay/overlay/creator.py
+++ b/roverlay/overlay/creator.py
@@ -196,7 +196,7 @@ class OverlayCreator ( object ):
delta = _stop - start
self.logger.debug (
- "timestamp: %s (after %f seconds)" % ( description, delta )
+ "timestamp: {} (after {} seconds)".format ( description, delta )
)
return _stop
# --- end of _timestamp (...) ---
@@ -214,10 +214,7 @@ class OverlayCreator ( object ):
# --- end of add_package (...) ---
def write_overlay ( self ):
- """Writes the overlay.
-
- arguments:
- """
+ """Writes the overlay."""
if self.overlay.writeable():
start = time.time()
self.overlay.write()
@@ -306,7 +303,6 @@ class OverlayCreator ( object ):
if do_close:
self._err_queue.push ( context=-1, error=None )
- # fixme: remove enabled?
for w in self._workers: w.enabled = False
else:
for w in self._workers: w.stop_when_empty()
@@ -373,11 +369,6 @@ class OverlayCreator ( object ):
arguments:
* package_info --
"""
- # ... TODO
- # * increase the number of successful/failed packages,
- # * request an incremental write to save memory etc.
-
- # if <>:
if package_info ['ebuild'] is not None:
self.create_success.inc()
if package_info.overlay_package_ref.new_ebuild():
diff --git a/roverlay/overlay/metadata/abstractnodes.py b/roverlay/overlay/metadata/abstractnodes.py
index 284ea20..060d369 100644
--- a/roverlay/overlay/metadata/abstractnodes.py
+++ b/roverlay/overlay/metadata/abstractnodes.py
@@ -2,6 +2,7 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+from roverlay import strutil
import re
import textwrap
@@ -16,7 +17,6 @@ class _MetadataBasicNode ( object ):
"""
# these chars lead to metadata.bad: invalid token
- # TODO/FIXME: look into repoman's / portage's source to get _all_ chars
INVALID_CHARS = "&<>"
def __init__ ( self, name, flags ):
@@ -92,7 +92,6 @@ class _MetadataBasicNode ( object ):
Does nothing if self._verify is not implemented, else dies on error.
"""
if hasattr ( self, '_verify' ) and not self._verify():
- # todo, verify could return ( Status, ErrorMessages ) etc.
raise Exception ( "verification failed for a metadata node." )
# --- end of _do_verify (...) ---
@@ -197,10 +196,14 @@ class MetadataLeaf ( _MetadataBasicNode ):
if not self._text_wrapper is None:
self._text_wrapper.subsequent_indent = self.text_indent
- def _value_str ( self ):
+ def _default_value_str ( self ):
"""Returns the value string. Derived classes may override this."""
#if self.value_format == ?: format value ~
- return str ( self.value )
+ return re.sub (
+ "[" + self.__class__.INVALID_CHARS + "]",
+ '',
+ strutil.ascii_filter ( str ( self.value ) )
+ )
# --- end of _value_str (...) ---
def _pretty_value_str ( self ):
@@ -208,7 +211,6 @@ class MetadataLeaf ( _MetadataBasicNode ):
Not used here, but subclasses can use it by simply writing
'_value_str = MetadataLeaf._pretty_value_str' in the class body.
"""
- # FIXME/TODO: could move this func to util
if not self.value: return ""
if self._text_wrapper is None:
@@ -218,13 +220,8 @@ class MetadataLeaf ( _MetadataBasicNode ):
width=self.linewidth if hasattr ( self, 'linewidth' ) else 50
)
- val_lines = self._text_wrapper.wrap (
- re.sub (
- "[{}]".format ( self.__class__.INVALID_CHARS ),
- '',
- self.value
- )
- )
+ val_lines = self._text_wrapper.wrap ( self._default_value_str() )
+
if len ( val_lines ) < 1:
# why?
return ""
@@ -242,10 +239,11 @@ class MetadataLeaf ( _MetadataBasicNode ):
self._do_verify()
if self.print_node_name:
return "{indent}<{name}{flags}>{value}</{name}>".format (
- indent=self.indent,
- name=self.name,
- flags=self._flagstr(),
- value=self._value_str(),
+ indent = self.indent,
+ name = self.name,
+ flags = self._flagstr(),
+ value = self._value_str() \
+ if hasattr ( self, '_value_str' ) else self._default_value_str()
)
else:
# not very useful, but allows to insert strings as nodes
diff --git a/roverlay/overlay/metadata/nodes.py b/roverlay/overlay/metadata/nodes.py
index 0002267..5f97181 100644
--- a/roverlay/overlay/metadata/nodes.py
+++ b/roverlay/overlay/metadata/nodes.py
@@ -2,7 +2,6 @@
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from roverlay import util
# import abstract nodes
from roverlay.overlay.metadata.abstractnodes import \
MetadataNode, MetadataNodeNamedAccess, MetadataLeaf
@@ -71,7 +70,7 @@ class MetadataRoot ( MetadataNodeNamedAccess ):
if not self.empty():
fh.write ( MetadataRoot.HEADER )
fh.write ( '\n' )
- fh.write ( util.ascii_filter ( self.to_str() ) )
+ fh.write ( self.to_str() )
fh.write ( '\n' )
return True
else:
diff --git a/roverlay/overlay/package.py b/roverlay/overlay/package.py
index 434b1b1..722be8b 100644
--- a/roverlay/overlay/package.py
+++ b/roverlay/overlay/package.py
@@ -122,8 +122,6 @@ class PackageDir ( object ):
if added:
# add a link to this PackageDir into the package info,
# !! package_info <-> self (double-linked)
- # FIXME: remove physical_only flag from PackageInfo if
- # overlay_package_ref can be used for that
package_info.overlay_package_ref = self
return True
else:
@@ -267,8 +265,17 @@ class PackageDir ( object ):
"Kept {kept}/{total} ebuilds.".format ( kept=kept, total=ecount )
)
- # FIXME: Manifest is now invalid and dir could be "empty" (no ebuilds)
- # FIXME: force metadata regeneration
+ if self._need_metadata:
+ self.generate_metadata ( skip_if_existent=False )
+
+ # Manifest is now invalid,
+ # need_manifest is set to True in purge_package()
+ #
+ # metadata will be re-written when calling write()
+ #
+ # dir could be "empty" (no ebuilds),
+ # which is solved when calling fs_cleanup(),
+ # implicitly called by write()
# --- end of keep_nth_latest (...) ---
def list_versions ( self ):
@@ -296,6 +303,7 @@ class PackageDir ( object ):
p = self._packages [pvr]
del self._packages [pvr]
self._remove_ebuild_file ( p )
+ self._need_metadata = True
return p
except Exception as e:
self.logger.exception ( e )
@@ -450,7 +458,6 @@ class PackageDir ( object ):
self.virtual_cleanup()
self.fs_cleanup()
- # FIXME / TODO call fs_cleanup
# -- lock
return success
# --- end of write (...) ---
@@ -483,10 +490,6 @@ class PackageDir ( object ):
fh.write ( str ( ebuild ) )
fh.write ( '\n' )
- # adjust owner/perm? TODO
- #if shared_fh is None:
- # chmod 0644 or 0444
- # chown 250.250
_success = True
except IOError as e:
self.logger.exception ( e )
@@ -574,13 +577,6 @@ class PackageDir ( object ):
elif ignore_empty:
return True
else:
- # FIXME: debug statements
- # FIXME: remove excpetion, maybe delete Manifest in this case,..
- for pvr, p in self._packages.items():
- print ( "{} {} ebuild={} efile={} has={}".format (
- pvr, p, p.has ('ebuild'), p ['ebuild_file'], self.has_ebuilds()
- ) )
-
raise Exception (
'In {mydir}: No ebuild written so far! '
'I really don\'t know what do to!'.format (
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index 3efdf66..5cbcef3 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -31,7 +31,7 @@ class Overlay ( object ):
write_allowed,
incremental,
skip_manifest,
- runtime_incremental=True
+ runtime_incremental=False
):
"""Initializes an overlay.
@@ -52,7 +52,7 @@ class Overlay ( object ):
!!! The created overlay cannot be used with
emerge/portage
* runtime_incremental -- see package.py:PackageDir.__init__ (...),
- Defaults to ?FIXME?
+ Defaults to False (saves memory but costs time)
"""
self.name = name
@@ -73,7 +73,7 @@ class Overlay ( object ):
self.skip_manifest = skip_manifest
- # fixme or ignore: calculating eclass names twice,
+ # calculating eclass names twice,
# once here and another time when calling _init_overlay
self._header.set_eclasses ( frozenset (
self._get_eclass_import_info ( only_eclass_names=True )
@@ -279,7 +279,6 @@ class Overlay ( object ):
def scan ( self, **kw ):
def scan_categories():
for x in os.listdir ( self.physical_location ):
- # FIXME could use a better check here
if '-' in x and self.has_dir ( x ):
yield self._get_category ( x )
# --- end of scan_categories (...) ---
@@ -322,8 +321,8 @@ class Overlay ( object ):
raises: IOError
- ! TODO/FIXME/DOC: This is not thread-safe, it's expected to be called
- when ebuild creation is done.
+ 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 )
@@ -354,9 +353,15 @@ class Overlay ( object ):
returns: None (implicit)
"""
if self._writeable and not self.skip_manifest:
- # FIXME: it would be good to ensure that profiles/categories exist
- for cat in self._categories.values():
- cat.write_manifest ( **manifest_kw )
+ # profiles/categories is required for successful Manifest
+ # creation
+ if os.path.isfile ( self._profiles_dir + os.sep + 'categories' ):
+ for cat in self._categories.values():
+ cat.write_manifest ( **manifest_kw )
+ else:
+ raise Exception (
+ 'profiles/categories is missing - cannot write Manifest files!'
+ )
elif not self.skip_manifest:
# FIXME debug print
print (
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-08-02 15:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-31 17:51 [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/metadata/, roverlay/overlay/ André Erdmann
-- strict thread matches above, loose matches on Subject: below --
2012-08-02 15:14 André Erdmann
2012-07-30 8:52 André Erdmann
2012-07-23 16:34 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
2012-07-30 8:52 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox