* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/overlay/pkgdir/manifest/, roverlay/tools/, roverlay/config/, roverlay/, ...
2013-06-13 16:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/pkgdir/manifest/, roverlay/tools/, roverlay/config/, roverlay/, André Erdmann
@ 2013-06-06 21:15 ` André Erdmann
0 siblings, 0 replies; 2+ messages in thread
From: André Erdmann @ 2013-06-06 21:15 UTC (permalink / raw
To: gentoo-commits
commit: 47d9b844a010d8b4334facc784d2db1ab08f80c5
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 6 21:13:22 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 6 21:13:22 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=47d9b844
roverlay/overlay: additions dir
---
roverlay/argutil.py | 30 ++++++-
roverlay/config/const.py | 15 ++++
roverlay/config/entrymap.py | 16 ++--
roverlay/overlay/additionsdir.py | 98 ++++++++++++++++++++++
roverlay/overlay/category.py | 13 ++-
.../overlay/pkgdir/manifest/manifest_ebuild.py | 4 +-
roverlay/overlay/pkgdir/packagedir_base.py | 65 +++++++++++---
roverlay/overlay/root.py | 27 +++++-
roverlay/tools/__init__.py | 0
roverlay/tools/patch.py | 45 ++++++++++
10 files changed, 286 insertions(+), 27 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 90d95df..99842fd 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -67,6 +67,12 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
return d
+ def is_fs_dir_or_void ( value ):
+ if value:
+ return is_fs_dir ( value )
+ else:
+ return ''
+
def is_fs_file_or_void ( value ):
if value:
return is_fs_file ( value )
@@ -180,6 +186,14 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--additions-dir', '-A', # '--patch-dir', '--ebuild-dir',
+ default=argparse.SUPPRESS,
+ help="directory containing patches and hand-written ebuilds",
+ metavar="<dir>",
+ type=is_fs_dir_or_void
+ )
+
+ arg (
'--overlay-name', '-N', default=argparse.SUPPRESS,
help="overlay name",
metavar="<name>",
@@ -353,6 +367,8 @@ def parse_argv ( command_map, **kw ):
All args/keywords are passed to get_parser().
Passes all exceptions.
"""
+ p = get_parser ( command_map=command_map, **kw ).parse_args()
+
def doconf ( value, path ):
pos = conf
if isinstance ( path, str ):
@@ -367,11 +383,17 @@ def parse_argv ( command_map, **kw ):
pos [k] = dict()
pos = pos [k]
+ # --- end of doconf (...) ---
+ def given ( attr_name ):
+ return hasattr ( p, attr_name )
+ # --- end of given (...) ---
- p = get_parser ( command_map=command_map, **kw ).parse_args()
-
- given = lambda kw : hasattr ( p, kw )
+ def doconf_simple ( attr_name, config_path ) :
+ value = getattr ( p, attr_name, None )
+ if value is not None:
+ doconf ( value, config_path )
+ # --- end of doconf_simple (...) ---
commands = ( p.commands, ) if isinstance ( p.commands, str ) else p.commands
conf = dict()
@@ -397,6 +419,8 @@ def parse_argv ( command_map, **kw ):
doconf ( p.overlay, 'OVERLAY.dir' )
#extra ['write_overlay'] = True
+ doconf_simple ( "additions_dir", "OVERLAY.additions_dir" )
+
if given ( 'overlay_name' ):
doconf ( p.overlay_name, 'OVERLAY.name' )
diff --git a/roverlay/config/const.py b/roverlay/config/const.py
index 48e0e55..b3e8dc4 100644
--- a/roverlay/config/const.py
+++ b/roverlay/config/const.py
@@ -68,6 +68,21 @@ _CONSTANTS = dict (
category = 'sci-R',
manifest_implementation = 'default',
),
+
+ TOOLS = dict (
+ EBUILD = dict (
+ prog = "/usr/bin/ebuild",
+ target = "manifest",
+ ),
+ PATCH = dict (
+ exe = "patch",
+ opts = (
+ '--no-backup-if-mismatch',
+ '--reject-file=-'
+ '--quiet', '--force',
+ )
+ ),
+ ),
)
def lookup ( key, fallback_value=None ):
diff --git a/roverlay/config/entrymap.py b/roverlay/config/entrymap.py
index 77525a8..c98bc68 100644
--- a/roverlay/config/entrymap.py
+++ b/roverlay/config/entrymap.py
@@ -223,6 +223,11 @@ CONFIG_ENTRY_MAP = dict (
'''
),
+ overlay_additions_dir = dict (
+ value_type = 'fs_abs:fs_dir',
+ description = 'directory containing ebuilds and ebuild patches',
+ ),
+
overlay_eclass = dict (
path = [ 'OVERLAY', 'eclass_files' ],
value_type = fs_abslist,
@@ -263,11 +268,11 @@ CONFIG_ENTRY_MAP = dict (
overlay_distdir_root = dict (
value_type = 'fs_dir',
- description = (
- 'DISTDIR which is used for Manifest creation and can, '
- 'depending on the DISTDIR strategy, '
- 'serve as package mirror directory',
- ),
+ description = '''
+ DISTDIR which is used for Manifest creation and can,
+ depending on the DISTDIR strategy,
+ serve as package mirror directory.
+ '''
),
overlay_distdir_strategy = dict (
@@ -293,6 +298,7 @@ CONFIG_ENTRY_MAP = dict (
eclass = 'overlay_eclass',
keep_nth_latest = 'overlay_keep_nth_latest',
manifest_implementation = 'overlay_manifest_implementation',
+ additions_dir = 'overlay_additions_dir',
distdir = 'overlay_distdir_root',
distdir_strategy = 'overlay_distdir_strategy',
distdir_flat = 'overlay_distdir_flat',
diff --git a/roverlay/overlay/additionsdir.py b/roverlay/overlay/additionsdir.py
new file mode 100644
index 0000000..7136bb5
--- /dev/null
+++ b/roverlay/overlay/additionsdir.py
@@ -0,0 +1,98 @@
+# R overlay -- overlay package, overlay additions dir
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+import os
+import re
+
+class AdditionsDir ( object ):
+
+ def __init__ ( self, fspath, name=None, parent=None ):
+ self.root = str ( fspath ) if fspath else None
+ self.parent = parent
+ self.name = name
+ # --- end of __init__ (...) ---
+
+ def exists ( self ):
+ return self.root is not None and os.path.isdir ( self.root )
+ # --- end of exists (...) ---
+
+ __bool__ = exists
+
+ def get_subdir ( self, relpath ):
+ if self.root:
+ return self.__class__ (
+ fspath = ( self.root + os.sep + relpath ),
+ name = relpath,
+ parent = self
+ )
+ else:
+ return self
+ # --- end of get_subdir (...) ---
+
+ def get_obj_subdir ( self, obj ):
+ return self.get_subdir ( obj.name )
+ # --- end of get_obj_subdir (...) ---
+
+ def __str__ ( self ):
+ return self.root or ""
+ # --- end of __str__ (...) ---
+
+
+class _AdditionsDirView ( object ):
+
+ def __init__ ( self, additions_dir ):
+ self._additions_dir = additions_dir
+ # --- end of __init__ (...) ---
+
+ def __bool__ ( self ):
+ return bool ( self._additions_dir )
+ # --- end of __bool__ (...) ---
+
+
+class _EbuildAdditionsView ( _AdditionsDirView ):
+
+ def __init__ ( self, additions_dir ):
+ super ( _EbuildAdditionsView, self ).__init__ (
+ additions_dir=additions_dir
+ )
+ if hasattr ( self, 'prepare' ):
+ self.prepare()
+ # --- end of __init__ (...) ---
+
+ def _get_files_with_suffix ( self, suffix ):
+ assert '.' not in self._additions_dir.name
+
+ fre = re.compile (
+ self._additions_dir.name + '[-](?P<pvr>[0-9.]+([-]r[0-9]+)?)'
+ + suffix.replace ( '.', '[.]' )
+ )
+ root = self._additions_dir.root
+ for fname in os.listdir ( root ):
+ fmatch = fre.match ( fname )
+ if fmatch:
+ yield ( fmatch.group ( 'pvr' ), ( root + os.sep + fname ), fname )
+ # --- end of _get_files_with_suffix (...) ---
+
+
+class PatchView ( _EbuildAdditionsView ):
+
+ def has_patches ( self ):
+ return bool ( getattr ( self, '_patches', None ) )
+ # --- end of has_patches (...) ---
+
+ def get_patches ( self, pvr ):
+ patch = self._patches.get ( pvr, None )
+ return ( patch, ) if patch is not None else None
+ # --- end of get_patches (...) ---
+
+ def prepare ( self ):
+ if self._additions_dir.exists():
+ # dict { pvr => patch_file }
+ self._patches = {
+ pvr: fpath
+ for pvr, fpath, fname in self._get_files_with_suffix ( '.patch' )
+ }
+ # --- end of prepare (...) ---
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index baca2d1..7ccd86e 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -212,7 +212,8 @@ class Category ( object ):
overwrite_ebuilds,
keep_n_ebuilds,
cautious,
- write_manifest
+ write_manifest,
+ additions_dir
):
"""Writes this category to its filesystem location.
@@ -230,7 +231,10 @@ class Category ( object ):
pkg = q.get_nowait()
# remove manifest writing from threaded writing since it's
# single-threaded
- pkg.write ( **write_kw )
+ pkg.write (
+ additions_dir = additions_dir.get_obj_subdir ( pkg ),
+ **write_kw
+ )
except queue.Empty:
break
except ( Exception, KeyboardInterrupt ) as err:
@@ -310,7 +314,10 @@ class Category ( object ):
else:
for package in self._subdirs.values():
- package.write ( **write_kwargs )
+ package.write (
+ additions_dir = additions_dir.get_obj_subdir ( package ),
+ **write_kwargs
+ )
self.remove_empty()
# --- end of write (...) ---
diff --git a/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py b/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
index 898ecb1..1004381 100644
--- a/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
+++ b/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
@@ -33,8 +33,8 @@ class ExternalManifestCreation ( object ):
def _doinit ( self ):
"""Initializes self's data, needs an initialized ConfigTree."""
self.manifest_env = ManifestEnv.get_new()
- self.ebuild_tgt = config.get ( 'TOOLS.EBUILD.target', 'manifest' )
- self.ebuild_prog = config.get ( 'TOOLS.EBUILD.prog', '/usr/bin/ebuild' )
+ self.ebuild_tgt = config.get_or_fail ( 'TOOLS.EBUILD.target' )
+ self.ebuild_prog = config.get_or_fail ( 'TOOLS.EBUILD.prog' )
# set PORDIR_OVERLAY and DISTDIR
self.manifest_env ['PORTDIR_OVERLAY'] = config.get_or_fail (
diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py
index 62dd7c7..0e5ee81 100644
--- a/roverlay/overlay/pkgdir/packagedir_base.py
+++ b/roverlay/overlay/pkgdir/packagedir_base.py
@@ -20,6 +20,10 @@ import sys
import threading
import shutil
+
+import roverlay.overlay.additionsdir
+import roverlay.tools.patch
+
from roverlay import util
from roverlay.packageinfo import PackageInfo
from roverlay.overlay.pkgdir.metadata import MetadataJob
@@ -427,7 +431,9 @@ class PackageDirBase ( object ):
raises:
* passes all exceptions (IOError, ..)
"""
- self.write_ebuilds ( overwrite=True, shared_fh=stream )
+ self.write_ebuilds (
+ overwrite=True, additions_dir=None, shared_fh=stream
+ )
self.write_metadata ( shared_fh=stream )
return True
# --- end of show (...) ---
@@ -445,6 +451,7 @@ class PackageDirBase ( object ):
# --- end of virtual_cleanup (...) ---
def write ( self,
+ additions_dir,
overwrite_ebuilds=False,
write_ebuilds=True, write_manifest=True, write_metadata=True,
cleanup=True, keep_n_ebuilds=None, cautious=True
@@ -452,6 +459,7 @@ class PackageDirBase ( object ):
"""Writes this directory to its (existent!) filesystem location.
arguments:
+ * additions_dir -- AdditionsDir object for this package
* 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
@@ -490,16 +498,16 @@ class PackageDirBase ( object ):
# write ebuilds
if self.modified and write_ebuilds:
+ # ( overwrite == None ) <= not modified, which is not
+ # possible in this if-branch
success = self.write_ebuilds (
- # ( overwrite == None ) <= not modified, which is not
- # possible in this if-branch
-
- overwrite = bool ( overwrite_ebuilds )
-
+ additions_dir = additions_dir,
+ overwrite = bool ( overwrite_ebuilds )
+ )
# overwrite = overwrite_ebuilds \
# if overwrite_ebuilds is not None \
# else not self.modified
- )
+
# cautious: remove ebuilds after writing them
if cautious and keep_n_ebuilds is not None:
@@ -525,13 +533,14 @@ class PackageDirBase ( object ):
return success
# --- end of write (...) ---
- def write_ebuilds ( self, overwrite, shared_fh=None ):
+ def write_ebuilds ( self, overwrite, additions_dir, shared_fh=None ):
"""Writes all ebuilds.
arguments:
+ * overwrite -- write ebuilds that have been written before
+ * additions_dir --
* 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
"""
ebuild_header = self.get_header()
@@ -562,6 +571,29 @@ class PackageDirBase ( object ):
return _success
# --- end of write_ebuild (...) ---
+ def patch_ebuild ( efile, patches ):
+ if patches:
+ self.logger.info ( "Patching " + str ( efile ) )
+ self.logger.debug (
+ "Patches for {} (in that order): {}".format ( efile, patches )
+ )
+
+ patch_ret = None
+
+ for patch in patches:
+ patch_ret = roverlay.tools.patch.dopatch (
+ filepath=efile, patch=patch, logger=self.logger
+ )
+
+ if patch_ret != os.EX_OK:
+ # TODO
+ raise Exception ( patch )
+
+ return True
+ else:
+ return True
+ # --- end of patch_ebuild (...) ---
+
def ebuilds_to_write():
"""Yields all ebuilds that are ready to be written."""
@@ -570,7 +602,7 @@ class PackageDirBase ( object ):
efile = self.ebuild_filepath_format.format ( PVR=ver )
if efile != p_info ['ebuild_file'] or overwrite:
- yield ( efile, p_info )
+ yield ( ver, efile, p_info )
# else efile exists
# --- end of ebuilds_to_write (...) ---
@@ -579,12 +611,21 @@ class PackageDirBase ( object ):
# don't call dodir if shared_fh is set
hasdir = bool ( shared_fh is not None )
- for efile, p_info in ebuilds_to_write():
+ patchview = roverlay.overlay.additionsdir.PatchView ( additions_dir )
+ haspatch = patchview.has_patches()
+
+ for pvr, efile, p_info in ebuilds_to_write():
if not hasdir:
util.dodir ( self.physical_location, mkdir_p=True )
hasdir = True
- if write_ebuild ( efile, p_info ['ebuild'] ):
+ if (
+ write_ebuild ( efile, p_info ['ebuild'] )
+ ) and (
+ not haspatch
+ or patch_ebuild ( efile, patchview.get_patches ( pvr ) )
+ ):
+
self._need_manifest = True
# update metadata for each successfully written ebuild
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index b9030d2..ca71b81 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -27,6 +27,9 @@ from roverlay import config, util
from roverlay.overlay.category import Category
from roverlay.overlay.header import EbuildHeader
+import roverlay.overlay.additionsdir
+
+
class Overlay ( object ):
DEFAULT_USE_DESC = '\n'.join ( (
'byte-compile - enable byte compiling',
@@ -63,6 +66,7 @@ class Overlay ( object ):
incremental = incremental,
write_allowed = write_allowed,
skip_manifest = skip_manifest,
+ additions_dir = config.get_or_fail ( 'OVERLAY.additions_dir' ),
runtime_incremental = runtime_incremental,
)
# --- end of new_configured (...) ---
@@ -78,7 +82,8 @@ class Overlay ( object ):
write_allowed,
incremental,
skip_manifest,
- runtime_incremental=False,
+ additions_dir,
+ runtime_incremental=False
):
"""Initializes an overlay.
@@ -98,6 +103,11 @@ class Overlay ( object ):
* skip_manifest -- skip Manifest generation to save time
!!! The created overlay cannot be used with
emerge/portage
+ * additions_dir -- path to a directory that contains additional
+ files, e.g. hand-written ebuilds and ebuild
+ patches. The directory has to exist (it will
+ be checked here).
+ A value of None or "" disables additions.
* runtime_incremental -- see package.py:PackageDir.__init__ (...),
Defaults to False (saves memory but costs time)
@@ -120,6 +130,14 @@ class Overlay ( object ):
self.skip_manifest = skip_manifest
+ if additions_dir:
+ if os.path.isdir ( additions_dir ):
+ self.additions_dirpath = os.path.abspath ( additions_dir )
+ else:
+ raise ValueError (
+ "additions dir {} does not exist!".format ( additions_dir )
+ )
+
# calculating eclass names twice,
# once here and another time when calling _init_overlay
self._header.set_eclasses ( frozenset (
@@ -463,12 +481,17 @@ class Overlay ( object ):
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 ),
cautious = True,
- write_manifest = not self.skip_manifest
+ write_manifest = not self.skip_manifest,
+ additions_dir = additions_dir.get_obj_subdir ( cat ),
)
else:
# FIXME debug print
diff --git a/roverlay/tools/__init__.py b/roverlay/tools/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/roverlay/tools/patch.py b/roverlay/tools/patch.py
new file mode 100644
index 0000000..119ff80
--- /dev/null
+++ b/roverlay/tools/patch.py
@@ -0,0 +1,45 @@
+# R overlay -- tools, run patch(1)
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+import subprocess
+
+import roverlay.config
+import roverlay.strutil
+import roverlay.util
+
+_PATCHENV = roverlay.util.keepenv (
+ ( 'PATH', '' ), 'LANG', 'LC_ALL', 'PWD', 'TMPDIR'
+)
+
+# NOTE:
+# this module has to be loaded after reading roverlay's config
+#
+
+_PATCHOPTS = (
+ ( roverlay.config.get_or_fail ( "TOOLS.PATCH.exe" ), )
+ + roverlay.config.get_or_fail ( "TOOLS.PATCH.opts" )
+)
+
+def dopatch ( filepath, patch, logger ):
+ print ( "RUN PATCH", filepath, patch )
+ patch_call = subprocess.Popen (
+ _PATCHOPTS + (
+ filepath, patch
+ ),
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=_PATCHENV,
+ )
+
+ output = patch_call.communicate()
+
+ # log stderr
+ for line in roverlay.strutil.pipe_lines ( output [1], use_filter=True ):
+ logger.warning ( line )
+
+ return patch_call.returncode
+# --- end of dopatch (...) ---
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/overlay/pkgdir/manifest/, roverlay/tools/, roverlay/config/, roverlay/, ...
@ 2013-06-13 16:34 André Erdmann
2013-06-06 21:15 ` [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: 47d9b844a010d8b4334facc784d2db1ab08f80c5
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 6 21:13:22 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 6 21:13:22 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=47d9b844
roverlay/overlay: additions dir
---
roverlay/argutil.py | 30 ++++++-
roverlay/config/const.py | 15 ++++
roverlay/config/entrymap.py | 16 ++--
roverlay/overlay/additionsdir.py | 98 ++++++++++++++++++++++
roverlay/overlay/category.py | 13 ++-
.../overlay/pkgdir/manifest/manifest_ebuild.py | 4 +-
roverlay/overlay/pkgdir/packagedir_base.py | 65 +++++++++++---
roverlay/overlay/root.py | 27 +++++-
roverlay/tools/__init__.py | 0
roverlay/tools/patch.py | 45 ++++++++++
10 files changed, 286 insertions(+), 27 deletions(-)
diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 90d95df..99842fd 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -67,6 +67,12 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
return d
+ def is_fs_dir_or_void ( value ):
+ if value:
+ return is_fs_dir ( value )
+ else:
+ return ''
+
def is_fs_file_or_void ( value ):
if value:
return is_fs_file ( value )
@@ -180,6 +186,14 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
)
arg (
+ '--additions-dir', '-A', # '--patch-dir', '--ebuild-dir',
+ default=argparse.SUPPRESS,
+ help="directory containing patches and hand-written ebuilds",
+ metavar="<dir>",
+ type=is_fs_dir_or_void
+ )
+
+ arg (
'--overlay-name', '-N', default=argparse.SUPPRESS,
help="overlay name",
metavar="<name>",
@@ -353,6 +367,8 @@ def parse_argv ( command_map, **kw ):
All args/keywords are passed to get_parser().
Passes all exceptions.
"""
+ p = get_parser ( command_map=command_map, **kw ).parse_args()
+
def doconf ( value, path ):
pos = conf
if isinstance ( path, str ):
@@ -367,11 +383,17 @@ def parse_argv ( command_map, **kw ):
pos [k] = dict()
pos = pos [k]
+ # --- end of doconf (...) ---
+ def given ( attr_name ):
+ return hasattr ( p, attr_name )
+ # --- end of given (...) ---
- p = get_parser ( command_map=command_map, **kw ).parse_args()
-
- given = lambda kw : hasattr ( p, kw )
+ def doconf_simple ( attr_name, config_path ) :
+ value = getattr ( p, attr_name, None )
+ if value is not None:
+ doconf ( value, config_path )
+ # --- end of doconf_simple (...) ---
commands = ( p.commands, ) if isinstance ( p.commands, str ) else p.commands
conf = dict()
@@ -397,6 +419,8 @@ def parse_argv ( command_map, **kw ):
doconf ( p.overlay, 'OVERLAY.dir' )
#extra ['write_overlay'] = True
+ doconf_simple ( "additions_dir", "OVERLAY.additions_dir" )
+
if given ( 'overlay_name' ):
doconf ( p.overlay_name, 'OVERLAY.name' )
diff --git a/roverlay/config/const.py b/roverlay/config/const.py
index 48e0e55..b3e8dc4 100644
--- a/roverlay/config/const.py
+++ b/roverlay/config/const.py
@@ -68,6 +68,21 @@ _CONSTANTS = dict (
category = 'sci-R',
manifest_implementation = 'default',
),
+
+ TOOLS = dict (
+ EBUILD = dict (
+ prog = "/usr/bin/ebuild",
+ target = "manifest",
+ ),
+ PATCH = dict (
+ exe = "patch",
+ opts = (
+ '--no-backup-if-mismatch',
+ '--reject-file=-'
+ '--quiet', '--force',
+ )
+ ),
+ ),
)
def lookup ( key, fallback_value=None ):
diff --git a/roverlay/config/entrymap.py b/roverlay/config/entrymap.py
index 77525a8..c98bc68 100644
--- a/roverlay/config/entrymap.py
+++ b/roverlay/config/entrymap.py
@@ -223,6 +223,11 @@ CONFIG_ENTRY_MAP = dict (
'''
),
+ overlay_additions_dir = dict (
+ value_type = 'fs_abs:fs_dir',
+ description = 'directory containing ebuilds and ebuild patches',
+ ),
+
overlay_eclass = dict (
path = [ 'OVERLAY', 'eclass_files' ],
value_type = fs_abslist,
@@ -263,11 +268,11 @@ CONFIG_ENTRY_MAP = dict (
overlay_distdir_root = dict (
value_type = 'fs_dir',
- description = (
- 'DISTDIR which is used for Manifest creation and can, '
- 'depending on the DISTDIR strategy, '
- 'serve as package mirror directory',
- ),
+ description = '''
+ DISTDIR which is used for Manifest creation and can,
+ depending on the DISTDIR strategy,
+ serve as package mirror directory.
+ '''
),
overlay_distdir_strategy = dict (
@@ -293,6 +298,7 @@ CONFIG_ENTRY_MAP = dict (
eclass = 'overlay_eclass',
keep_nth_latest = 'overlay_keep_nth_latest',
manifest_implementation = 'overlay_manifest_implementation',
+ additions_dir = 'overlay_additions_dir',
distdir = 'overlay_distdir_root',
distdir_strategy = 'overlay_distdir_strategy',
distdir_flat = 'overlay_distdir_flat',
diff --git a/roverlay/overlay/additionsdir.py b/roverlay/overlay/additionsdir.py
new file mode 100644
index 0000000..7136bb5
--- /dev/null
+++ b/roverlay/overlay/additionsdir.py
@@ -0,0 +1,98 @@
+# R overlay -- overlay package, overlay additions dir
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+import os
+import re
+
+class AdditionsDir ( object ):
+
+ def __init__ ( self, fspath, name=None, parent=None ):
+ self.root = str ( fspath ) if fspath else None
+ self.parent = parent
+ self.name = name
+ # --- end of __init__ (...) ---
+
+ def exists ( self ):
+ return self.root is not None and os.path.isdir ( self.root )
+ # --- end of exists (...) ---
+
+ __bool__ = exists
+
+ def get_subdir ( self, relpath ):
+ if self.root:
+ return self.__class__ (
+ fspath = ( self.root + os.sep + relpath ),
+ name = relpath,
+ parent = self
+ )
+ else:
+ return self
+ # --- end of get_subdir (...) ---
+
+ def get_obj_subdir ( self, obj ):
+ return self.get_subdir ( obj.name )
+ # --- end of get_obj_subdir (...) ---
+
+ def __str__ ( self ):
+ return self.root or ""
+ # --- end of __str__ (...) ---
+
+
+class _AdditionsDirView ( object ):
+
+ def __init__ ( self, additions_dir ):
+ self._additions_dir = additions_dir
+ # --- end of __init__ (...) ---
+
+ def __bool__ ( self ):
+ return bool ( self._additions_dir )
+ # --- end of __bool__ (...) ---
+
+
+class _EbuildAdditionsView ( _AdditionsDirView ):
+
+ def __init__ ( self, additions_dir ):
+ super ( _EbuildAdditionsView, self ).__init__ (
+ additions_dir=additions_dir
+ )
+ if hasattr ( self, 'prepare' ):
+ self.prepare()
+ # --- end of __init__ (...) ---
+
+ def _get_files_with_suffix ( self, suffix ):
+ assert '.' not in self._additions_dir.name
+
+ fre = re.compile (
+ self._additions_dir.name + '[-](?P<pvr>[0-9.]+([-]r[0-9]+)?)'
+ + suffix.replace ( '.', '[.]' )
+ )
+ root = self._additions_dir.root
+ for fname in os.listdir ( root ):
+ fmatch = fre.match ( fname )
+ if fmatch:
+ yield ( fmatch.group ( 'pvr' ), ( root + os.sep + fname ), fname )
+ # --- end of _get_files_with_suffix (...) ---
+
+
+class PatchView ( _EbuildAdditionsView ):
+
+ def has_patches ( self ):
+ return bool ( getattr ( self, '_patches', None ) )
+ # --- end of has_patches (...) ---
+
+ def get_patches ( self, pvr ):
+ patch = self._patches.get ( pvr, None )
+ return ( patch, ) if patch is not None else None
+ # --- end of get_patches (...) ---
+
+ def prepare ( self ):
+ if self._additions_dir.exists():
+ # dict { pvr => patch_file }
+ self._patches = {
+ pvr: fpath
+ for pvr, fpath, fname in self._get_files_with_suffix ( '.patch' )
+ }
+ # --- end of prepare (...) ---
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index baca2d1..7ccd86e 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -212,7 +212,8 @@ class Category ( object ):
overwrite_ebuilds,
keep_n_ebuilds,
cautious,
- write_manifest
+ write_manifest,
+ additions_dir
):
"""Writes this category to its filesystem location.
@@ -230,7 +231,10 @@ class Category ( object ):
pkg = q.get_nowait()
# remove manifest writing from threaded writing since it's
# single-threaded
- pkg.write ( **write_kw )
+ pkg.write (
+ additions_dir = additions_dir.get_obj_subdir ( pkg ),
+ **write_kw
+ )
except queue.Empty:
break
except ( Exception, KeyboardInterrupt ) as err:
@@ -310,7 +314,10 @@ class Category ( object ):
else:
for package in self._subdirs.values():
- package.write ( **write_kwargs )
+ package.write (
+ additions_dir = additions_dir.get_obj_subdir ( package ),
+ **write_kwargs
+ )
self.remove_empty()
# --- end of write (...) ---
diff --git a/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py b/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
index 898ecb1..1004381 100644
--- a/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
+++ b/roverlay/overlay/pkgdir/manifest/manifest_ebuild.py
@@ -33,8 +33,8 @@ class ExternalManifestCreation ( object ):
def _doinit ( self ):
"""Initializes self's data, needs an initialized ConfigTree."""
self.manifest_env = ManifestEnv.get_new()
- self.ebuild_tgt = config.get ( 'TOOLS.EBUILD.target', 'manifest' )
- self.ebuild_prog = config.get ( 'TOOLS.EBUILD.prog', '/usr/bin/ebuild' )
+ self.ebuild_tgt = config.get_or_fail ( 'TOOLS.EBUILD.target' )
+ self.ebuild_prog = config.get_or_fail ( 'TOOLS.EBUILD.prog' )
# set PORDIR_OVERLAY and DISTDIR
self.manifest_env ['PORTDIR_OVERLAY'] = config.get_or_fail (
diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py
index 62dd7c7..0e5ee81 100644
--- a/roverlay/overlay/pkgdir/packagedir_base.py
+++ b/roverlay/overlay/pkgdir/packagedir_base.py
@@ -20,6 +20,10 @@ import sys
import threading
import shutil
+
+import roverlay.overlay.additionsdir
+import roverlay.tools.patch
+
from roverlay import util
from roverlay.packageinfo import PackageInfo
from roverlay.overlay.pkgdir.metadata import MetadataJob
@@ -427,7 +431,9 @@ class PackageDirBase ( object ):
raises:
* passes all exceptions (IOError, ..)
"""
- self.write_ebuilds ( overwrite=True, shared_fh=stream )
+ self.write_ebuilds (
+ overwrite=True, additions_dir=None, shared_fh=stream
+ )
self.write_metadata ( shared_fh=stream )
return True
# --- end of show (...) ---
@@ -445,6 +451,7 @@ class PackageDirBase ( object ):
# --- end of virtual_cleanup (...) ---
def write ( self,
+ additions_dir,
overwrite_ebuilds=False,
write_ebuilds=True, write_manifest=True, write_metadata=True,
cleanup=True, keep_n_ebuilds=None, cautious=True
@@ -452,6 +459,7 @@ class PackageDirBase ( object ):
"""Writes this directory to its (existent!) filesystem location.
arguments:
+ * additions_dir -- AdditionsDir object for this package
* 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
@@ -490,16 +498,16 @@ class PackageDirBase ( object ):
# write ebuilds
if self.modified and write_ebuilds:
+ # ( overwrite == None ) <= not modified, which is not
+ # possible in this if-branch
success = self.write_ebuilds (
- # ( overwrite == None ) <= not modified, which is not
- # possible in this if-branch
-
- overwrite = bool ( overwrite_ebuilds )
-
+ additions_dir = additions_dir,
+ overwrite = bool ( overwrite_ebuilds )
+ )
# overwrite = overwrite_ebuilds \
# if overwrite_ebuilds is not None \
# else not self.modified
- )
+
# cautious: remove ebuilds after writing them
if cautious and keep_n_ebuilds is not None:
@@ -525,13 +533,14 @@ class PackageDirBase ( object ):
return success
# --- end of write (...) ---
- def write_ebuilds ( self, overwrite, shared_fh=None ):
+ def write_ebuilds ( self, overwrite, additions_dir, shared_fh=None ):
"""Writes all ebuilds.
arguments:
+ * overwrite -- write ebuilds that have been written before
+ * additions_dir --
* 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
"""
ebuild_header = self.get_header()
@@ -562,6 +571,29 @@ class PackageDirBase ( object ):
return _success
# --- end of write_ebuild (...) ---
+ def patch_ebuild ( efile, patches ):
+ if patches:
+ self.logger.info ( "Patching " + str ( efile ) )
+ self.logger.debug (
+ "Patches for {} (in that order): {}".format ( efile, patches )
+ )
+
+ patch_ret = None
+
+ for patch in patches:
+ patch_ret = roverlay.tools.patch.dopatch (
+ filepath=efile, patch=patch, logger=self.logger
+ )
+
+ if patch_ret != os.EX_OK:
+ # TODO
+ raise Exception ( patch )
+
+ return True
+ else:
+ return True
+ # --- end of patch_ebuild (...) ---
+
def ebuilds_to_write():
"""Yields all ebuilds that are ready to be written."""
@@ -570,7 +602,7 @@ class PackageDirBase ( object ):
efile = self.ebuild_filepath_format.format ( PVR=ver )
if efile != p_info ['ebuild_file'] or overwrite:
- yield ( efile, p_info )
+ yield ( ver, efile, p_info )
# else efile exists
# --- end of ebuilds_to_write (...) ---
@@ -579,12 +611,21 @@ class PackageDirBase ( object ):
# don't call dodir if shared_fh is set
hasdir = bool ( shared_fh is not None )
- for efile, p_info in ebuilds_to_write():
+ patchview = roverlay.overlay.additionsdir.PatchView ( additions_dir )
+ haspatch = patchview.has_patches()
+
+ for pvr, efile, p_info in ebuilds_to_write():
if not hasdir:
util.dodir ( self.physical_location, mkdir_p=True )
hasdir = True
- if write_ebuild ( efile, p_info ['ebuild'] ):
+ if (
+ write_ebuild ( efile, p_info ['ebuild'] )
+ ) and (
+ not haspatch
+ or patch_ebuild ( efile, patchview.get_patches ( pvr ) )
+ ):
+
self._need_manifest = True
# update metadata for each successfully written ebuild
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index b9030d2..ca71b81 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -27,6 +27,9 @@ from roverlay import config, util
from roverlay.overlay.category import Category
from roverlay.overlay.header import EbuildHeader
+import roverlay.overlay.additionsdir
+
+
class Overlay ( object ):
DEFAULT_USE_DESC = '\n'.join ( (
'byte-compile - enable byte compiling',
@@ -63,6 +66,7 @@ class Overlay ( object ):
incremental = incremental,
write_allowed = write_allowed,
skip_manifest = skip_manifest,
+ additions_dir = config.get_or_fail ( 'OVERLAY.additions_dir' ),
runtime_incremental = runtime_incremental,
)
# --- end of new_configured (...) ---
@@ -78,7 +82,8 @@ class Overlay ( object ):
write_allowed,
incremental,
skip_manifest,
- runtime_incremental=False,
+ additions_dir,
+ runtime_incremental=False
):
"""Initializes an overlay.
@@ -98,6 +103,11 @@ class Overlay ( object ):
* skip_manifest -- skip Manifest generation to save time
!!! The created overlay cannot be used with
emerge/portage
+ * additions_dir -- path to a directory that contains additional
+ files, e.g. hand-written ebuilds and ebuild
+ patches. The directory has to exist (it will
+ be checked here).
+ A value of None or "" disables additions.
* runtime_incremental -- see package.py:PackageDir.__init__ (...),
Defaults to False (saves memory but costs time)
@@ -120,6 +130,14 @@ class Overlay ( object ):
self.skip_manifest = skip_manifest
+ if additions_dir:
+ if os.path.isdir ( additions_dir ):
+ self.additions_dirpath = os.path.abspath ( additions_dir )
+ else:
+ raise ValueError (
+ "additions dir {} does not exist!".format ( additions_dir )
+ )
+
# calculating eclass names twice,
# once here and another time when calling _init_overlay
self._header.set_eclasses ( frozenset (
@@ -463,12 +481,17 @@ class Overlay ( object ):
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 ),
cautious = True,
- write_manifest = not self.skip_manifest
+ write_manifest = not self.skip_manifest,
+ additions_dir = additions_dir.get_obj_subdir ( cat ),
)
else:
# FIXME debug print
diff --git a/roverlay/tools/__init__.py b/roverlay/tools/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/roverlay/tools/patch.py b/roverlay/tools/patch.py
new file mode 100644
index 0000000..119ff80
--- /dev/null
+++ b/roverlay/tools/patch.py
@@ -0,0 +1,45 @@
+# R overlay -- tools, run patch(1)
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+import subprocess
+
+import roverlay.config
+import roverlay.strutil
+import roverlay.util
+
+_PATCHENV = roverlay.util.keepenv (
+ ( 'PATH', '' ), 'LANG', 'LC_ALL', 'PWD', 'TMPDIR'
+)
+
+# NOTE:
+# this module has to be loaded after reading roverlay's config
+#
+
+_PATCHOPTS = (
+ ( roverlay.config.get_or_fail ( "TOOLS.PATCH.exe" ), )
+ + roverlay.config.get_or_fail ( "TOOLS.PATCH.opts" )
+)
+
+def dopatch ( filepath, patch, logger ):
+ print ( "RUN PATCH", filepath, patch )
+ patch_call = subprocess.Popen (
+ _PATCHOPTS + (
+ filepath, patch
+ ),
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=_PATCHENV,
+ )
+
+ output = patch_call.communicate()
+
+ # log stderr
+ for line in roverlay.strutil.pipe_lines ( output [1], use_filter=True ):
+ logger.warning ( line )
+
+ return patch_call.returncode
+# --- end of dopatch (...) ---
^ 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/overlay/pkgdir/manifest/, roverlay/tools/, roverlay/config/, roverlay/, André Erdmann
2013-06-06 21:15 ` [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