commit:     1111e063d87554087526b3f6ef43612125db9bfb
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Mar 31 15:44:49 2014 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Mar 31 15:44:49 2014 +0000
URL:        
http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1111e063

let's run on debian #1: roverlay-setup

This commit adds basic support for target-specific setup
via the "--target-type <type>" switch.

So far this affects config file creation only and there are 2 choices:

* "gentoo": have portage and a PORTDIR
* "foreign" a.k.a. "not gentoo": neither portage nor PORTDIR available

---
 roverlay/config/defconfig.py    |  66 ++++++++++++------
 roverlay/setupscript/runtime.py | 148 ++++++++++++++++++++++++++++------------
 roverlay/static/targetenv.py    |  51 ++++++++++++++
 3 files changed, 204 insertions(+), 61 deletions(-)

diff --git a/roverlay/config/defconfig.py b/roverlay/config/defconfig.py
index 4bff289..383bb96 100644
--- a/roverlay/config/defconfig.py
+++ b/roverlay/config/defconfig.py
@@ -148,7 +148,7 @@ class ConfigOption ( object ):
 class RoverlayConfigCreation ( object ):
 
    def __init__ ( self,
-      is_installed,
+      is_installed, target_type,
       work_root     = '~/roverlay',
       data_root     = '/usr/share/roverlay',
       conf_root     = '/etc/roverlay',
@@ -167,7 +167,7 @@ class RoverlayConfigCreation ( object ):
       self._ctree            = tree.ConfigTree()
       self._cloader          = self._ctree.get_loader()
       self._verify_value     = self._cloader._make_and_verify_value
-      self.reset ( is_installed=is_installed )
+      self.reset ( is_installed=is_installed, target_type=target_type )
    # --- end of __init__ (...) ---
 
    def iter_options ( self ):
@@ -189,6 +189,8 @@ class RoverlayConfigCreation ( object ):
                   svalue = self.get_datadir ( value[2:] )
                elif v == 'c':
                   svalue = self.get_confdir ( value[2:] )
+               elif v == 'a':
+                  svalue = self.get_additions_dir ( value[2:] )
                else:
                   svalue = value
             else:
@@ -215,7 +217,7 @@ class RoverlayConfigCreation ( object ):
       else:
          raise ConfigOptionMissing ( key )
 
-   def reset ( self, is_installed ):
+   def reset ( self, is_installed, target_type ):
       workdir       = self.get_workdir
       datadir       = self.get_datadir
       confdir       = self.get_confdir
@@ -223,15 +225,21 @@ class RoverlayConfigCreation ( object ):
 
       cachedir = _fspath_prefix_func ( self.work_root, 'cache' )
 
+      _NULLCONF = lambda *a, **b: None
+      _GET_A    = lambda a, b: a
+      _GET_B    = lambda a, b: b
+      _T_TRUE   = ( ConfigOption, _NULLCONF,    _GET_A )
+      _T_FALSE  = ( _NULLCONF,    ConfigOption, _GET_B )
+      _get_setup_triple = lambda cond: ( _T_TRUE if cond else _T_FALSE )
 
-      UNLESS_INSTALLED = lambda *a, **b: (
-         None if is_installed else ConfigOption ( *a, **b )
+      IF_INSTALLED, UNLESS_INSTALLED, get_inst_val = (
+         _get_setup_triple ( is_installed )
       )
-      IF_INSTALLED = lambda *a, **b: (
-         ConfigOption ( *a, **b ) if is_installed else None
+      IF_PORTDIR, UNLESS_PORTDIR,  get_portdir_val = (
+         _get_setup_triple ( target_type.portdir )
       )
-      get_val = lambda v_inst, v_standalone: (
-         v_inst if is_installed else v_standalone
+      IF_PORTAGE, UNLESS_PORTAGE, get_portage_val = (
+         _get_setup_triple ( target_type.has_portage )
       )
 
 
@@ -250,27 +258,35 @@ class RoverlayConfigCreation ( object ):
             use_default_desc=False
          ),
          ConfigOption ( 'CACHEDIR', cachedir() ),
-         ConfigOption (
-            'PORTDIR', '/usr/portage', use_default_desc=False,
+         IF_PORTDIR (
+            'PORTDIR', target_type.portdir, use_default_desc=False,
             description=(
                "portage directory",
                " used to scan for valid licenses",
             ),
          ),
+         UNLESS_PORTAGE (
+            'EBUILD_PROG', '/usr/bin/ebuild',
+            comment_default=True, required=False, recommended=None,
+            description=(
+               ' optional, but required for importing hand-written ebuilds'
+               ' and MANIFEST_IMPLEMENTATION=ebuild (see below)'
+            ),
+         ),
          '',
          '# --- Logging Configuration (optional) ---',
          '',
          ConfigOption (
-            'LOG_LEVEL', get_val ( 'WARNING', 'INFO' ), required=False,
+            'LOG_LEVEL', get_inst_val ( 'WARNING', 'INFO' ), required=False,
             comment_default=is_installed,
          ),
          ConfigOption (
-            'LOG_LEVEL_CONSOLE', get_val ( 'INFO', 'WARNING' ),
+            'LOG_LEVEL_CONSOLE', get_inst_val ( 'INFO', 'WARNING' ),
             required=False, comment_default=is_installed,
             use_default_desc=False, append_newline=False,
          ),
          ConfigOption (
-            'LOG_LEVEL_FILE', get_val ( 'ERROR', 'WARNING' ),
+            'LOG_LEVEL_FILE', get_inst_val ( 'ERROR', 'WARNING' ),
             required=False, comment_default=is_installed,
             use_default_desc=False, append_newline=False,
          ),
@@ -350,7 +366,10 @@ class RoverlayConfigCreation ( object ):
          ConfigOption (
             'OVERLAY_CATEGORY', 'sci-R', defaults_to=True,
             comment_default=True, required=False, use_default_desc=False,
-            description="default category for created ebuilds",
+            description=(
+               "default category for created ebuilds",
+               " (usually overridden by package rules)"
+            )
          ),
          ConfigOption (
             'REPO_CONFIG', confdir ( 'repo.list' ),
@@ -389,24 +408,33 @@ class RoverlayConfigCreation ( object ):
          ),
          ConfigOption (
             'USE_PORTAGE_LICENSES', 'no', required=False,
-            comment_default=True, defaults_to="yes"
+            comment_default=target_type.portdir, defaults_to="yes"
+         ),
+         UNLESS_PORTDIR (
+            'LICENSES_FILE', datadir ( 'licenses' ), required=True,
+            use_default_desc=False, defaults_to="<CACHEDIR>/licenses",
+            description=(
+               "file that lists all known licenses (one per line)"
+            ),
          ),
          ConfigOption (
             'CREATE_LICENSES_FILE', 'no', required=False,
-            comment_default=True, defaults_to="yes"
+            comment_default=target_type.portdir, defaults_to="yes"
          ),
          ConfigOption (
             'NOSYNC', 'yes', required=False, comment_default=True,
             defaults_to="no",
          ),
          ConfigOption (
-            'MANIFEST_IMPLEMENTATION', "ebuild", required=False,
+            'MANIFEST_IMPLEMENTATION', 'ebuild', required=False,
             use_default_desc=False, comment_default=True, defaults_to="next",
             description=(
                "Manifest file creation",
                ' Available choices are \'next\' (internal, fast)',
                ' and \'ebuild\' (using ebuild(1), slow, but failsafe).',
-            ),
+            ) + get_portage_val (
+               (), ( ' *** \'ebuild\' needs a valid EBUILD_PROG ***', )
+            )
          ),
       ]
 

diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 2afbc9f..afe9daa 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -17,10 +17,12 @@ import roverlay.fsutil
 import roverlay.runtime
 
 import roverlay.config.defconfig
+import roverlay.config.entryutil
 
 import roverlay.setupscript.initenv
 import roverlay.setupscript.hookenv
 
+import roverlay.static.targetenv
 
 
 if sys.hexversion >= 0x3000000:
@@ -29,6 +31,12 @@ else:
    read_user_input = raw_input
 
 
+CONFIG_FS_OPTIONS = frozenset (
+   k for k, v in roverlay.config.entryutil.iter_entries_with_value_type (
+      { 'fs_path', 'fs_abs', 'fs_dir', 'fs_file', }
+   )
+)
+
 
 def setup_main_installed():
    return setup_main ( True )
@@ -117,6 +125,25 @@ class SetupArgumentParser ( 
roverlay.argparser.RoverlayArgumentParser ):
       arg = self.setup_setup_minimal ( title='common options' )
 
       arg (
+         '--target-type',
+         dest    = "target_type",
+         default = roverlay.static.targetenv.DEFAULT_TARGET,
+         metavar = "<type>",
+         choices = roverlay.static.targetenv.TARGET_INFO,
+         flags   = self.ARG_WITH_DEFAULT,
+         help    = (
+            'set the environment in which roverlay will be run'
+            ' (choose from %(choices)s)'
+         )
+      )
+
+      arg (
+         '--foreign', '--not-gentoo', dest="target_type",
+         flags=self.ARG_SHARED, action="store_const", const="foreign",
+         help="set target environment to \'foreign\'"
+      )
+
+      arg (
          '--output', '-O', metavar="<file|dir|->", dest='output',
          default='-', type=arg_stdout_or_fs,
          flags=self.ARG_WITH_DEFAULT,
@@ -348,6 +375,7 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
       self.additions_dir      = None
       self.hook_overwrite     = None
 
+      self.target_type        = None
 
 # not used
 #      COLUMNS = os.environ.get ( 'COLUMNS', 78 ) # should use termios/...
@@ -359,9 +387,14 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
    # --- end of __init__ (...) ---
 
    def get_parser_defaults ( self ):
+      defaults = {}
+
+      if 'ROVERLAY_TARGET_TYPE' in os.environ:
+         defaults ['target_type'] = os.environ ['ROVERLAY_TARGET_TYPE']
+
       if self.is_installed():
          instinfo = self.INSTALLINFO
-         return {
+         defaults.update ({
             'work_root'         : instinfo ['workroot'],
             'data_root'         : instinfo ['libexec'],
             'conf_root'         : instinfo ['confroot'],
@@ -369,11 +402,11 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
             'import_config'     : 'symlink=root',
             'additions_dir'     : instinfo ['workroot'] + os.sep + 'files',
             'hook_relpath'      : False,
-         }
+         })
       else:
          assert self.prjroot
          prjroot = self.prjroot + os.sep
-         return {
+         defaults.update ({
             'work_root'         : prjroot + 'workdir',
             'data_root'         : prjroot + 'files',
             'conf_root'         : prjroot + 'config',
@@ -381,7 +414,10 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
             'import_config'     : 'disable',
             'additions_dir'     : prjroot + 'files',
             'hook_relpath'      : True,
-         }
+         })
+      # -- end if
+
+      return defaults
    # --- end of get_parser_defaults (...) ---
 
    def create_argparser ( self ):
@@ -425,53 +461,66 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
       )
    # --- end of create_new_target_config (...) ---
 
-   def _expanduser_pwd ( self, fspath ):
-      return roverlay.fsutil.pwd_expanduser (
-         fspath, self.options ['target_uid']
-      )
+   def _expanduser_pwd ( self, fspath,
+      _expand=roverlay.fsutil.pwd_expanduser
+    ):
+      return _expand ( fspath, self.options ['target_uid'] )
    # --- end of _expanduser_pwd (...) ---
 
    def create_config_file ( self, expand_user=False ):
-      def _get_prjroot_relpath ( fspath ):
-         p = os.path.relpath ( fspath, self.prjroot )
-         if p and ( p[0] != '.' or p == '.' ):
-            return p
-         else:
-            return fspath
-      # --- end of get_prjroot_relpath (...) ---
+      _IDENT      = lambda x: x
+      _FS_OPTIONS = CONFIG_FS_OPTIONS
 
-      get_prjroot_relpath = (
-         _get_prjroot_relpath
-            if ( self.options ['prjroot_relpath'] and self.prjroot )
-         else (lambda p: p)
-      )
+      def _unexpand ( fspath,
+         _unexpanduser_pwd = roverlay.fsutil.pwd_unexpanduser,
+         _target_uid       = self.options ['target_uid']
+      ):
+         return _unexpanduser_pwd ( fspath, _target_uid )
+      # --- end of _unexpand (...) ---
+
+      def _get_prjroot_relpath ( fspath,
+         _relpath=os.path.relpath, _prjroot=self.prjroot
+      ):
+         p = _relpath ( fspath, _prjroot )
+         return p if ( p and ( p[0] != '.' or p == '.' ) ) else fspath
+      # --- end of _get_prjroot_relpath (...) ---
+
+      def var_iter ( cmdline_vars ):
+         for kv in cmdline_vars:
+            key, sepa, value = kv.partition ( '=' )
+            if key and sepa:
+               yield ( key, value )
+            else:
+               raise ValueError ( "bad variable given: {!r}".format ( kv ) )
+      # --- end of var_iter (...) ---
+
+      if self.options ['prjroot_relpath'] and self.prjroot:
+         get_config_fspath = _get_prjroot_relpath
+      elif expand_user:
+         get_config_fspath = _IDENT
+      else:
+         get_config_fspath = _unexpand
 
       conf_creator = roverlay.config.defconfig.RoverlayConfigCreation (
          is_installed  = self.is_installed(),
-         work_root     = get_prjroot_relpath (
-            self.work_root if expand_user else self.options ['work_root']
-         ),
-         data_root     = get_prjroot_relpath (
-            self.data_root if expand_user else self.options ['data_root']
-         ),
-         conf_root     = get_prjroot_relpath (
-            self.user_conf_root if expand_user
-            else self.options ['private_conf_root']
-         ),
-         additions_dir = get_prjroot_relpath (
-            self.additions_dir if expand_user
-            else self.options ['additions_dir']
-         )
+         target_type   = self.target_type,
+         work_root     = get_config_fspath ( self.work_root ),
+         data_root     = get_config_fspath ( self.data_root ),
+         conf_root     = get_config_fspath ( self.user_conf_root ),
+         additions_dir = get_config_fspath ( self.additions_dir ),
       )
+      set_option = conf_creator.set_option
 
-      for kv in self.options ['config_vars']:
-         key, sepa, value = kv.partition ( '=' )
-         if not sepa:
-            raise Exception ( "bad variable given: {!r}".format ( kv ) )
-         elif key in { 'ADDITIONS_DIR', 'OVERLAY_ADDITIONS_DIR', }:
-            conf_creator.set_option ( key, get_prjroot_relpath ( value ) )
-         else:
-            conf_creator.set_option ( key, value )
+      if get_config_fspath is _IDENT:
+         for key, value in var_iter ( self.options ['config_vars'] ):
+            set_option ( key, value )
+      else:
+         for key, value in var_iter ( self.options ['config_vars'] ):
+            if key.lower() in _FS_OPTIONS:
+               set_option ( key, get_config_fspath ( value ) )
+            else:
+               set_option ( key, value )
+      # -- end if
 
       return conf_creator.get_str()
    # --- end of create_config_file (...) ---
@@ -523,6 +572,21 @@ class SetupEnvironment ( 
roverlay.runtime.IndependentRuntimeEnvironment ):
          )
       )
 
+      target_type_str = options ['target_type']
+      try:
+         self.target_type = (
+            roverlay.static.targetenv.TARGET_INFO [target_type_str]
+         )
+      except KeyError:
+         sys.stderr.write (
+            "invalid $ROVERLAY_TARGET_TYPE/--target-type: {!r}\n".format (
+               target_type_str
+            )
+         )
+         sys.exit ( os.EX_USAGE )
+      # -- end try
+      del target_type_str
+
       self.fs_private_virtual = roverlay.fsutil.VirtualFsOperations (
          uid=target_uid, gid=target_gid,
          file_mode=self.PRIVATE_FILE_MODE, dir_mode=self.PRIVATE_DIR_MODE

diff --git a/roverlay/static/targetenv.py b/roverlay/static/targetenv.py
new file mode 100644
index 0000000..330c8ee
--- /dev/null
+++ b/roverlay/static/targetenv.py
@@ -0,0 +1,51 @@
+# R overlay --
+# -*- coding: utf-8 -*-
+# Copyright (C) 2014 André Erdmann <d...@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 collections
+
+
+# *** FIXME: doc ***
+# gentoo means:
+# * have PORTDIR
+# * have ebuild(1) from portage
+# and foreign -- "not gentoo":
+# * don't use PORTDIR
+# * don't use portage
+# * use a hardcoded licenses file
+# ...
+#
+
+DEFAULT_TARGET = "gentoo"
+
+# dict: env_name(str) => defaults(TargetInfo)
+TARGET_INFO = collections.OrderedDict()
+
+#TargetInfo = collections.namedtuple ( 'TargetInfo', 'name has_portage 
portdir' )
+class TargetInfo ( object ):
+   __instances = dict()
+
+   @classmethod
+   def get_instance ( cls, *args ):
+      obj = cls.__instances.get ( args, None )
+      if obj is None:
+         obj = cls ( *args )
+         cls.__instances [args] = obj
+      return obj
+
+   def __init__ ( self, name, has_portage, portdir ):
+      super ( TargetInfo, self ).__init__()
+      self.name        = name
+      self.has_portage = has_portage
+      self.portdir     = portdir
+# --- end of TargetInfo ---
+
+def add_entry ( name, *args ):
+   TARGET_INFO [name] = TargetInfo.get_instance ( name, *args )
+# --- end of add_entry (...) ---
+
+
+add_entry ( 'gentoo',  True, "/usr/portage" )
+add_entry ( 'foreign', False, False )

Reply via email to