* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2014-04-01 16:38 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2014-04-01 16:38 UTC (permalink / raw
To: gentoo-commits
commit: 9402ffb0190bed041670f725d477603c247febad
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Mar 31 17:15:00 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Apr 1 16:36:30 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9402ffb0
setupscript, arg parser: add ROVERLAY_TARGET_TYPE
... to epilog
---
roverlay/setupscript/runtime.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index afe9daa..b9b7ed0 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -426,8 +426,10 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
defaults = self.get_parser_defaults(),
epilog = (
'Environment variables:\n'
- '* ROVERLAY_PRJROOT - path to roverlay\'s source dir\n'
- '* ROVERLAY_INSTALLED - mark roverlay as installed (if set and not empty)\n'
+ '* ROVERLAY_PRJROOT - path to roverlay\'s source dir\n'
+ '* ROVERLAY_INSTALLED - mark roverlay as installed\n'
+ ' (if set and not \'0\', \'no\', \'n\' \'false\')\n'
+ '* ROVERLAY_TARGET_TYPE - set target environment type\n'
)
)
# --- end of create_argparser (...) ---
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2014-02-22 14:56 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2014-02-22 14:56 UTC (permalink / raw
To: gentoo-commits
commit: 1a8328b48d7918107cffa391096ec0cdfa8d9212
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Feb 21 18:32:11 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Feb 21 18:32:11 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1a8328b4
roverlay/setupscript/runtime: minor cleanup
---
roverlay/setupscript/runtime.py | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 0f4294d..2afbc9f 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -330,21 +330,27 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
def __init__ ( self, *args, **kwargs ):
super ( SetupEnvironment, self ).__init__ ( *args, **kwargs )
- self.UID = os.getuid()
- self.GID = os.getgid()
+ self.UID = os.getuid()
+ self.GID = os.getgid()
- self.expanduser = None
- self.fs_ops = None
- self.fs_ops_virtual = None
+ # filesystem-related functions
+ self.expanduser = None
+ self.fs_private_virtual = None
+ self.fs_private = None
+ self.fs_shared_virtual = None
+ self.fs_shared = None
+
+ self.want_chown = None
+ self.data_root = None
+ self.work_root = None
+ self.conf_root = None
+ self.user_conf_root = None
+ self.additions_dir = None
+ self.hook_overwrite = None
- self.want_chown = None
- self.data_root = None
- self.work_root = None
- self.conf_root = None
- self.user_conf_root = None
# not used
-# COLUMNS = os.environ.get ( 'COLUMNS', 78 )
+# COLUMNS = os.environ.get ( 'COLUMNS', 78 ) # should use termios/...
#
# self.text_wrapper = textwrap.TextWrapper (
# width=COLUMNS, initial_indent='', subsequent_indent='',
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2014-02-21 17:36 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2014-02-21 17:36 UTC (permalink / raw
To: gentoo-commits
commit: 796c1d77dafadccc44e028d91366228502af4416
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Feb 20 21:20:28 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Feb 20 21:20:28 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=796c1d77
roverlay-setup, config import: minor improvement
fs_ops.unlink() always succeeds in --pretend mode (no-op), so "roverlay-setup
--pretend" gives misleading output when user_config_root==config_root.
=> do not reset user_conf_root in --pretend mode if it isn't a symlink.
---
roverlay/setupscript/initenv.py | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/roverlay/setupscript/initenv.py b/roverlay/setupscript/initenv.py
index 58677e1..ef06436 100644
--- a/roverlay/setupscript/initenv.py
+++ b/roverlay/setupscript/initenv.py
@@ -186,15 +186,11 @@ class SetupInitEnvironment (
# assert os.path.isdir ( os.path.dirname(user_conf_root) == work_root )
if user_conf_root is None and (
- fs_ops.unlink ( setup_env.user_conf_root )
+ not pretend or os.path.islink ( setup_env.user_conf_root )
):
- # config_root was a symlink
-
- if pretend:
- user_conf_root = setup_env.user_conf_root
- else:
+ if fs_ops.unlink ( setup_env.user_conf_root ):
+ # user_conf_root was a symlink
user_conf_root = setup_env.get_user_config_root()
-
# -- end if
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2014-02-17 17:22 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2014-02-17 17:22 UTC (permalink / raw
To: gentoo-commits
commit: 5af9d454a5da4eac702857ea392e6725e6cdd013
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Feb 17 17:21:48 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Feb 17 17:21:48 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=5af9d454
roverlay-setup, init: fix config file location (#2)
+ handle standalone versions of roverlay
---
roverlay/setupscript/runtime.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 5aab1d8..0f4294d 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -406,10 +406,11 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
# --- end of get_user_config_root (...) ---
def get_config_file_path ( self ):
- return (
- self._get_config_roots()[1]
- + os.sep + self.access_constant ( 'config_file_name' )
- )
+ cname = self.access_constant ( 'config_file_name' )
+ if self.is_installed():
+ return self._get_config_roots()[1] + os.sep + cname
+ else:
+ return self.prjroot + os.sep + cname
# --- end of get_config_file_path (...) ---
def create_new_target_config ( self ):
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2014-02-17 17:10 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2014-02-17 17:10 UTC (permalink / raw
To: gentoo-commits
commit: a6bc40c39930cbaf419e7440a6d478954d49fd16
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Feb 17 17:09:38 2014 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Feb 17 17:09:38 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a6bc40c3
roverlay-setup, init: fix config file location
Write R-overlay.conf to user_conf_root (or conf_root), not work_root.
---
roverlay/setupscript/runtime.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 56b2a8b..5aab1d8 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -407,7 +407,8 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
def get_config_file_path ( self ):
return (
- self.work_root + os.sep + self.access_constant ( 'config_file_name' )
+ self._get_config_roots()[1]
+ + os.sep + self.access_constant ( 'config_file_name' )
)
# --- end of get_config_file_path (...) ---
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-19 15:00 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-19 15:00 UTC (permalink / raw
To: gentoo-commits
commit: daefc87c578f6b8a4b7bd903c40a1d84adbead37
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 19 15:00:03 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 19 15:00:03 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=daefc87c
roverlay/setupscript/hookenv: comments, cleanup
---
roverlay/setupscript/hookenv.py | 544 +++++++++++++++++++++++++++++++++-------
1 file changed, 453 insertions(+), 91 deletions(-)
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index d361801..212d041 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -19,6 +19,9 @@ import roverlay.setupscript.baseenv
class HookOverwriteControl ( object ):
+ """Object for deciding whether a file/link/... is allowed to be
+ overwritten by a hook link."""
+
OV_NONE = 0
OV_SYM_DEAD = 2**0
OV_SYM_EXIST = 2**1
@@ -35,16 +38,37 @@ class HookOverwriteControl ( object ):
@classmethod
def from_str ( cls, vstr ):
+ """Returns a new instance representing one of the control modes from
+ OV_KEYWORDS.
+
+ arguments:
+ * vstr --
+ """
return cls ( cls.OV_KEYWORDS[vstr] )
# --- end of from_str (...) ---
def __init__ ( self, value ):
+ """HookOverwriteControl constructor.
+
+ arguments:
+ * value -- the control mode (has to be an int, usually a comibination of
+ the OV_* masks provided by the HookOverwriteControl class)
+ """
super ( HookOverwriteControl, self ).__init__()
assert isinstance ( value, int ) and value >= 0
self.value = value
# --- end of __init__ (...) ---
def can_overwrite ( self, mask=None ):
+ """Returns whether the control mode allows to overwrite files/links
+ with the given mask.
+
+ The return value should be interpreted in boolean context, but can
+ be an int.
+
+ arguments:
+ * mask --
+ """
if mask is None:
return self.value == self.OV_NONE
else:
@@ -52,15 +76,21 @@ class HookOverwriteControl ( object ):
# --- end of can_overwrite (...) ---
def overwrite_dead_symlinks ( self ):
+ """Returns whether overwriting of dangling/broken symlinks is allowed."""
return self.value & self.OV_SYM_DEAD
def overwrite_symlinks ( self ):
+ """Returns whether overwriting of arbitrary symlinks is allowed."""
return self.value & self.OV_SYM
def overwrite_all ( self ):
+ """Returns True if the control mode does not restrict overwriting,
+ else False."""
return self.value == self.OV_ALL
def get_str ( self ):
+ """Returns a string representation of the control mode suitable for
+ printing."""
value = self.value
def gen_words():
if value == self.OV_NONE:
@@ -87,6 +117,7 @@ class HookOverwriteControl ( object ):
class HookScriptBase ( roverlay.util.objects.Referenceable ):
+ """A hook script."""
CACHE_REF = True
@@ -99,7 +130,9 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
* fspath -- absolute path to the hook script
* filename -- name of the hook script
Defaults to os.path.basename(fspath).
- * priority -- priority of the hook script. Defaults to auto-detect.
+ * priority -- priority of the hook script.
+ Defaults to None (no priority).
+ Passing True as priority enables filename-based detection.
* is_hidden -- whether the script is "hidden" or not. Defaults to False.
"""
super ( HookScriptBase, self ).__init__()
@@ -132,11 +165,12 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
def __str__ ( self ):
yesno = lambda k: 'y' if k else 'n'
+
return "<{cls} {name!r}, hidden={h} prio={p}>".format (
- cls=self.__class__.__name__,
- name=self.name,
- h=yesno ( self.is_hidden ),
- p=(
+ cls = self.__class__.__name__,
+ name = self.name,
+ h = yesno ( self.is_hidden ),
+ p = (
"auto" if self.priority is None else
( "IGNORE" if self.priority < 0 else self.priority )
),
@@ -144,66 +178,46 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
# --- end of __str__ (...) ---
def has_priority ( self ):
+ """Returns True if this hook script has a valid priority."""
return self.priority is not None and self.priority >= 0
# --- end of has_priority (...) ---
- def set_priority ( self, priority, only_if_unset=True ):
- if self.priority is None:
- self.priority = priority
- elif self.priority < 0:
- raise Exception (
- "cannot assign priority to script with priority < 0."
- )
- elif not only_if_unset:
- self.priority = priority
- # --- end of set_priority (...) ---
-
- def get_static_info ( self ):
- return roverlay.static.hookinfo.get ( self.name, None )
- # --- end of get_static_info (...) ---
-
def is_visible ( self ):
+ """Returns True if this hook script can be used for linking/...,
+ else False."""
return not self.is_hidden and (
self.priority is None or self.priority >= 0
)
# --- end of is_visible (...) ---
- @roverlay.util.objects.abstractmethod
- def get_hookscript ( self ):
- pass
- # --- end of get_hookscript (...) ---
-
- @roverlay.util.objects.abstractmethod
- def get_hookscript_path ( self ):
- pass
- # --- end of get_hookscript_path (...) ---
-
- def get_dest_name ( self, file_ext='.sh', digit_len=2 ):
- # file_ext has to be .sh, else the script doesn't get recognized
- # by mux.sh
-
- prio = self.priority
- if prio is not None:
- if prio < 0:
- raise AssertionError ( "hook script has no priority." )
-
- return "{prio:0>{l}d}-{fname}{f_ext}".format (
- prio=prio, fname=self.name, f_ext=file_ext, l=digit_len,
- )
- else:
- return self.filename
- # --- end of get_dest_name (...) ---
-
# --- end of HookScriptBase ---
class UserHookScript ( HookScriptBase ):
+ """A hook script that resides in the user's hook script dir."""
@classmethod
def create_for_hook (
cls, hook, destdir, event_name, priority_gen,
file_ext='.sh', digit_len=2
):
+ """Creates a UserHookScript instance that can be used for linking
+ a HookScript in the given directory.
+
+ arguments:
+ * hook -- HookScript object
+ * destdir -- directory where the link to the HookScript will be
+ created
+ * event_name -- name of the event (usually basename of destdir)
+ * priority_gen -- priority generator (or an int) which will be used
+ if the HookScript object doesn't provide a priority
+ * file_ext -- file extension of the link name. Defautls to '.sh',
+ which shouldn't be changed, because the "mux.sh"
+ script recognizes file with this extension only.
+ * digit_len -- digit length of the priority part of the file name.
+ ("d^{>=digit_len}-{hook name}{file_ext}")
+ Defaults to 2.
+ """
if type ( priority_gen ) == int:
prio = priority_gen
elif hook.has_priority():
@@ -227,6 +241,17 @@ class UserHookScript ( HookScriptBase ):
# --- end of create_for_hook (...) ---
def __init__ ( self, fspath, filename=None, event=None, priority=True ):
+ """UserHookScript constructor.
+
+ arguments:
+ * fspath -- absolute path to the hook script
+ * filename -- name of the hook script
+ Defaults to os.path.basename(fspath).
+ * event -- name of the event to which this script belongs to,
+ e.g. "overlay_success" (or None). Defaults to None.
+ * priority -- priority of the hook script.
+ Defaults to True (auto-detect).
+ """
super ( UserHookScript, self ).__init__ (
fspath, filename=filename, priority=priority
)
@@ -237,12 +262,21 @@ class UserHookScript ( HookScriptBase ):
):
self.hook_script_ref = None
else:
+ # False means that this UserHookScript is not a link
self.hook_script_ref = False
self.event = event
# --- end of __init__ (...) ---
def set_hookscript ( self, script_obj, strict=True ):
+ """Assigns a HookScript to this UserHookScript. Also establishes
+ a back-reference in the hook script.
+
+ arguments:
+ * script_obj -- HookScript object
+ * strict -- whether to fail if this UserHookScript is not a link
+ (True) or not (False). Defaults to True.
+ """
if strict and script_obj and self.hook_script_ref is False:
raise Exception (
"user hook script {} is not a link!".format ( self.fspath )
@@ -256,13 +290,26 @@ class UserHookScript ( HookScriptBase ):
# --- end of set_hookscript (...) ---
def has_hookscript ( self ):
+ """Returns whether this object has a hook script of any kind (either
+ a HookScript object or a file)."""
return self.hook_script_ref is not None
# --- end of has_hookscript (...) ---
- def get_hookscript ( self ):
+ def get_hookscript ( self, unsafe=False ):
+ """Returns the HookScript object to which this instance belongs to.
+ Returns None if this UserHookScript is not a link.
+
+ arguments:
+ * unsafe -- do not raise ObjectDisappeared if not linked or hook script
+ disappeared and return None instead.
+
+ Raises: roverlay.util.objects.ObjectDisappeared
+ """
ref = self.hook_script_ref
if ref is False:
return None
+ elif unsafe:
+ return None if ref is None else ref.deref_unsafe()
elif ref is None:
raise roverlay.util.objects.ObjectDisappeared()
else:
@@ -270,10 +317,12 @@ class UserHookScript ( HookScriptBase ):
# --- end of get_hookscript (...) ---
def get_hookscript_path ( self ):
+ """Returns the link target (can be identical to the fspath attribute)."""
return self.hook_script_fspath
# --- end of get_hookscript_path (...) ---
def get_dest_name ( self ):
+ """Returns the link name."""
return self.filename
# --- end of get_dest_name (...) ---
@@ -281,11 +330,20 @@ class UserHookScript ( HookScriptBase ):
class HookScript ( HookScriptBase ):
+ """A hook script that resides in the 'static data' dir."""
def __init__ ( self, fspath, filename=None ):
+ """HookScript constructor.
+ Also looks up static information (hook priority etc.).
+
+ arguments:
+ * fspath -- absolute path to the hook script
+ * filename -- name of the hook script
+ Defaults to os.path.basename(fspath).
+ """
super ( HookScript, self ).__init__ ( fspath, filename=filename )
- static_entry = self.get_static_info()
+ static_entry = roverlay.static.hookinfo.get ( self.name, None )
if static_entry is not None:
self.default_events = static_entry[0]
self.priority = static_entry[1]
@@ -297,50 +355,87 @@ class HookScript ( HookScriptBase ):
# --- end of __init__ (...) ---
def add_user_script ( self, user_script ):
+ """Registers a UserHookScript linking to this object (as reference)."""
self.user_script_refs.add ( user_script.get_ref() )
# --- end of add_user_script (...) ---
- def iter_user_scripts ( self, ignore_missing=True ):
+ def iter_user_scripts ( self, ignore_missing=True, check_backref=True ):
+ """Iterates over all UserHookScripts linked to this object.
+
+ arguments:
+ * ignore_missing -- do not fail if a referenced object disappeared.
+ Defaults to True.
+ * check_backref -- if True: ignore UserHookScripts that do no longer
+ link to this object. Defaults to True.
+ """
if ignore_missing:
+ if check_backref:
+ for ref in self.user_script_refs:
+ obj = ref.deref_unsafe()
+ if (
+ obj is not None and
+ obj.get_hookscript ( unsafe=True ) is self
+ ):
+ yield obj
+ else:
+ for ref in self.user_script_refs:
+ obj = ref.deref_unsafe()
+ if obj is not None:
+ yield obj
+ elif check_backref:
for ref in self.user_script_refs:
- obj = ref.deref_unsafe()
- if obj is not None:
- yield obj
+ obj = obj.deref_safe()
+ if obj.get_hookscript ( unsafe=False ) is self:
+ yield obj.deref_safe()
else:
for ref in self.user_script_refs:
yield obj.deref_safe()
# --- end of iter_user_scripts (...) ---
- def get_hookscript ( self ):
- return self
- # --- end of get_hookscript (...) ---
-
- def get_hookscript_path ( self ):
- return self.fspath
- # --- end of get_hookscript_path (...) ---
-
# --- end of HookScript ---
class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
+ """A directory containing hook scripts."""
HOOK_SCRIPT_CLS = None
DIRNAMES_IGNORE = frozenset({ '.*', })
FILENAMES_IGNORE = frozenset({ '.*', })
def dirname_filter ( self, dirname, _fnmatch=fnmatch.fnmatch ):
+ """Returns True if dirname does not match any pattern in
+ DIRNAMES_IGNORE, else False.
+
+ arguments:
+ * dirname --
+ * _fnmatch -- function for matching dirname against pattern.
+ Defaults to fnmatch.fnmatch.
+ """
return all (
not _fnmatch ( dirname, pat ) for pat in self.DIRNAMES_IGNORE
)
# --- end of dirname_filter (...) ---
def filename_filter ( self, filename, _fnmatch=fnmatch.fnmatch ):
+ """Returns True if dirname does not match any pattern in
+ FILENAMES_IGNORE, else False.
+
+ arguments:
+ * filename --
+ * _fnmatch -- function for matching filename against pattern.
+ Defaults to fnmatch.fnmatch.
+ """
return all (
not _fnmatch ( filename, pat ) for pat in self.FILENAMES_IGNORE
)
# --- end of filename_filter (...) ---
def __init__ ( self, root ):
+ """HookScriptDirBase constructor.
+
+ arguments:
+ * root -- absolute filesystem path to the hook script dir's root dir
+ """
super ( HookScriptDirBase, self ).__init__()
self.root = root
@@ -348,11 +443,18 @@ class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
self.writable = None
# --- end of __init__ (...) ---
- def __bool__ ( self ):
- return bool ( self.scripts )
- # --- end of __bool__ (...) ---
+ def __len__ ( self ):
+ """Returns the number of scripts."""
+ # also used in boolean context
+ return len ( self.scripts )
+ # --- end of __len__ (...) ---
def get_fspath ( self, relpath=None ):
+ """Returns the filesystem path of this dir or of a sub dir/file.
+
+ arguments:
+ * relpath -- sub dir/file path relative to the root. Defaults to None.
+ """
if relpath:
return self.root + os.sep + str ( relpath )
else:
@@ -360,48 +462,100 @@ class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
# --- end of get_fspath (...) ---
def get_script ( self, name ):
+ """Returns the script with the given name.
+ Typically faster than find_by_name(), but less accurate when dealing
+ with user scripts.
+
+ arguments:
+ * name -- script name
+ """
script = self.scripts [name]
- return script if script.is_visible() else None
+ if script.is_visible():
+ return script
+ else:
+ raise KeyError ( name )
# --- end of get_scripts (...) ---
def iter_scripts ( self ):
+ """Generator that yields all visible scripts."""
for script in self.scripts.values():
if script.is_visible():
yield script
# --- end of iter_scripts (...) ---
def find_all ( self, condition, c_args=(), c_kwargs={} ):
+ """Generator that yields all visible scripts for which
+ condition ( script, *c_args, **c_kwargs ) evaluates to True.
+
+ arguments:
+ * condition -- function/callable
+ * c_args -- packed args for condition. Defaults to ().
+ * c_kwargs -- packed keyword args for condition. Defaults to {}.
+ """
for script in self.iter_scripts():
if condition ( script, *c_args, **c_kwargs ):
yield script
# --- end of find_all (...) ---
def find ( self, condition, c_args=(), c_kwargs={}, **kw ):
+ """Like find_all(), but returns the first match, if any, else None.
+
+ arguments:
+ * condition -- function/callable
+ * c_args -- packed args for condition. Defaults to ().
+ * c_kwargs -- packed keyword args for condition. Defaults to {}.
+ * **kw -- additional keyword args for find_all().
+ """
try:
return next ( self.find_all ( condition, c_args, c_kwargs, **kw ) )
except StopIteration:
return None
# --- end of find (...) ---
- def find_by_name ( self, name, **kw ):
- return self.find (
- lambda s, n: s.name == n, c_args=( name, ), **kw
- )
- # --- end of find_all_by_name (...) ---
-
def find_all_by_name ( self, name, **kw ):
+ """Generator that yields all visible scripts whose names matches the
+ given one.
+
+ arguments:
+ * name --
+ * **kw -- additional keyword args for find_all()
+ """
return self.find_all (
lambda s, n: s.name == n, c_args=( name, ), **kw
)
# --- end of find_all_by_name (...) ---
+ def find_by_name ( self, name, **kw ):
+ """Like find_all_by_name(), but returns the first match, if any,
+ else None.
+
+ arguments:
+ * name --
+ * **kw --
+ """
+ try:
+ return next ( self.find_all_by_name ( name, **kw ) )
+ except StopIteration:
+ return None
+ # --- end of find_by_name (...) ---
+
def find_all_by_name_begin ( self, prefix, **kw ):
+ """Generator that yields all visible scripts whose names begin with
+ the given prefix.
+
+ arguments:
+ * prefix --
+ * **kw -- additional keyword args for find_all()
+ """
return self.find_all (
lambda s, pre: s.name.startswith ( pre ), c_args=( prefix, ), **kw
)
# --- end of find_all_by_name_begin (...) ---
def scan ( self ):
+ """Scans the filesystem location of this hook script dir for hook
+ scripts and adds them to the scripts attribute.
+ """
root = self.root
try:
filenames = sorted ( os.listdir ( root ) )
@@ -422,35 +576,97 @@ class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
class NestedHookScriptDirBase ( HookScriptDirBase ):
+ """A hook script dir with a nested structure (hook scripts in subdirs)."""
+
SUBDIR_CLS = collections.OrderedDict
def get_script ( self, name ):
- return [
- script for script in self.iter_scripts() if script.name == name
- ]
- # --- end of get_script (...) ---
+ """Returns a list of all visible scripts with the given name.
- def create_hookscript ( self, fspath, filename, root ):
- return self.HOOK_SCRIPT_CLS ( fspath, filename=filename )
- # --- end of create_hookscript (...) ---
+ arguments:
+ * name --
+ """
+ return list ( self.find_all_by_name ( name ) )
+ # --- end of get_script (...) ---
def scan ( self, prune_empty=True ):
- self.scripts = roverlay.fsutil.get_fs_dict (
- self.root, create_item=self.create_hookscript,
- dict_cls=self.SUBDIR_CLS, dirname_filter=self.dirname_filter,
- filename_filter=self.filename_filter, include_root=False,
- prune_empty=prune_empty,
+ """Scans the hook script dir for hook scripts.
+ Calls scan_scripts() when done.
+
+ arguments:
+ * prune_empty -- whether to keep empty dirs in the scripts dict
+ (False) or not (True). Defaults to True.
+ """
+ def get_script_name ( filename ):
+ """Returns the script name of the given filename.
+
+ arguments:
+ * filename --
+ """
+ prio, sepa, name = filename.partition ( '-' )
+ if name:
+ try:
+ prio_int = int ( prio, 10 )
+ except ValueError:
+ return filename
+ else:
+ return name
+ else:
+ return filename
+ # --- end of get_script_name (...) ---
+
+ def create_hookscript (
+ fspath, filename, root, HOOK_SCRIPT_CLS=self.HOOK_SCRIPT_CLS
+ ):
+ """Creates a new hook script object.
+
+ arguments:
+ * fspath -- absolute path to the script file
+ * filename -- name of the script file
+ * root -- directory of the script file
+ * HOOK_SCRIPT_CLS -- hook script class.
+ Defaults to elf.HOOK_SCRIPT_CLS.
+ """
+ return HOOK_SCRIPT_CLS ( fspath, filename=filename )
+ # --- end of create_hookscript (...) ---
+
+ new_scripts = roverlay.fsutil.get_fs_dict (
+ self.root,
+ create_item = create_hookscript,
+ dict_cls = self.SUBDIR_CLS,
+ dirname_filter = self.dirname_filter,
+ filename_filter = self.filename_filter,
+ include_root = False,
+ prune_empty = prune_empty,
+ file_key = get_script_name,
)
+ self.scripts.update ( new_scripts )
self.scan_scripts()
# --- end of scan (...) ---
def scan_scripts ( self ):
+ """Performs additional actions after scanning scripts, e.g.
+ setting correct event attributes.
+ """
for event, hook in self.iter_scripts():
if hook.event is None:
hook.event = event
# --- end of scan (...) ---
def iter_scripts ( self, event=None, ignore_missing=False ):
+ """Generator that yields all visible script.
+
+ Depending on the event parameter, the items are either
+ 2-tuples(event_name, script) (event is None) or scripts.
+
+ arguments:
+ * event -- specific event to iterator over (or None for all)
+ Defaults to None.
+ * ignore_missing -- do not fail if event subdir is missing.
+ only meaningful if event is not None
+ Defaults to False.
+ """
+
# roverlay uses per-event subdirs containing hook files
SUBDIR_CLS = self.SUBDIR_CLS
@@ -474,6 +690,16 @@ class NestedHookScriptDirBase ( HookScriptDirBase ):
# --- end of iter_scripts (...) ---
def find_all ( self, condition, c_args=(), c_kwargs={}, event=None ):
+ """Generator that yields all scripts matching the given condition.
+ Can optionally be restricted to a single event subdir.
+ See HookScriptDirBase.find_all() for details.
+
+ arguments:
+ * condition --
+ * c_args --
+ * c_kwargs --
+ * event --
+ """
if event is None:
for event_name, script in self.iter_scripts():
if condition ( script, *c_args, **c_kwargs ):
@@ -485,6 +711,11 @@ class NestedHookScriptDirBase ( HookScriptDirBase ):
# --- end of find_all_by_name (...) ---
def get_subdir ( self, event_name ):
+ """Returns the requested event subdir dict (by creating it if necessary)
+
+ arguments:
+ * event_name --
+ """
subdir = self.scripts.get ( event_name, None )
if subdir is None:
subdir = self.SUBDIR_CLS()
@@ -498,10 +729,17 @@ class NestedHookScriptDirBase ( HookScriptDirBase ):
class UserHookScriptDir ( NestedHookScriptDirBase ):
+ """A nested hook script dir that contains UserHookScripts."""
HOOK_SCRIPT_CLS = UserHookScript
def __init__ ( self, *args, **kwargs ):
+ """See HookScriptDirBase.__init__().
+
+ arguments:
+ * *args -- passed to super().__init__()
+ * **kwargs -- passed to super().__init__()
+ """
super ( UserHookScriptDir, self ).__init__ ( *args, **kwargs )
# per-event prio gen
## self._prio_gen = collections.defaultdict (
@@ -511,16 +749,23 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
# --- end of __init__ (...) ---
def _create_new_prio_gen ( self ):
+ """Creates and returns a new priority generator."""
return roverlay.util.counter.SkippingPriorityGenerator (
10, skip=roverlay.static.hookinfo.get_priorities()
)
# --- end of _create_new_prio_gen (...) ---
def _get_prio_gen ( self, event_name ):
+ """Returns a priority generator for the given event.
+
+ arguments:
+ * event_name --
+ """
return self._prio_gen
# --- end of _get_prio_gen (...) ---
def scan_scripts ( self ):
+ """Performs additional actions after scanning the directory."""
prios = collections.defaultdict ( list )
for event, hook in self.iter_scripts():
if hook.event is None:
@@ -536,6 +781,17 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
def create_hookdir_refs ( self,
hook_dir, overwrite=False, compare_fspath=True
):
+ """Establishes links (references) from user scripts to hook scripts
+ in the given hook dir (which usually creates backreferences).
+
+ arguments:
+ * hook_dir -- hook directory (HookScriptDir)
+ * overwrite -- overwrite existing references
+ * compare_fspath -- if True: link only if filesystem paths
+ (link target, script filepath) match
+ else: link if names match
+ Defaults to True.
+ """
for event, user_script in self.iter_scripts():
if overwrite or not user_script.has_hookscript():
try:
@@ -550,6 +806,15 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
# --- end of create_hookdir_refs (...) ---
def make_hookdir_refs ( self, hook_dir, overwrite=False ):
+ """Calls create_hookdir_refs() twice, first with compare_fspath=True,
+ and then with compare_fspath=False, so that exact matches are preferred.
+
+ See create_hookdir_refs() for details.
+
+ arguments:
+ * hook_dir --
+ * overwrite --
+ """
# try exact fs path matches first, then use name-based ones
self.create_hookdir_refs (
hook_dir, overwrite=overwrite, compare_fspath=True
@@ -560,6 +825,11 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
# --- end of make_hookdir_refs (...) ---
def add_entry_unsafe ( self, hook ):
+ """Adds a hook object (UserHookScript) to this script directory.
+
+ arguments:
+ * hook -- hook object (the event attribute has to be set)
+ """
if hook.event:
self.get_subdir ( hook.event ) [hook.name] = hook
else:
@@ -568,6 +838,13 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
# --- end of add_entry_unsafe (...) ---
def get_entry_for_link ( self, hook, event_name ):
+ """Returns a UserHookScript object that can be used to link against
+ the given HookScript object.
+
+ arguments:
+ * hook --
+ * event_name --
+ """
existing_entry = self.find_by_name ( hook.name, event=event_name )
if existing_entry:
return existing_entry
@@ -581,12 +858,6 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
return user_hook
# --- end of get_entry_for_link (...) ---
- def iter_nonlinked ( self ):
- for event, script in self.iter_scripts():
- if not script.has_hookscript():
- yield script
- # --- end of iter_nonlinked (...) ---
-
# --- end of UserHookScriptDir ---
@@ -595,12 +866,24 @@ class HookScriptDir ( HookScriptDirBase ):
HOOK_SCRIPT_CLS = HookScript
def iter_linked ( self ):
- # 2-tuple ( hook_script, list ( linked_user_scripts ) )
+ """Generator that yields
+ 2-tuples ( HookScript, list( UserHookScript references ) ).
+
+ The UserHookScript references list can be empty.
+ """
for script in self.iter_scripts():
yield ( script, list ( script.iter_user_scripts() ) )
# --- end of iter_linked (...) ---
def iter_default_scripts ( self, unpack=False ):
+ """Generator that yields all default scripts.
+
+ Depending on the unpack parameter, the items are either HookScripts
+ (False) or 2-tuples (event, HookScript) (True).
+
+ arguments:
+ * unpack -- defaults to False
+ """
if unpack:
for script in self.iter_scripts():
if script.default_events:
@@ -613,6 +896,9 @@ class HookScriptDir ( HookScriptDirBase ):
# --- end of iter_default_scripts (...) ---
def get_default_scripts ( self ):
+ """
+ Returns a dict containg per-event lists of the default HookScripts.
+ """
return roverlay.util.dictwalk.dictmerge (
self.iter_default_scripts ( unpack=True ),
get_value=lambda kv:kv[1]
@@ -626,12 +912,25 @@ class HookScriptDir ( HookScriptDirBase ):
class SetupHookEnvironment (
roverlay.setupscript.baseenv.SetupSubEnvironment
):
+ """'Environment' for managing hooks."""
NEEDS_CONFIG_TREE = True
def format_hook_info_lines ( self,
info, sort_info=True, append_newline=False
):
+ """Generator that accepts a list of
+ (scripts, list ( event to which script is linked, priority)) and yields
+ formatted text lines "<script name> | <event>(<prio>)..." for each
+ script.
+
+ arguments:
+ * info --
+ * sort_info -- whether to sort info (by "has events",name)
+ Defaults to True.
+ * append_newline -- whether to append a newline at the end
+ Defaults to False.
+ """
max_name_len = min ( 30, max ( len(x[0]) for x in info ) )
event_names = set()
@@ -670,6 +969,14 @@ class SetupHookEnvironment (
# --- end of format_hook_info_lines (...) ---
def get_hook_root_info ( self, nonlinked_only=False ):
+ """Returns a list with information about the hook root suitable
+ for being formatted by format_hook_info_lines().
+
+ arguments:
+ * nonlinked_only -- whether to exclude scripts that are linked to
+ >= 1 event(s) (True) or not (False).
+ Defaults to False.
+ """
if nonlinked_only:
return [
( script.name, [] )
@@ -687,6 +994,9 @@ class SetupHookEnvironment (
# --- end of get_hook_root_info (...) ---
def get_user_hook_info ( self ):
+ """Returns a list with information about the user hook root suitable
+ for being formatted by format_hook_info_lines().
+ """
return [
( s.name, [ ( s.event or "undef", s.priority ) ] )
for event, s in self.user_hooks.iter_scripts()
@@ -694,6 +1004,8 @@ class SetupHookEnvironment (
# --- end of get_user_hook_info (...) ---
def gen_hook_info_lines ( self, append_newline=True ):
+ """Generator that yields (formatted) text lines with information
+ about hooks in the user hook root and the hook root."""
info = (
self.get_user_hook_info()
+ self.get_hook_root_info ( nonlinked_only=True )
@@ -705,7 +1017,7 @@ class SetupHookEnvironment (
# --- end of gen_hook_info_lines (...) ---
def setup ( self ):
-
+ """Performs subclass-specific initialization."""
self.hook_overwrite_control = self.setup_env.hook_overwrite
additions_dir = self.config.get ( 'OVERLAY.additions_dir', None )
@@ -732,6 +1044,15 @@ class SetupHookEnvironment (
# --- end of setup (...) ---
def check_link_allowed ( self, source, link, link_name ):
+ """Returns whether symlinking link->source is allowed.
+ This decision is made based on the fileystem "state" of the link
+ and the HookOverwriteControl object (bound to this instance).
+
+ arguments:
+ * source -- link destination (absolute filesystem path)
+ * link -- link file (absolute filesystem path)
+ * link_name -- file name of the link
+ """
if os.path.lexists ( link ):
allow_overwrite = False
@@ -780,6 +1101,14 @@ class SetupHookEnvironment (
# --- end of check_link_allowed (...) ---
def link_hooks_v ( self, event_name, hooks ):
+ """Links several hooks to the given event.
+
+ Returns True on success, else False.
+
+ arguments:
+ * event_name --
+ * hooks --
+ """
success = False
user_hooks = self.user_hooks
@@ -830,6 +1159,14 @@ class SetupHookEnvironment (
# --- end of link_hooks_v (...) ---
def link_hooks_to_events ( self, hooks, events ):
+ """Links several hooks to several events.
+
+ Returns True on success, else False.
+
+ arguments:
+ * hooks --
+ * events --
+ """
success = True
for event_name in events:
if not self.link_hooks_v ( event_name, hooks ):
@@ -838,6 +1175,15 @@ class SetupHookEnvironment (
# --- end of link_hooks_to_events (...) ---
def unlink_hooks ( self, hooks, symlinks_only=True ):
+ """Removes several hooks.
+
+ Returns: None (implicit)
+
+ arguments:
+ * hooks -- iterable of UserHookScripts
+ * symlinks_only -- if True: remove symlinks only, else remove files
+ else well. Defaults to True.
+ """
unlink = self.setup_env.fs_private.unlink
if not symlinks_only:
@@ -861,6 +1207,7 @@ class SetupHookEnvironment (
# --- end of unlink_hooks (...) ---
def enable_defaults ( self ):
+ """Enables all default hooks."""
# not strict: missing hooks are ignored
success = False
if self.hook_root:
@@ -875,6 +1222,10 @@ class SetupHookEnvironment (
# --- end of enable_defaults (...) ---
def run ( self ):
+ """main() function that gets its information from the setup env.
+
+ Supports show and add/del <hook> <event>...
+ """
setup_env = self.setup_env
options = setup_env.options
command = options ['hook.action']
@@ -883,6 +1234,7 @@ class SetupHookEnvironment (
if command in { 'show', }:
self.info ( '\n'.join ( self.gen_hook_info_lines() ) )
+ # -- end <show>
elif command in { 'add', }:
hooks = list ( self.hook_root.find_all_by_name_begin ( hook_name ) )
@@ -892,11 +1244,17 @@ class SetupHookEnvironment (
)
# FIXME: exit code?
+ elif "all" in hooks:
+ self.error (
+ "cannot add hooks to the (virtual) \'all\' event!\n"
+ )
+
elif len ( hooks ) == 1:
- # good
+ # exactly one hook matches
self.link_hooks_to_events ( hooks, hook_events )
else:
+ # > 1 matches, find exact matches
exact_matches = [ k for k in hooks if k.name == hook_name ]
if not exact_matches or len ( exact_matches ) != 1:
@@ -908,6 +1266,8 @@ class SetupHookEnvironment (
else:
self.link_hooks_to_events ( exact_matches, hook_events )
+ # -- end <add>
+
elif command in { 'del', }:
hooks_to_unlink = []
@@ -978,6 +1338,8 @@ class SetupHookEnvironment (
# -- end if
self.unlink_hooks ( hooks_to_unlink )
+ # -- end <del>
+
else:
raise NotImplementedError ( command )
# --- end of run (...) ---
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-18 15:24 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-18 15:24 UTC (permalink / raw
To: gentoo-commits
commit: a9cde023d35bad3c87fc677d5bff862248426646
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Sep 18 15:23:25 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Sep 18 15:23:25 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=a9cde023
roverlay-setup: proper priority assignment (EXP)
Set priority on a per-user-dir basis.
"experimental": needs a fixup/cleanup
---
roverlay/setupscript/hookenv.py | 227 +++++++++++++++++++++++++---------------
1 file changed, 143 insertions(+), 84 deletions(-)
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index 8d70f02..d361801 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -147,6 +147,17 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
return self.priority is not None and self.priority >= 0
# --- end of has_priority (...) ---
+ def set_priority ( self, priority, only_if_unset=True ):
+ if self.priority is None:
+ self.priority = priority
+ elif self.priority < 0:
+ raise Exception (
+ "cannot assign priority to script with priority < 0."
+ )
+ elif not only_if_unset:
+ self.priority = priority
+ # --- end of set_priority (...) ---
+
def get_static_info ( self ):
return roverlay.static.hookinfo.get ( self.name, None )
# --- end of get_static_info (...) ---
@@ -167,9 +178,20 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
pass
# --- end of get_hookscript_path (...) ---
- @roverlay.util.objects.abstractmethod
- def get_dest_name ( self, *args, **kwargs ):
- pass
+ def get_dest_name ( self, file_ext='.sh', digit_len=2 ):
+ # file_ext has to be .sh, else the script doesn't get recognized
+ # by mux.sh
+
+ prio = self.priority
+ if prio is not None:
+ if prio < 0:
+ raise AssertionError ( "hook script has no priority." )
+
+ return "{prio:0>{l}d}-{fname}{f_ext}".format (
+ prio=prio, fname=self.name, f_ext=file_ext, l=digit_len,
+ )
+ else:
+ return self.filename
# --- end of get_dest_name (...) ---
# --- end of HookScriptBase ---
@@ -177,9 +199,36 @@ class HookScriptBase ( roverlay.util.objects.Referenceable ):
class UserHookScript ( HookScriptBase ):
- def __init__ ( self, fspath, filename=None, event=None ):
+ @classmethod
+ def create_for_hook (
+ cls, hook, destdir, event_name, priority_gen,
+ file_ext='.sh', digit_len=2
+ ):
+ if type ( priority_gen ) == int:
+ prio = priority_gen
+ elif hook.has_priority():
+ prio = hook.priority
+ else:
+ prio = next ( priority_gen )
+
+ filename = "{prio:0>{dlen}}-{name}{fext}".format (
+ prio = prio,
+ dlen = digit_len,
+ name = hook.name,
+ fext = file_ext,
+ )
+
+ instance = cls (
+ ( destdir + os.sep + filename ), filename=filename,
+ event=event_name, priority=prio,
+ )
+ instance.set_hookscript ( hook )
+ return instance
+ # --- end of create_for_hook (...) ---
+
+ def __init__ ( self, fspath, filename=None, event=None, priority=True ):
super ( UserHookScript, self ).__init__ (
- fspath, filename=filename, priority=True
+ fspath, filename=filename, priority=priority
)
self.hook_script_fspath = os.path.realpath ( self.fspath )
@@ -190,7 +239,6 @@ class UserHookScript ( HookScriptBase ):
else:
self.hook_script_ref = False
-
self.event = event
# --- end of __init__ (...) ---
@@ -250,8 +298,6 @@ class HookScript ( HookScriptBase ):
def add_user_script ( self, user_script ):
self.user_script_refs.add ( user_script.get_ref() )
- if self.priority is None and user_script.has_priority():
- self.priority = user_script.priority
# --- end of add_user_script (...) ---
def iter_user_scripts ( self, ignore_missing=True ):
@@ -265,30 +311,6 @@ class HookScript ( HookScriptBase ):
yield obj.deref_safe()
# --- end of iter_user_scripts (...) ---
- def set_priority_from_generator ( self, number_gen, only_if_unset=True ):
- if self.priority is None:
- self.priority = next ( number_gen )
- return True
- elif only_if_unset or self.priority < 0:
- return False
- else:
- self.priority = next ( number_gen )
- return True
- # --- end of set_priority_from_generator (...) ---
-
- def get_dest_name ( self, file_ext='.sh', digit_len=2 ):
- # file_ext has to be .sh, else the script doesn't get recognized
- # by mux.sh
-
- prio = self.priority
- if prio is None or prio < 0:
- raise AssertionError ( "hook script has no priority." )
-
- return "{prio:0>{l}d}-{fname}{f_ext}".format (
- prio=prio, fname=self.name, f_ext=file_ext, l=digit_len,
- )
- # --- end of get_dest_name (...) ---
-
def get_hookscript ( self ):
return self
# --- end of get_hookscript (...) ---
@@ -361,11 +383,17 @@ class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
return None
# --- end of find (...) ---
+ def find_by_name ( self, name, **kw ):
+ return self.find (
+ lambda s, n: s.name == n, c_args=( name, ), **kw
+ )
+ # --- end of find_all_by_name (...) ---
+
def find_all_by_name ( self, name, **kw ):
return self.find_all (
lambda s, n: s.name == n, c_args=( name, ), **kw
)
- # --- end of find_by_name (...) ---
+ # --- end of find_all_by_name (...) ---
def find_all_by_name_begin ( self, prefix, **kw ):
return self.find_all (
@@ -413,7 +441,10 @@ class NestedHookScriptDirBase ( HookScriptDirBase ):
filename_filter=self.filename_filter, include_root=False,
prune_empty=prune_empty,
)
+ self.scan_scripts()
+ # --- end of scan (...) ---
+ def scan_scripts ( self ):
for event, hook in self.iter_scripts():
if hook.event is None:
hook.event = event
@@ -453,6 +484,16 @@ class NestedHookScriptDirBase ( HookScriptDirBase ):
yield script
# --- end of find_all_by_name (...) ---
+ def get_subdir ( self, event_name ):
+ subdir = self.scripts.get ( event_name, None )
+ if subdir is None:
+ subdir = self.SUBDIR_CLS()
+ self.scripts [event_name] = subdir
+ # -- end if
+ return subdir
+ # --- end of get_subdir (...) ---
+
+
# --- end of NestedHookScriptDirBase ---
@@ -460,6 +501,38 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
HOOK_SCRIPT_CLS = UserHookScript
+ def __init__ ( self, *args, **kwargs ):
+ super ( UserHookScriptDir, self ).__init__ ( *args, **kwargs )
+ # per-event prio gen
+## self._prio_gen = collections.defaultdict (
+## self._create_new_prio_gen,
+## )
+ self._prio_gen = self._create_new_prio_gen()
+ # --- end of __init__ (...) ---
+
+ def _create_new_prio_gen ( self ):
+ return roverlay.util.counter.SkippingPriorityGenerator (
+ 10, skip=roverlay.static.hookinfo.get_priorities()
+ )
+ # --- end of _create_new_prio_gen (...) ---
+
+ def _get_prio_gen ( self, event_name ):
+ return self._prio_gen
+ # --- end of _get_prio_gen (...) ---
+
+ def scan_scripts ( self ):
+ prios = collections.defaultdict ( list )
+ for event, hook in self.iter_scripts():
+ if hook.event is None:
+ hook.event = event
+ if hook.has_priority():
+ prios [event].append ( hook.priority )
+ # -- end for
+
+ for event, priolist in prios.items():
+ self._get_prio_gen ( event ).add_generated ( priolist )
+ # --- end of scan (...) ---
+
def create_hookdir_refs ( self,
hook_dir, overwrite=False, compare_fspath=True
):
@@ -486,27 +559,27 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
)
# --- end of make_hookdir_refs (...) ---
- def register_hook_link_unsafe ( self, event_name, hook, link, link_name ):
- subdir = self.scripts.get ( event_name, None )
- if subdir is None or link_name not in subdir:
- if subdir is None:
- subdir = self.SUBDIR_CLS()
- self.scripts [event_name] = subdir
- # -- end if
-
- entry = self.HOOK_SCRIPT_CLS ( link, filename=link_name )
- subdir [link_name] = entry
+ def add_entry_unsafe ( self, hook ):
+ if hook.event:
+ self.get_subdir ( hook.event ) [hook.name] = hook
else:
- entry = subdir [link_name]
- # -- end if
-
- entry.set_hookscript ( hook, strict=False )
- if entry.event is None:
- entry.event = event_name
- elif entry.event != event_name:
- raise AssertionError ( "entry.event != event_name" )
+ raise AssertionError ( "hook.event is not set." )
return True
- # --- end of register_hook_link_unsafe (...) ---
+ # --- end of add_entry_unsafe (...) ---
+
+ def get_entry_for_link ( self, hook, event_name ):
+ existing_entry = self.find_by_name ( hook.name, event=event_name )
+ if existing_entry:
+ return existing_entry
+ else:
+ user_hook = UserHookScript.create_for_hook (
+ hook = hook,
+ destdir = ( self.root + os.sep + event_name ),
+ event_name = event_name,
+ priority_gen = self._get_prio_gen ( event_name )
+ )
+ return user_hook
+ # --- end of get_entry_for_link (...) ---
def iter_nonlinked ( self ):
for event, script in self.iter_scripts():
@@ -642,21 +715,6 @@ class SetupHookEnvironment (
)
self.hook_root.scan()
- # TODO:
- # prio_gen should be bound to user hook dirs (per event dir)
- # (priority assignment needs to be changed to realize that)
- #
- self._prio_gen = roverlay.util.counter.SkippingPriorityGenerator (
- 30, skip=(
- h.priority for h in self.hook_root.iter_scripts()
- if h.has_priority()
- )
- )
- # not strictly necessary
- self._prio_gen.add_generated (
- roverlay.static.hookinfo.get_priorities()
- )
-
if additions_dir:
self.user_hooks = UserHookScriptDir (
os.path.join ( additions_dir, 'hooks' )
@@ -669,11 +727,6 @@ class SetupHookEnvironment (
self.user_hooks.scan()
if self.hook_root:
self.user_hooks.make_hookdir_refs ( self.hook_root )
-
- self._prio_gen.add_generated (
- h.priority for ev, h in self.user_hooks.iter_scripts()
- if h.has_priority()
- )
else:
self.user_hooks = None
# --- end of setup (...) ---
@@ -729,40 +782,46 @@ class SetupHookEnvironment (
def link_hooks_v ( self, event_name, hooks ):
success = False
- if self.user_hooks is not None and self.user_hooks.writable:
+ user_hooks = self.user_hooks
- destdir = self.user_hooks.get_fspath ( event_name )
- self.setup_env.fs_private.dodir ( destdir )
+ if user_hooks is not None and user_hooks.writable:
+
+ self.setup_env.fs_private.dodir (
+ user_hooks.get_fspath ( event_name )
+ )
# note that there is a race condition when users manipulate their
# hook dir while running roverlay-setup
to_link = []
for script in hooks:
- script.set_priority_from_generator ( self._prio_gen )
- dest_name = script.get_dest_name()
- link = destdir + os.sep + dest_name
+ user_script = user_hooks.get_entry_for_link ( script, event_name )
- if self.check_link_allowed ( script.fspath, link, dest_name ):
- to_link.append ( ( script, dest_name, link ) )
+ if self.check_link_allowed (
+ script.fspath, user_script.fspath, user_script.get_dest_name()
+ ):
+ to_link.append ( ( script, user_script ) )
# -- end for
- register_link = self.user_hooks.register_hook_link_unsafe
+ register_link = user_hooks.add_entry_unsafe
symlink = self.setup_env.fs_private.symlink
unlink = self.setup_env.fs_private.unlink
relative_links = self.setup_env.options ['hook_relpath']
success = True
- for script, dest_name, link in to_link:
+ for script, user_script in to_link:
+ link = user_script.fspath
unlink ( link )
if relative_links:
have_link = symlink (
- os.path.relpath ( script.fspath, destdir ), link
+ os.path.relpath (
+ script.fspath, os.path.dirname ( link )
+ ), link
)
else:
have_link = symlink ( script.fspath, link )
if have_link:
- register_link ( event_name, script, link, dest_name )
+ register_link ( user_script )
elif have_link is not None:
success = False
# -- end if
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-13 15:20 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-13 15:20 UTC (permalink / raw
To: gentoo-commits
commit: 60a9c209e4c43ec6de3437c3c26ed036b7976f56
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 13 15:19:29 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 13 15:19:29 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=60a9c209
setupscript: --[no-]relpath-hooks
Controls whether links with absolute/relative paths are created.
Defaults to absolute if installed and relative if not.
---
roverlay/setupscript/hookenv.py | 15 +++++++++++----
roverlay/setupscript/runtime.py | 13 +++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index 5ffcbdd..001e9cd 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -674,12 +674,19 @@ class SetupHookEnvironment (
to_link.append ( ( script, dest_name, link ) )
# -- end for
- register_link = self.user_hooks.register_hook_link_unsafe
- symlink = self.setup_env.private_file.symlink
- success = True
+ register_link = self.user_hooks.register_hook_link_unsafe
+ symlink = self.setup_env.private_file.symlink
+ relative_links = self.setup_env.options ['hook_relpath']
+ success = True
for script, dest_name, link in to_link:
- have_link = symlink ( script.fspath, link )
+ if relative_links:
+ have_link = symlink (
+ os.path.relpath ( script.fspath, destdir ), link
+ )
+ else:
+ have_link = symlink ( script.fspath, link )
+
if have_link:
register_link ( event_name, script, link, dest_name )
elif have_link is not None:
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 43733a3..6ce804b 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -243,6 +243,17 @@ class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
),
)
+ arg (
+ '--relpath-hooks', dest='hook_relpath',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help='create hook links with relative paths',
+ )
+ arg (
+ '--no-relpath-hooks', dest='hook_relpath',
+ flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+ help='create hook links with absolute paths',
+ )
+
return arg
# --- end of setup_hooks (...) ---
@@ -293,6 +304,7 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
'private_conf_root' : instinfo ['workroot'] + os.sep + 'config',
'import_config' : 'symlink=root',
'additions_dir' : instinfo ['workroot'] + os.sep + 'files',
+ 'hook_relpath' : False,
}
else:
assert self.prjroot
@@ -304,6 +316,7 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
'private_conf_root' : prjroot + 'config',
'import_config' : 'disable',
'additions_dir' : prjroot + 'files',
+ 'hook_relpath' : True,
}
# --- end of get_parser_defaults (...) ---
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-13 15:10 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-13 15:10 UTC (permalink / raw
To: gentoo-commits
commit: 0a3962d2d7d9f9ede5316058ec9709c825223e26
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 13 15:03:47 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 13 15:03:47 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0a3962d2
setupscript: support standalone roverlay
This commit adds support for using roverlay-setup with not-installed versions of
roverlay.
For roverlay/setupscript/, this mostly affects the arg parser's defaults, and
allows to make paths in the config file relative to the git repo (IFF a subdir).
Additionally, --import-config gets disabled if roverlay is not installed.
---
roverlay/setupscript/initenv.py | 21 ++++++++++-
roverlay/setupscript/runtime.py | 81 +++++++++++++++++++++++++++++++++--------
2 files changed, 84 insertions(+), 18 deletions(-)
diff --git a/roverlay/setupscript/initenv.py b/roverlay/setupscript/initenv.py
index 5e511f8..2807841 100644
--- a/roverlay/setupscript/initenv.py
+++ b/roverlay/setupscript/initenv.py
@@ -90,15 +90,24 @@ class SetupInitEnvironment (
yield ( "user\'s config root",
get_path_option ( 'private_conf_root', self.setup_env.user_conf_root )
)
+ yield ( "additions dir",
+ get_path_option ( 'additions_dir', self.setup_env.additions_dir )
+ )
import_config = get_option ( 'import_config' )
if import_config == 'disable':
yield ( "import config", "no" )
- else:
+ elif self.setup_env.is_installed():
yield ( "import config",
"yes, "
+ self.IMPORT_CONFIG_DESC [import_config].format ( **fmt_vars )
)
+ else:
+ yield (
+ "import config",
+ 'no, standalone roverlay cannot import config '
+ 'with mode={!r}'.format ( import_config )
+ )
yield ( "enable default hooks", get_option ( 'want_default_hooks' ) )
@@ -147,7 +156,15 @@ class SetupInitEnvironment (
def do_import_config ( self, pretend ):
"""Imports the config."""
- mode = self.setup_env.options ['import_config']
+ mode = self.setup_env.options ['import_config']
+
+ if mode == 'disable':
+ self.info ( "config import: disabled.\n" )
+ return
+ elif not self.setup_env.is_installed():
+ self.error ( "config import: disabled due to standalone mode.\n" )
+ return
+
fs_ops = self.setup_env.private_dir
user_conf_root = self.setup_env.get_user_config_root()
# assert os.path.isdir ( os.path.dirname(user_conf_root) == work_root )
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 5a55515..43733a3 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -129,6 +129,15 @@ class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
help="additional variables",
)
+ arg (
+ '--prjroot-relpath', dest='prjroot_relpath',
+ flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+ help=(
+ 'make --{work,data,conf}-root, --{conf,additions}-dir '
+ 'relative to ROVERLAY_PRJROOT (for distributing config files)'
+ )
+ )
+
return arg
# --- end of setup_config (...) ---
@@ -141,9 +150,9 @@ class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
'\'--variable ADDITIONS_DIR={0}\'.'.format ( val )
)
- self.parsed ['config_vars'].append (
- "ADDITIONS_DIR=" + self.parsed ['additions_dir']
- )
+## self.parsed ['config_vars'].append (
+## "ADDITIONS_DIR=" + self.parsed ['additions_dir']
+## )
# --- end of parse_config (...) ---
def setup_init ( self ):
@@ -274,19 +283,39 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
# )
# --- end of __init__ (...) ---
- def create_argparser ( self ):
- instinfo = self.access_constant ( 'INSTALLINFO' )
-
- return SetupArgParser (
- description = 'roverlay setup script',
- defaults = {
+ def get_parser_defaults ( self ):
+ if self.is_installed():
+ instinfo = self.INSTALLINFO
+ return {
'work_root' : instinfo ['workroot'],
'data_root' : instinfo ['libexec'],
'conf_root' : instinfo ['confroot'],
'private_conf_root' : instinfo ['workroot'] + os.sep + 'config',
'import_config' : 'symlink=root',
'additions_dir' : instinfo ['workroot'] + os.sep + 'files',
- },
+ }
+ else:
+ assert self.prjroot
+ prjroot = self.prjroot + os.sep
+ return {
+ 'work_root' : prjroot + 'workdir',
+ 'data_root' : prjroot + 'files',
+ 'conf_root' : prjroot + 'config',
+ 'private_conf_root' : prjroot + 'config',
+ 'import_config' : 'disable',
+ 'additions_dir' : prjroot + 'files',
+ }
+ # --- end of get_parser_defaults (...) ---
+
+ def create_argparser ( self ):
+ return SetupArgParser (
+ description = 'roverlay setup script',
+ defaults = self.get_parser_defaults(),
+ epilog = (
+ 'Environment variables:\n'
+ '* ROVERLAY_PRJROOT - path to roverlay\'s source dir\n'
+ '* ROVERLAY_INSTALLED - mark roverlay as installed (if set and not empty)\n'
+ )
)
# --- end of create_argparser (...) ---
@@ -324,24 +353,44 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
# --- 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 (...) ---
+
+ get_prjroot_relpath = (
+ _get_prjroot_relpath
+ if ( self.options ['prjroot_relpath'] and self.prjroot )
+ else (lambda p: p)
+ )
+
conf_creator = roverlay.config.defconfig.RoverlayConfigCreation (
- is_installed = self.is_installed(),
- work_root = (
+ is_installed = self.is_installed(),
+ work_root = get_prjroot_relpath (
self.work_root if expand_user else self.options ['work_root']
),
- data_root = (
+ data_root = get_prjroot_relpath (
self.data_root if expand_user else self.options ['data_root']
),
- conf_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']
+ )
)
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 )
@@ -367,8 +416,7 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
# --- end of auto_reconfigure (...) ---
def setup ( self ):
- self.PWD_INITIAL = os.getcwd()
- self.setup_common()
+ self.setup_common ( allow_prjroot_missing=False )
# ref
options = self.options
@@ -389,6 +437,7 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
self.data_root = expanduser ( options ['data_root'] )
self.conf_root = expanduser ( options ['conf_root'] )
self.user_conf_root = expanduser ( options ['private_conf_root'] )
+ self.additions_dir = expanduser ( options ['additions_dir'] )
self.hook_overwrite = (
roverlay.setupscript.hookenv.HookOverwriteControl.from_str (
options ['hook_overwrite']
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-13 15:10 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-13 15:10 UTC (permalink / raw
To: gentoo-commits
commit: 0a59f1f7b3e34459257d018ca252751a35f66cc2
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Sep 13 15:02:47 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Sep 13 15:02:47 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0a59f1f7
setupscript/hookenv, --pretend: handle missing files
+ fix HOOKDIR_SCRIPT_CLS typo
---
roverlay/setupscript/hookenv.py | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index ebfe0d1..5ffcbdd 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -7,7 +7,6 @@
import collections
import errno
import fnmatch
-import itertools
import os
@@ -180,9 +179,13 @@ class UserHookScript ( HookScriptBase ):
)
self.hook_script_fspath = os.path.realpath ( self.fspath )
- self.hook_script_ref = (
- False if not os.path.islink ( self.fspath ) else None
- )
+ if (
+ os.path.islink ( self.fspath ) or not os.path.lexists ( self.fspath )
+ ):
+ self.hook_script_ref = None
+ else:
+ self.hook_script_ref = False
+
self.event = event
# --- end of __init__ (...) ---
@@ -436,7 +439,7 @@ class UserHookScriptDir ( NestedHookScriptDirBase ):
self.scripts [event_name] = subdir
# -- end if
- entry = self.HOOKDIR_CLS ( link, filename=link_name )
+ entry = self.HOOK_SCRIPT_CLS ( link, filename=link_name )
subdir [link_name] = entry
else:
entry = subdir [link_name]
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-12 16:36 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-12 16:36 UTC (permalink / raw
To: gentoo-commits
commit: 1eb711c0e3f609ef0d0845921f9086dc39da2f5c
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Sep 12 16:33:30 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Sep 12 16:33:30 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1eb711c0
roverlay/setupscript: "hooks" command
Added a "hooks" command for managing hooks. Currently, it is able to print
information about hooks enabled/available. The underlying code (HookScript*,
UserHookScript* classes) supports more, e.g. linking hooks.
Also added a "--overwrite-hooks [<when>]" option to roverlay-setup, which can be
used to control which hooks will be overwritten, e.g. when running the init
command.
---
roverlay/setupscript/hookenv.py | 641 ++++++++++++++++++++++++++++++++++------
roverlay/setupscript/initenv.py | 3 +
roverlay/setupscript/runtime.py | 38 ++-
3 files changed, 595 insertions(+), 87 deletions(-)
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index e07b4e7..ebfe0d1 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -6,40 +6,130 @@
import collections
import errno
+import fnmatch
+import itertools
import os
+import roverlay.fsutil
import roverlay.static.hookinfo
import roverlay.util.counter
+import roverlay.util.dictwalk
+import roverlay.util.objects
+import roverlay.setupscript.baseenv
+
+
+class HookOverwriteControl ( object ):
+ OV_NONE = 0
+ OV_SYM_DEAD = 2**0
+ OV_SYM_EXIST = 2**1
+ OV_SYM = OV_SYM_DEAD|OV_SYM_EXIST
+ OV_FILE = 2**2
+ OV_ALL = ( 2**3 ) - 1
+
+ OV_KEYWORDS = {
+ 'none' : OV_NONE,
+ 'dead' : OV_SYM_DEAD,
+ 'links' : OV_SYM,
+ 'all' : OV_ALL,
+ }
+
+ @classmethod
+ def from_str ( cls, vstr ):
+ return cls ( cls.OV_KEYWORDS[vstr] )
+ # --- end of from_str (...) ---
+
+ def __init__ ( self, value ):
+ super ( HookOverwriteControl, self ).__init__()
+ assert isinstance ( value, int ) and value >= 0
+ self.value = value
+ # --- end of __init__ (...) ---
+ def can_overwrite ( self, mask=None ):
+ if mask is None:
+ return self.value == self.OV_NONE
+ else:
+ return self.value & mask
+ # --- end of can_overwrite (...) ---
-class HookScript ( object ):
+ def overwrite_dead_symlinks ( self ):
+ return self.value & self.OV_SYM_DEAD
+
+ def overwrite_symlinks ( self ):
+ return self.value & self.OV_SYM
+
+ def overwrite_all ( self ):
+ return self.value == self.OV_ALL
+
+ def get_str ( self ):
+ value = self.value
+ def gen_words():
+ if value == self.OV_NONE:
+ yield "none"
+ else:
+ if value & self.OV_SYM_EXIST:
+ if value & self.OV_SYM_DEAD:
+ yield "symlinks"
+ else:
+ yield "symlinks to existing files"
+ elif value & self.OV_SYM_DEAD:
+ yield "broken symlinks"
+
+ if value & self.OV_FILE:
+ yield "files"
+ # --- end of gen_words (...) ---
+
+ return ', '.join ( gen_words() ) + " (0x{:x})".format ( value )
+ # --- end of get_str (...) ---
+
+ __str__ = get_str
+
+# --- end of HookOverwriteControl ---
+
+
+class HookScriptBase ( roverlay.util.objects.Referenceable ):
+
+ CACHE_REF = True
+
+ def __init__ ( self,
+ fspath, filename=None, priority=None, is_hidden=False
+ ):
+ """HookScriptBase constructor.
+
+ arguments:
+ * fspath -- absolute path to the hook script
+ * filename -- name of the hook script
+ Defaults to os.path.basename(fspath).
+ * priority -- priority of the hook script. Defaults to auto-detect.
+ * is_hidden -- whether the script is "hidden" or not. Defaults to False.
+ """
+ super ( HookScriptBase, self ).__init__()
- def __init__ ( self, fspath, filename=None ):
- super ( HookScript, self ).__init__()
fname = (
filename if filename is not None else os.path.basename ( fspath )
)
- self.fspath = fspath
- self.name = os.path.splitext ( fname )[0] or fname
- static_entry = roverlay.static.hookinfo.get ( self.name, None )
-
- if static_entry is not None:
- self.default_events = static_entry[0]
- self.priority = static_entry[1]
- self.is_hidden = static_entry[2]
+ self.filename = fname
+
+ if priority is True:
+ prio_str, dash, remainder = fname.partition ( '-' )
+ if prio_str and dash and remainder:
+ try:
+ prio = int ( prio_str, 10 )
+ except ValueError:
+ self.priority = None
+ else:
+ self.priority = prio
+ fname = remainder
+ else:
+ self.priority = None
else:
- self.default_events = False
- self.priority = None
- self.is_hidden = False
- # --- end of __init__ (...) ---
+ self.priority = priority
- def is_visible ( self ):
- return not self.is_hidden and (
- self.priority is None or self.priority >= 0
- )
- # --- end of is_visible (...) ---
+ self.name = os.path.splitext ( fname )[0]
+ self.fspath = fspath
+ self.is_hidden = is_hidden
+ # --- end of __init__ (...) ---
def __str__ ( self ):
yesno = lambda k: 'y' if k else 'n'
@@ -54,6 +144,118 @@ class HookScript ( object ):
)
# --- end of __str__ (...) ---
+ def get_static_info ( self ):
+ return roverlay.static.hookinfo.get ( self.name, None )
+ # --- end of get_static_info (...) ---
+
+ def is_visible ( self ):
+ return not self.is_hidden and (
+ self.priority is None or self.priority >= 0
+ )
+ # --- end of is_visible (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def get_hookscript ( self ):
+ pass
+ # --- end of get_hookscript (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def get_hookscript_path ( self ):
+ pass
+ # --- end of get_hookscript_path (...) ---
+
+ @roverlay.util.objects.abstractmethod
+ def get_dest_name ( self, *args, **kwargs ):
+ pass
+ # --- end of get_dest_name (...) ---
+
+# --- end of HookScriptBase ---
+
+
+class UserHookScript ( HookScriptBase ):
+
+ def __init__ ( self, fspath, filename=None, event=None ):
+ super ( UserHookScript, self ).__init__ (
+ fspath, filename=filename, priority=True
+ )
+
+ self.hook_script_fspath = os.path.realpath ( self.fspath )
+ self.hook_script_ref = (
+ False if not os.path.islink ( self.fspath ) else None
+ )
+
+ self.event = event
+ # --- end of __init__ (...) ---
+
+ def set_hookscript ( self, script_obj, strict=True ):
+ if script_obj and self.hook_script_ref is False:
+ raise Exception (
+ "user hook script {} is not a link!".format ( self.fspath )
+ )
+ elif script_obj is None or script_obj is False:
+ self.hook_script_ref = False
+
+ else:
+ self.hook_script_ref = script_obj.get_ref()
+ script_obj.add_user_script ( self )
+ # --- end of set_hookscript (...) ---
+
+ def has_hookscript ( self ):
+ return self.hook_script_ref is not None
+ # --- end of has_hookscript (...) ---
+
+ def get_hookscript ( self ):
+ ref = self.hook_script_ref
+ if ref is False:
+ return None
+ elif ref is None:
+ raise roverlay.util.objects.ObjectDisappeared()
+ else:
+ return ref.deref_safe()
+ # --- end of get_hookscript (...) ---
+
+ def get_hookscript_path ( self ):
+ return self.hook_script_fspath
+ # --- end of get_hookscript_path (...) ---
+
+ def get_dest_name ( self ):
+ return self.filename
+ # --- end of get_dest_name (...) ---
+
+# --- end of UserHookScript ---
+
+
+class HookScript ( HookScriptBase ):
+
+ def __init__ ( self, fspath, filename=None ):
+ super ( HookScript, self ).__init__ ( fspath, filename=filename )
+
+ static_entry = self.get_static_info()
+ if static_entry is not None:
+ self.default_events = static_entry[0]
+ self.priority = static_entry[1]
+ self.is_hidden = static_entry[2]
+ else:
+ self.default_events = False
+
+ self.user_script_refs = set()
+ # --- end of __init__ (...) ---
+
+ def add_user_script ( self, user_script ):
+ self.user_script_refs.add ( user_script.get_ref() )
+ # --- end of add_user_script (...) ---
+
+ def iter_user_scripts ( self, ignore_missing=True ):
+ if ignore_missing:
+ for ref in self.user_script_refs:
+ obj = ref.deref_unsafe()
+ if obj is not None:
+ yield obj
+ else:
+ for ref in self.user_script_refs:
+ yield obj.deref_safe()
+ # --- end of iter_user_scripts (...) ---
+
def set_priority_from_generator ( self, number_gen, only_if_unset=True ):
if self.priority is None:
self.priority = next ( number_gen )
@@ -78,53 +280,47 @@ class HookScript ( object ):
)
# --- end of get_dest_name (...) ---
+ def get_hookscript ( self ):
+ return self
+ # --- end of get_hookscript (...) ---
+
+ def get_hookscript_path ( self ):
+ return self.fspath
+ # --- end of get_hookscript_path (...) ---
# --- end of HookScript ---
-class HookScriptDir ( object ):
+class HookScriptDirBase ( roverlay.util.objects.Referenceable ):
+
+ HOOK_SCRIPT_CLS = None
def __init__ ( self, root ):
- super ( HookScriptDir, self ).__init__()
+ super ( HookScriptDirBase, self ).__init__()
- self.root = root
- self._scripts = collections.OrderedDict()
+ self.root = root
+ self.scripts = collections.OrderedDict()
+ self.writable = None
# --- end of __init__ (...) ---
def __bool__ ( self ):
- return bool ( self._scripts )
+ return bool ( self.scripts )
# --- end of __bool__ (...) ---
+ def get_fspath ( self, relpath=None ):
+ if relpath:
+ return self.root + os.sep + str ( relpath )
+ else:
+ return self.root
+ # --- end of get_fspath (...) ---
+
def get_script ( self, name ):
- script = self._scripts [name]
+ script = self.scripts [name]
return script if script.is_visible() else None
# --- end of get_scripts (...) ---
- def iter_default_scripts ( self, unpack=False ):
- if unpack:
- for script in self._scripts.values():
- if script.default_events:
- for event in script.default_events:
- yield ( event, script )
- else:
- for script in self._scripts.values():
- if script.default_events:
- yield script
- # --- end of iter_default_scripts (...) ---
-
- def get_default_scripts ( self ):
- scripts = dict()
- for event, script in self.iter_default_scripts ( unpack=True ):
- if event not in scripts:
- scripts [event] = [ script ]
- else:
- scripts [event].append ( script )
-
- return scripts
- # --- end of get_default_scripts (...) ---
-
def iter_scripts ( self ):
- for script in self._scripts.values():
+ for script in self.scripts.values():
if script.is_visible():
yield script
# --- end of iter_scripts (...) ---
@@ -136,80 +332,354 @@ class HookScriptDir ( object ):
except OSError as oserr:
if oserr.errno != errno.ENOENT:
raise
-
else:
+ HOOK_CLS = self.HOOK_SCRIPT_CLS
for fname in filenames:
fspath = root + os.sep + fname
if os.path.isfile ( fspath ):
- script_obj = HookScript ( fspath, fname )
- self._scripts [script_obj.name] = script_obj
+ script_obj = HOOK_CLS ( fspath, filename=fname )
+ self.scripts [script_obj.name] = script_obj
# --- end of scan (...) ---
+# --- end of HookScriptDirBase ---
+
+
+class NestedHookScriptDirBase ( HookScriptDirBase ):
+ SUBDIR_CLS = collections.OrderedDict
+ DIRNAMES_IGNORE = frozenset({ '.*', })
+ FILENAMES_IGNORE = frozenset({ '.*', })
+
+ def dirname_filter ( self, dirname, _fnmatch=fnmatch.fnmatch ):
+ for pattern in self.DIRNAMES_IGNORE:
+ if _fnmatch ( dirname, pattern ):
+ return False
+ return True
+ # --- end of dirname_filter (...) ---
+
+ def get_script ( self, name ):
+ return [
+ script for script in self.iter_scripts() if script.name == name
+ ]
+ # --- end of get_script (...) ---
+
+ def filename_filter ( self, filename, _fnmatch=fnmatch.fnmatch ):
+ for pattern in self.FILENAMES_IGNORE:
+ if _fnmatch ( filename, pattern ):
+ return False
+ return True
+ # --- end of filename_filter (...) ---
+
+ def create_hookscript ( self, fspath, filename, root ):
+ return self.HOOK_SCRIPT_CLS ( fspath, filename=filename )
+ # --- end of create_hookscript (...) ---
+
+ def scan ( self, prune_empty=True ):
+ SUBDIR_CLS = self.SUBDIR_CLS
+
+ self.scripts = roverlay.fsutil.get_fs_dict (
+ self.root, create_item=self.create_hookscript,
+ dict_cls=self.SUBDIR_CLS, dirname_filter=self.dirname_filter,
+ filename_filter=self.filename_filter, include_root=False,
+ prune_empty=True,
+ )
+
+ for event, hook in self.iter_scripts():
+ if hook.event is None:
+ hook.event = event
+ # --- end of scan (...) ---
+
+ def iter_scripts ( self ):
+ # roverlay uses per-event subdirs containing hook files
+ SUBDIR_CLS = self.SUBDIR_CLS
+ for event, subdir in self.scripts.items():
+ if isinstance ( subdir, SUBDIR_CLS ):
+ for hook in subdir.values():
+ if isinstance ( hook, HookScriptBase ) and hook.is_visible():
+ #if not isinstance ( hook, SUBDIR_CLS ):
+ yield ( event, hook )
+ # --- end of iter_scripts (...) ---
+
+# --- end of NestedHookScriptDirBase ---
+
+
+class UserHookScriptDir ( NestedHookScriptDirBase ):
+
+ HOOK_SCRIPT_CLS = UserHookScript
+
+ def create_hookdir_refs ( self,
+ hook_dir, overwrite=False, compare_fspath=True
+ ):
+ for event, user_script in self.iter_scripts():
+ if overwrite or not user_script.has_hookscript():
+ try:
+ hook = hook_dir.get_script ( user_script.name )
+ except KeyError:
+ pass
+ else:
+ if hook is not None and (
+ not compare_fspath or user_script.fspath == hook.fspath
+ ):
+ user_script.set_hookscript ( hook )
+ # --- end of create_hookdir_refs (...) ---
+
+ def make_hookdir_refs ( self, hook_dir, overwrite=False ):
+ # try exact fs path matches first, then use name-based ones
+ self.create_hookdir_refs ( hook_dir, compare_fspath=True )
+ self.create_hookdir_refs ( hook_dir, compare_fspath=False )
+ # --- end of make_hookdir_refs (...) ---
+
+ def register_hook_link_unsafe ( self, event_name, hook, link, link_name ):
+ subdir = self.scripts.get ( event_name, None )
+ if subdir is None or link_name not in subdir:
+ if subdir is None:
+ subdir = self.SUBDIR_CLS()
+ self.scripts [event_name] = subdir
+ # -- end if
+
+ entry = self.HOOKDIR_CLS ( link, filename=link_name )
+ subdir [link_name] = entry
+ else:
+ entry = subdir [link_name]
+ # -- end if
+
+ entry.set_hookscript ( hook, strict=False )
+ if entry.event is None:
+ entry.event = event_name
+ elif entry.event != event_name:
+ raise AssertionError ( "entry.event != event_name" )
+ return True
+ # --- end of register_hook_link_unsafe (...) ---
+
+ def iter_nonlinked ( self ):
+ for event, script in self.iter_scripts():
+ if not script.has_hookscript():
+ yield script
+ # --- end of iter_nonlinked (...) ---
+
+# --- end of UserHookScriptDir ---
+
+
+class HookScriptDir ( HookScriptDirBase ):
+
+ HOOK_SCRIPT_CLS = HookScript
+
+ def iter_linked ( self ):
+ # 2-tuple ( hook_script, list ( linked_user_scripts ) )
+ for script in self.iter_scripts():
+ yield ( script, list ( script.iter_user_scripts() ) )
+ # --- end of iter_linked (...) ---
+
+ def iter_default_scripts ( self, unpack=False ):
+ if unpack:
+ for script in self.iter_scripts():
+ if script.default_events:
+ for event in script.default_events:
+ yield ( event, script )
+ else:
+ for script in self.iter_scripts():
+ if script.default_events:
+ yield script
+ # --- end of iter_default_scripts (...) ---
+
+ def get_default_scripts ( self ):
+ return roverlay.util.dictwalk.dictmerge (
+ self.iter_default_scripts ( unpack=True ),
+ get_value=lambda kv:kv[1]
+ )
+ # --- end of get_default_scripts (...) ---
+
# --- end of HookScriptDir ---
+
class SetupHookEnvironment (
roverlay.setupscript.baseenv.SetupSubEnvironment
):
NEEDS_CONFIG_TREE = True
- def setup ( self ):
- additions_dir = self.config.get ( 'OVERLAY.additions_dir', None )
- if additions_dir:
- self.user_hook_root = os.path.join ( additions_dir, 'hooks' )
- self.writable = self.setup_env.private_file.check_writable (
- self.user_hook_root + os.sep + '.keep'
+ def format_hook_info_lines ( self,
+ info, sort_info=True, append_newline=False
+ ):
+ max_name_len = min ( 30, max ( len(x[0]) for x in info ) )
+
+ event_names = set()
+ for name, ev_prio in info:
+ event_names.update ( item[0] for item in ev_prio )
+
+ event_words = [
+ ( ev, (4+len(ev)) * ' ' ) for ev in sorted ( event_names )
+ ]
+
+ if sort_info:
+ my_info = sorted (
+ info,
+ key=lambda k: ( not k[1], k[0] )
)
else:
- self.user_hook_root = None
- self.writable = None
+ my_info = info
+
+ for name, event_prio_list in my_info:
+ events = dict ( event_prio_list )
+ get_prio = lambda p: ( "UU" if p is None else p )
+
+ yield "{name:>{nlen}} | {ev}".format (
+ name=name, nlen=max_name_len,
+ ev=' '.join (
+ (
+ "{name}({prio:0>2})".format (
+ name=ev, prio=get_prio ( events[ev] )
+ ) if ev in events else replacement
+ for ev, replacement in event_words
+ )
+ )
+ ).rstrip()
+ # -- end for
+
+ if append_newline:
+ yield ""
+ # --- end of format_hook_info_lines (...) ---
+
+ def get_hook_root_info ( self, nonlinked_only=False ):
+ if nonlinked_only:
+ return [
+ ( script.name, [] )
+ for script, user_scripts in self.hook_root.iter_linked()
+ if not user_scripts
+ ]
+ else:
+ return [
+ (
+ script.name,
+ [ ( s.event or "undef", s.priority ) for s in user_scripts ]
+ )
+ for script, user_scripts in self.hook_root.iter_linked()
+ ]
+ # --- end of get_hook_root_info (...) ---
+
+ def get_user_hook_info ( self ):
+ return [
+ ( s.name, [ ( s.event or "undef", s.priority ) ] )
+ for event, s in self.user_hooks.iter_scripts()
+ ]
+ # --- end of get_user_hook_info (...) ---
+
+ def gen_hook_info_lines ( self, append_newline=True ):
+ info = (
+ self.get_user_hook_info()
+ + self.get_hook_root_info ( nonlinked_only=True )
+ )
+ for line in self.format_hook_info_lines (
+ info, append_newline=append_newline
+ ):
+ yield line
+ # --- end of gen_hook_info_lines (...) ---
+
+ def setup ( self ):
+ self.hook_overwrite_control = self.setup_env.hook_overwrite
+
+ additions_dir = self.config.get ( 'OVERLAY.additions_dir', None )
self.hook_root = HookScriptDir (
os.path.join ( self.setup_env.data_root, 'hooks' )
)
self.hook_root.scan()
self._prio_gen = roverlay.util.counter.UnsafeCounter ( 30 )
+
+
+ if additions_dir:
+ self.user_hooks = UserHookScriptDir (
+ os.path.join ( additions_dir, 'hooks' )
+ )
+ self.user_hooks.writable = (
+ self.setup_env.private_file.check_writable (
+ self.user_hooks.get_fspath ( '.keep' )
+ )
+ )
+ self.user_hooks.scan()
+ if self.hook_root:
+ self.user_hooks.make_hookdir_refs ( self.hook_root )
+ else:
+ self.user_hooks = None
# --- end of setup (...) ---
- def _link_hook ( self, source, link ):
+ def check_link_allowed ( self, source, link, link_name ):
if os.path.lexists ( link ):
- linkdest = os.path.realpath ( link )
+ allow_overwrite = False
+
+ skip_message = (
+ 'Skipping activation of hook {!r} - '.format ( link_name )
+ )
+ ov_message = 'Overwriting hook {!r} - '.format ( link_name )
+
+
+ if os.path.islink ( link ):
+ linkdest = os.path.realpath ( link )
+
+ if linkdest == source or linkdest == os.path.realpath ( source ):
+ self.info ( skip_message + "already set up.\n" )
+ allow_overwrite = None
- message = 'Skipping activation of hook {!r} - '.format ( link )
+ elif os.path.exists ( link ):
+ if self.hook_overwrite_control.overwrite_symlinks():
+ self.info ( ov_message + "symlink.\n" )
+ allow_overwrite = True
+ else:
+ self.error ( skip_message + "symlink.\n" )
- if linkdest == source or linkdest == os.path.realpath ( source ):
- self.info ( message + "already set up.\n" )
- return True
+ elif self.hook_overwrite_control.overwrite_dead_symlinks():
+ self.info ( ov_message + "broken symlink.\n" )
+ allow_overwrite = True
+
+ else:
+ self.error ( skip_message + "broken symlink.\n" )
+
+ elif os.path.isfile ( link ):
+ if self.hook_overwrite_control.overwrite_all():
+ self.error ( ov_message + "file.\n" )
+ allow_overwrite = True
+ else:
+ self.error ( skip_message + "file.\n" )
- elif link != linkdest:
- # symlink or link was relative
- self.error ( message + "is a link to another file.\n" )
else:
- self.error ( message + "exists, but is not a link.\n" )
+ self.error ( skip_message + "not a file!\n" )
- return None
+ # -- end if
+
+ return allow_overwrite
else:
- return self.setup_env.private_file.symlink ( source, link )
- # --- end of _link_hook (...) ---
+ return True
+ # --- end of check_link_allowed (...) ---
def link_hooks_v ( self, event_name, hooks ):
success = False
- if self.writable and self.user_hook_root:
- destdir = self.user_hook_root + os.sep + event_name
+ if self.user_hooks is not None and self.user_hooks.writable:
+
+ destdir = self.user_hooks.get_fspath ( event_name )
self.setup_env.private_dir.dodir ( destdir )
+ # note that there is a race condition when users manipulate their
+ # hook dir while running roverlay-setup
to_link = []
for script in hooks:
script.set_priority_from_generator ( self._prio_gen )
- to_link.append (
- ( script.fspath, destdir + os.sep + script.get_dest_name() )
- )
-
- success = True
- for source, link_name in to_link:
- if self._link_hook ( source, link_name ) is False:
+ dest_name = script.get_dest_name()
+ link = destdir + os.sep + dest_name
+
+ if self.check_link_allowed ( script.fspath, link, dest_name ):
+ to_link.append ( ( script, dest_name, link ) )
+ # -- end for
+
+ register_link = self.user_hooks.register_hook_link_unsafe
+ symlink = self.setup_env.private_file.symlink
+ success = True
+
+ for script, dest_name, link in to_link:
+ have_link = symlink ( script.fspath, link )
+ if have_link:
+ register_link ( event_name, script, link, dest_name )
+ elif have_link is not None:
success = False
# -- end if
@@ -230,4 +700,9 @@ class SetupHookEnvironment (
return success
# --- end of enable_defaults (...) ---
+ def run ( self ):
+ # TODO
+ self.info ( '\n'.join ( self.gen_hook_info_lines() ) )
+ # --- end of run (...) ---
+
# --- end of SetupHookEnvironment ---
diff --git a/roverlay/setupscript/initenv.py b/roverlay/setupscript/initenv.py
index febe39e..5e511f8 100644
--- a/roverlay/setupscript/initenv.py
+++ b/roverlay/setupscript/initenv.py
@@ -101,6 +101,9 @@ class SetupInitEnvironment (
)
yield ( "enable default hooks", get_option ( 'want_default_hooks' ) )
+
+ yield ( "overwrite hooks", self.setup_env.hook_overwrite.get_str() )
+
yield ( "additional config variables", get_option ( 'config_vars' ) )
# --- end of gen_pretend_options (...) ---
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index e094951..5a55515 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -50,14 +50,18 @@ def arg_stdout_or_fs ( value ):
class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
MULTIPLE_COMMANDS = False
COMMAND_DESCRIPTION = {
- 'init': 'initialize roverlay\'s config and filesystem layout',
- 'mkconfig': 'generate a config file',
+ 'init' : 'initialize roverlay\'s config and filesystem layout',
+ 'mkconfig' : 'generate a config file',
+ 'hooks' : 'manage hook files',
}
DEFAULT_COMMAND = "init"
- COMMANDS_WITH_PRETEND = frozenset ({ 'init', })
+ COMMANDS_WITH_PRETEND = frozenset ({ 'init', 'hooks', })
- SETUP_TARGETS = ( 'version', 'actions', 'setup', 'config', 'init', )
+ SETUP_TARGETS = (
+ 'usage', 'version',
+ 'actions', 'setup', 'config', 'init', 'hooks',
+ )
PARSE_TARGETS = ( 'actions', 'setup', 'config', 'init', )
@@ -214,6 +218,25 @@ class SetupArgParser ( roverlay.argparser.RoverlayArgumentParser ):
)
# --- end of parse_init (...) ---
+ def setup_hooks ( self ):
+ arg = self.add_argument_group (
+ "hooks", title="options for managing hooks"
+ )
+
+ arg (
+ "--overwrite-hooks", dest='hook_overwrite',
+ default="dead", const="links", nargs="?", metavar="<when>",
+ choices=[ 'none', 'dead', 'links', 'all', ],
+ flags=self.ARG_WITH_DEFAULT,
+ help=(
+ 'control hook overwrite behavior '
+ '(%(choices)s; \'%(const)s\' if specified without an arg)'
+ ),
+ )
+
+ return arg
+ # --- end of setup_hooks (...) ---
+
# --- end of SetupArgParser ---
@@ -366,6 +389,11 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
self.data_root = expanduser ( options ['data_root'] )
self.conf_root = expanduser ( options ['conf_root'] )
self.user_conf_root = expanduser ( options ['private_conf_root'] )
+ self.hook_overwrite = (
+ roverlay.setupscript.hookenv.HookOverwriteControl.from_str (
+ options ['hook_overwrite']
+ )
+ )
self.fs_ops_virtual = {
@@ -470,6 +498,8 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ):
def default_main ( self ):
if self.wants_command ( "mkconfig" ):
self.write_config_file ( self.options ['output'] )
+ elif self.wants_command ( "hooks" ):
+ self.get_hook_env().run()
elif self.wants_command ( "init" ):
self.get_init_env().run()
# --- end of default_main (...) ---
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/
@ 2013-09-11 14:50 André Erdmann
0 siblings, 0 replies; 12+ messages in thread
From: André Erdmann @ 2013-09-11 14:50 UTC (permalink / raw
To: gentoo-commits
commit: b33e905caa08f4912c5ecc1813da659688513497
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Sep 11 13:09:38 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Sep 11 13:09:38 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=b33e905c
add copyright note to roverlay/setupscript/*.py
---
roverlay/setupscript/__init__.py | 3 +++
roverlay/setupscript/baseenv.py | 3 +++
roverlay/setupscript/hookenv.py | 3 +++
roverlay/setupscript/initenv.py | 4 ++++
roverlay/setupscript/runtime.py | 3 +++
5 files changed, 16 insertions(+)
diff --git a/roverlay/setupscript/__init__.py b/roverlay/setupscript/__init__.py
index 740a69c..874cd6a 100644
--- a/roverlay/setupscript/__init__.py
+++ b/roverlay/setupscript/__init__.py
@@ -1,2 +1,5 @@
# R overlay -- setup script
# -*- 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.
diff --git a/roverlay/setupscript/baseenv.py b/roverlay/setupscript/baseenv.py
index 349d077..eb05764 100644
--- a/roverlay/setupscript/baseenv.py
+++ b/roverlay/setupscript/baseenv.py
@@ -1,5 +1,8 @@
# R overlay -- setup script, base env
# -*- 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.
class SetupSubEnvironment ( object ):
diff --git a/roverlay/setupscript/hookenv.py b/roverlay/setupscript/hookenv.py
index 9c5fedb..e07b4e7 100644
--- a/roverlay/setupscript/hookenv.py
+++ b/roverlay/setupscript/hookenv.py
@@ -1,5 +1,8 @@
# R overlay -- setup script, env for managing hooks
# -*- 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 collections
import errno
diff --git a/roverlay/setupscript/initenv.py b/roverlay/setupscript/initenv.py
index f07953a..febe39e 100644
--- a/roverlay/setupscript/initenv.py
+++ b/roverlay/setupscript/initenv.py
@@ -1,5 +1,8 @@
# R overlay -- setup script, env for the "init" command
# -*- 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 textwrap
@@ -17,6 +20,7 @@ class SetupInitEnvironment (
roverlay.setupscript.baseenv.SetupSubEnvironment
):
+ # ( action_name, can_be_skipped )
ACTIONS = (
( 'pretend', False ),
( 'prepare_config_file', False ),
diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py
index 9ba3eec..e094951 100644
--- a/roverlay/setupscript/runtime.py
+++ b/roverlay/setupscript/runtime.py
@@ -1,5 +1,8 @@
# R overlay -- setup script, runtime
# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
from __future__ import print_function
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-04-01 16:38 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-01 16:38 [gentoo-commits] proj/R_overlay:master commit in: roverlay/setupscript/ André Erdmann
-- strict thread matches above, loose matches on Subject: below --
2014-02-22 14:56 André Erdmann
2014-02-21 17:36 André Erdmann
2014-02-17 17:22 André Erdmann
2014-02-17 17:10 André Erdmann
2013-09-19 15:00 André Erdmann
2013-09-18 15:24 André Erdmann
2013-09-13 15:20 André Erdmann
2013-09-13 15:10 André Erdmann
2013-09-13 15:10 André Erdmann
2013-09-12 16:36 André Erdmann
2013-09-11 14:50 André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox