public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2012-08-02 15:14 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2012-08-02 15:14 UTC (permalink / raw
  To: gentoo-commits

commit:     dbd601765440a1f735ead40c89c2c02d64c07af3
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug  2 15:09:09 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug  2 15:09:09 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=dbd60176

main script, argutil: command_map

---
 roverlay.py         |    4 ++--
 roverlay/argutil.py |   38 ++++++++++++++++++++++----------------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index 3297325..bd250ea 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -62,8 +62,8 @@ COMMAND_DESCRIPTION = {
 
 commands, config_file, additional_config, extra_opts = \
 	roverlay.argutil.parse_argv (
-		CMD_DESC=COMMAND_DESCRIPTION,
-		DEFAULT_CONFIG="R-overlay.conf"
+		command_map=COMMAND_DESCRIPTION,
+		default_config_file="R-overlay.conf"
 	)
 
 OPTION = extra_opts.get

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 4cefdbd..813a7d7 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -3,13 +3,13 @@ import os.path
 import argparse
 import roverlay
 
-def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
+def get_parser ( command_map, default_config_file, default_command='create' ):
 
 	def is_fs_file ( value ):
 		f = os.path.abspath ( value )
 		if not os.path.isfile ( f ):
 			raise argparse.ArgumentTypeError (
-				"%r is not a file." % value
+				"{!r} is not a file.".format ( value )
 			)
 		return f
 
@@ -17,7 +17,7 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 		d = os.path.abspath ( value )
 		if not os.path.isdir ( d ):
 			raise argparse.ArgumentTypeError (
-				"%r is not a directory." % value
+				"{!r} is not a directory.".format ( value )
 			)
 		return d
 
@@ -25,7 +25,7 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 		d = os.path.abspath ( value )
 		if os.path.exists ( d ) and not os.path.isdir ( d ):
 			raise argparse.ArgumentTypeError (
-				"%r cannot be a directory." % value
+				"{!r} cannot be a directory.".format ( value )
 			)
 		return d
 
@@ -40,7 +40,13 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 			roverlay.description_str, roverlay.license_str,
 		)),
 		epilog = 'Known commands:\n' + '\n'.join (
-			( ( '* ' + c ).ljust(17) + ' - ' + d for (c,d) in CMD_DESC.items() )
+			(
+				# '* <space> <command> - <command description>'
+				'* {cmd} - {desc}'.format (
+					cmd  = i [0].ljust ( 15 ),
+					desc = i [1]
+				) for i in command_map.items()
+			)
 		),
 		add_help=True,
 		formatter_class=argparse.RawDescriptionHelpFormatter,
@@ -60,18 +66,17 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 
 	arg (
 		'commands',
-		# fixme: CMD_DESC is "unknown", but default is set to a specific command
-		default='create',
-		help="action to perform. choices are " + ', '.join (CMD_DESC.keys()) + \
+		default=default_command,
+		help="action to perform. choices are " + ', '.join (command_map.keys()) + \
 			". defaults to %(default)s.",
 		nargs="*",
-		choices=CMD_DESC.keys(),
+		choices=command_map.keys(),
 		metavar="command"
 	)
 
 	arg (
 		'-c', '--config',
-		default=DEFAULT_CONFIG,
+		default=default_config_file,
 		help="config file",
 		type=is_fs_file_or_void, metavar="<file>"
 	)
@@ -205,7 +210,7 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 	return parser
 # --- end of get_parser (...) ---
 
-def parse_argv ( *args, **kw ):
+def parse_argv ( command_map, **kw ):
 	"""Parses sys.argv and returns the result as tuple
 	(<commands to run>, <config file>,
 	<dict for config>, <extra options as dict>).
@@ -229,7 +234,7 @@ def parse_argv ( *args, **kw ):
 				pos = pos [k]
 
 
-	p = get_parser ( *args, **kw ).parse_args()
+	p = get_parser ( command_map=command_map, **kw ).parse_args()
 
 	given = lambda kw : hasattr ( p, kw )
 
@@ -264,13 +269,14 @@ def parse_argv ( *args, **kw ):
 		doconf ( p.distroot, 'distfiles.root' )
 
 	if given ( 'distdirs' ):
+		if given ( 'distroot' ):
+			raise Exception ( "--distdir and --disroot are mutually exclusive!" )
+
 		doconf ( (), 'REPO.config_files' )
 		extra ['distdirs'] = frozenset ( p.distdirs )
 		extra ['nosync']   = True
-		# FIXME: COMMANDS are unknown here (theoretically)
-		commands.append ( "create" )
-		# FIXME:
-		# distdir implies --nosync, but LocalRepo doesn't care about that ( sync() is nosync() )
+		if 'create' in command_map:
+			commands.append ( "create" )
 
 	if given ( 'deprule_file' ):
 		doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2024-08-23  7:28 Benda XU
  0 siblings, 0 replies; 18+ messages in thread
From: Benda XU @ 2024-08-23  7:28 UTC (permalink / raw
  To: gentoo-commits

commit:     633975107b4a543c40454e3bdb7a44c498cb566b
Author:     Benda Xu <heroxbd <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 23 07:26:39 2024 +0000
Commit:     Benda XU <heroxbd <AT> gentoo <DOT> org>
CommitDate: Fri Aug 23 07:28:27 2024 +0000
URL:        https://gitweb.gentoo.org/proj/R_overlay.git/commit/?id=63397510

digest.py: bump to Python 3.11.

portage has a C implementation of Whirlpool as the hash algorithm is
largely unavailable after OpenSSL 3 is released.

Signed-off-by: Benda Xu <heroxbd <AT> gentoo.org>

 roverlay-9999.ebuild | 2 +-
 roverlay/digest.py   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/roverlay-9999.ebuild b/roverlay-9999.ebuild
index a2d2888..3e40ee6 100644
--- a/roverlay-9999.ebuild
+++ b/roverlay-9999.ebuild
@@ -3,7 +3,7 @@
 
 EAPI=7
 
-PYTHON_COMPAT=( python3_8 )
+PYTHON_COMPAT=( python3_11 )
 PYTHON_REQ_USE="ssl,threads(+),readline(+)"
 
 EGIT_REPO_URI='git://anongit.gentoo.org/proj/R_overlay.git'

diff --git a/roverlay/digest.py b/roverlay/digest.py
index 99e094b..ffe2336 100644
--- a/roverlay/digest.py
+++ b/roverlay/digest.py
@@ -68,7 +68,7 @@ if hashlib_supports ( 'whirlpool' ):
    _HASH_CREATE_MAP ['whirlpool'] = hashlib_wrap ( "whirlpool" )
 else:
    import portage.util.whirlpool
-   _HASH_CREATE_MAP ['whirlpool'] = portage.util.whirlpool.new
+   _HASH_CREATE_MAP ['whirlpool'] = portage.util.whirlpool.CWhirlpool
 
 # -- end of imports / HASH_CREATE_MAP
 


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2014-08-23 19:03 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2014-08-23 19:03 UTC (permalink / raw
  To: gentoo-commits

commit:     19c64a0a66ec382fe8e436a7e33f52d75e580fa6
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Aug 23 19:01:52 2014 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Aug 23 19:01:52 2014 +0000
URL:        http://sources.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=19c64a0a

roverlay 0.3.1

---
 VERSION          | 2 +-
 roverlay/core.py | 2 +-
 setup.py         | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/VERSION b/VERSION
index 0d91a54..9e11b32 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.0
+0.3.1

diff --git a/roverlay/core.py b/roverlay/core.py
index 97681d0..4550e81 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -26,7 +26,7 @@ import roverlay.util.common
 
 
 name        = "R_overlay"
-version     = "0.3.0"
+version     = "0.3.1"
 
 description_str = "R overlay creation (roverlay) " + version
 license_str     = (

diff --git a/setup.py b/setup.py
index acc8c3e..fc88200 100755
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ SCRIPT_DIR = os.path.join ( "bin", "install" )
 
 setup (
    name         = 'R_Overlay',
-   version      = "0.3.0",
+   version      = "0.3.1",
    description  = 'Automatically generated overlay of R packages (SoC2012)',
    author       = 'Andr\xe9 Erdmann',
    author_email = 'dywi@mailerd.de',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2014-07-29 20:26 André Erdmann
  2014-08-23 19:03 ` André Erdmann
  0 siblings, 1 reply; 18+ messages in thread
From: André Erdmann @ 2014-07-29 20:26 UTC (permalink / raw
  To: gentoo-commits

commit:     78092d3fc3cbebae86f9ccac956430252bc597e6
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul 29 20:19:11 2014 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul 29 20:19:14 2014 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=78092d3f

roverlay 0.3.0

Changes since 0.2.6:
* a lot of fixes/minor enhancements
* build file changes (Makefile/ebuild, helper scripts)
* addition control feature -- regenerate ebuilds by means of replace/revbump
* partial support for running roverlay on non-Gentoo systems (still TODO)

---
 VERSION          | 2 +-
 roverlay/core.py | 2 +-
 setup.py         | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/VERSION b/VERSION
index 53a75d6..0d91a54 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.6
+0.3.0

diff --git a/roverlay/core.py b/roverlay/core.py
index 2f4215b..97681d0 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -26,7 +26,7 @@ import roverlay.util.common
 
 
 name        = "R_overlay"
-version     = "0.2.6"
+version     = "0.3.0"
 
 description_str = "R overlay creation (roverlay) " + version
 license_str     = (

diff --git a/setup.py b/setup.py
index ccb6037..acc8c3e 100755
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ SCRIPT_DIR = os.path.join ( "bin", "install" )
 
 setup (
    name         = 'R_Overlay',
-   version      = '0.2.6',
+   version      = "0.3.0",
    description  = 'Automatically generated overlay of R packages (SoC2012)',
    author       = 'Andr\xe9 Erdmann',
    author_email = 'dywi@mailerd.de',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-09-23 15:30 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-09-23 15:30 UTC (permalink / raw
  To: gentoo-commits

commit:     154028089fe5f23eaf9ee62a79dc222042937391
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep 23 15:14:25 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep 23 15:14:25 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=15402808

roverlay 0.2.6

Notable changes since 0.2.5:

* package rules
-> else-action block
-> action: run self-test after creation
-> variable substitution in "set_<key> <value>" actions
-> add dependencies to (R)DEPEND and RSUGGESTS (RSUGGESTS doesn't support Depend
   Atoms with versions/slots/...)
-> ignore dependency strings
-> set LICENSE variable

* config files
-> dependency rules
-> use per-repo categories
-> EVENT_HOOK_RC, shell config file for configuring hooks

* hook scripts:
-> git-commit-overlay: reinit git repo
-> git-push: push changes to remote (not enabled by default)
-> run hooks in subshells

* distmap:
[-> partial parsing of ebuild files for getting SRC_URI entries]
-> detect and handle file collisions (package file available in >1 repo)
-> automatically drop orphaned entries
-> add files from imported ebuilds to the distmap (so that the distmap rarely
   needs to be regenerated)

* dependency resolution:
-> dynamic selfdep pool: look up deps in repo-specific pool first

* add LICENSE variable to generated ebuilds (from DESCRIPTION data; package
  rules' LICENSE take precedence)

* (depres) console reimplementation with tab completion, command history,...

* API for external access to roverlay's functionality (mostly depres,
  partially already implemented in 0.2.5)

* persistent stats collection (numbers like ebuild count, failure rate,...)

* helper scripts:
-> roverlay-sh sets up roverlay's hook environment and runs a shell script
   afterwards
-> roverlay-status for generating status reports based on mako templates
-> roverlay-setup for configuring/setting up roverlay automatically

* ebuild: pkg_config() using roverlay-setup, use distutils-r1, git-r3

* bash completion for roverlay, roverlay-status, roverlay-setup

* documentation should be (almost) up-to-date

* a lot of fixes/enhancement, e.g. more meaningful logging of error conditions

---
 roverlay/core.py | 2 +-
 setup.py         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/roverlay/core.py b/roverlay/core.py
index 1a5ac5c..01066c8 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -25,7 +25,7 @@ import roverlay.tools.shenv
 
 
 name        = "R_overlay"
-version     = "0.2.5"
+version     = "0.2.6"
 
 description_str = "R overlay creation (roverlay) " + version
 license_str     = (

diff --git a/setup.py b/setup.py
index 9c9772e..ccb6037 100755
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ SCRIPT_DIR = os.path.join ( "bin", "install" )
 
 setup (
    name         = 'R_Overlay',
-   version      = '0.2.5',
+   version      = '0.2.6',
    description  = 'Automatically generated overlay of R packages (SoC2012)',
    author       = 'Andr\xe9 Erdmann',
    author_email = 'dywi@mailerd.de',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-08-19 15:42 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-08-19 15:42 UTC (permalink / raw
  To: gentoo-commits

commit:     115be915c988c9347ce34366a4cf76420d1137c6
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 19 15:16:53 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 19 15:16:53 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=115be915

fix my name

---
 roverlay/core.py | 2 +-
 setup.py         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/roverlay/core.py b/roverlay/core.py
index be85b0b..8430fd9 100644
--- a/roverlay/core.py
+++ b/roverlay/core.py
@@ -29,7 +29,7 @@ version     = "0.2.5"
 
 description_str = "R overlay creation (roverlay) " + version
 license_str     = (
-   'Copyright (C) 2012, 2013 Andr\xc3\xa9 Erdmann\n'
+   'Copyright (C) 2012, 2013 Andr\xe9 Erdmann\n'
    'Distributed under the terms of the GNU General Public License;\n'
    'either version 2 of the License, or (at your option) any later version.\n'
 )

diff --git a/setup.py b/setup.py
index 90f52ff..ae99cd5 100755
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ setup (
    name         = 'R_Overlay',
    version      = '0.2.5',
    description  = 'Automatically generated overlay of R packages (SoC2012)',
-   author       = 'André Erdmann',
+   author       = 'Andr\xe9 Erdmann',
    author_email = 'dywi@mailerd.de',
    license      = 'GPLv2+',
    url          = 'http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=summary',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-08-09 10:18 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-08-09 10:18 UTC (permalink / raw
  To: gentoo-commits

commit:     f5b1a9ab8aab7175eacc0a78005fe5ddb0ed9b41
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Aug  9 10:06:41 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Aug  9 10:06:41 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f5b1a9ab

clean up main script / arg parsing

This commit is a (more or less) complete rewrite of roverlay's arg parsing.

Notable differences/changes:
* fixes name clash issues / "hidden" imports; all modules can now be imported
  at the beginning of the file
* usage of a "runtime environment" data object instead of global variables
  run_<command>() functions use this environment (passed as first arg) now
* extensible/modular arg parser creation, which allows to write helper scripts
  with a reduced set of options

---
 roverlay.py               |   6 +-
 roverlay/argparser.py     | 604 ++++++++++++++++++++++++++++++++++++++
 roverlay/argutil.py       | 717 ++++++++++++++--------------------------------
 roverlay/defaultscript.py | 426 +++++++++++++++++++++++++++
 roverlay/main.py          | 592 --------------------------------------
 roverlay/runtime.py       | 152 ++++++++++
 setup.py                  |   6 +-
 7 files changed, 1401 insertions(+), 1102 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index fd1b3e8..a17ff80 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -1,11 +1,11 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 # R overlay -- main script
-# Copyright (C) 2012 André Erdmann <dywi@mailerd.de>
+# Copyright (C) 2012, 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 roverlay.main
+import roverlay.defaultscript
 
 if __name__ == '__main__':
-	roverlay.main.main ( False )
+	roverlay.defaultscript.main ( False )

diff --git a/roverlay/argparser.py b/roverlay/argparser.py
new file mode 100644
index 0000000..054d710
--- /dev/null
+++ b/roverlay/argparser.py
@@ -0,0 +1,604 @@
+# R overlay -- roverlay package, arg parser
+# -*- coding: utf-8 -*-
+# Copyright (C) 2012, 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 argparse
+import collections
+
+import roverlay.core
+import roverlay.argutil
+import roverlay.util.objects
+
+# lazy import
+from roverlay.argutil import \
+   couldbe_fs_dir, couldbe_fs_file, couldbe_stdout_or_file, \
+   get_gid, is_gid, get_uid, is_uid, \
+   is_fs_dir, is_fs_dir_or_void, is_fs_file, \
+   is_fs_file_or_dir, is_fs_file_or_void, \
+   ArgumentParserProxy
+
+
+class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ):
+   def __init__ (
+      self, defaults=None, description=True, formatter_class=True, **kwargs
+   ):
+      super ( RoverlayArgumentParserBase, self ).__init__ (
+         defaults = defaults,
+         description = (
+            '\n'.join ((
+               roverlay.core.description_str, roverlay.core.license_str
+            )) if description is True else description
+         ),
+         formatter_class = (
+            argparse.RawDescriptionHelpFormatter
+            if formatter_class is True else formatter_class
+         ),
+         **kwargs
+      )
+
+
+      self.extra_conf = None
+   # --- end of __init__ (...) ---
+
+   def do_extraconf ( self, value, path ):
+      pos = self.extra_conf
+      if isinstance ( path, str ):
+         path = path.split ( '.' )
+
+      last = len ( path ) - 1
+      for i, k in enumerate ( path ):
+         if i == last:
+            pos [k.lower()] = value
+         else:
+            k = k.upper()
+            if not k in pos:
+               pos [k] = dict()
+
+            pos = pos [k]
+
+      return pos
+   # --- end of do_extraconf (...) ---
+
+   def do_extraconf_simple ( self, attr_name, path ):
+      if attr_name in self.parsed:
+         self.do_extraconf ( self.parsed[attr_name], path )
+         return True
+      else:
+         return False
+   # --- end of do_extraconf_simple (...) ---
+
+   def parse ( self, *args, **kwargs ):
+      self.parse_args ( *args, **kwargs )
+      parsed          = vars ( self.parsed )
+      self.parsed     = parsed
+      self.extra_conf = dict()
+
+      conf_ifdef = self.do_extraconf_simple
+
+      # config
+      conf_ifdef ( 'field_definition', 'DESCRIPTION.field_definition_file' )
+      conf_ifdef ( 'repo_config', 'REPO.config_files' )
+      conf_ifdef ( 'deprule_file', 'DEPRES.SIMPLE_RULES.files' )
+      conf_ifdef ( 'package_rules', 'PACKAGE_RULES.files' )
+
+
+      # overlay
+      conf_ifdef ( 'overlay_dir', 'OVERLAY.dir' )
+      conf_ifdef ( 'overlay_name', 'OVERLAY.name' )
+      conf_ifdef ( 'additions_dir', 'OVERLAY.additions_dir' )
+      if 'write_overlay' in parsed:
+         self.do_extraconf (
+            not ( parsed ['write_overlay'] ), 'write_disabled'
+         )
+
+
+      # remote_minimal
+      if 'sync' in parsed:
+         self.do_extraconf ( not ( parsed ['sync'] ), 'nosync' )
+
+
+      # remote
+      if conf_ifdef ( 'distroot', 'DISTFILES.root' ):
+         if 'local_distdirs' in parsed:
+            raise Exception (
+               "--force-distroot and --distroot are mutually exclusive."
+            )
+      elif 'local_distdirs' in parsed:
+         parsed ['local_distdirs'] = frozenset ( parsed ['local_distdirs'] )
+
+         # --from implies --no-sync and disables all repo config files
+         self.do_extraconf ( (), 'REPO.config_files' )
+         self.do_extraconf ( True, 'nosync' )
+
+
+      # overlay creation
+      conf_ifdef ( 'distmap_verify', 'OVERLAY.DISTDIR.verify' )
+      conf_ifdef (
+         'manifest_implementation', 'OVERLAY.manifest_implementation'
+      )
+
+      if (
+         parsed.get ( 'fixup_category_move' ) and
+         parsed.get ( 'fixup_category_move_reverse' )
+      ) or (
+         not parsed.get ( 'incremental', True ) and (
+            parsed.get ( 'fixup_category_move' ) or
+            parsed.get ( 'fixup_category_move_reverse' )
+         )
+      ):
+         raise Exception (
+            'mutually exclusive: --fixup-category-move{,-reverse}, '
+            '--no-incremental'
+         )
+
+
+      if hasattr ( self.__class__, 'PARSE_TARGETS' ):
+         for attr in self.__class__.PARSE_TARGETS:
+            getattr ( self, 'parse_' + attr )()
+   # --- end of parse (...) ---
+
+   def setup ( self ):
+      if hasattr ( self.__class__, 'SETUP_TARGETS' ):
+         for attr in self.__class__.SETUP_TARGETS:
+            getattr ( self, 'setup_' + attr )()
+      else:
+         raise roverlay.util.objects.AbstractMethodError ( self, 'setup' )
+   # --- end of setup (...) ---
+
+   def setup_version ( self ):
+      self.arg (
+         '-V', '--version', action='version',
+         version=self.defaults.get ( "version", roverlay.core.version )
+      )
+   # --- end of setup_version (...) ---
+
+   def setup_config_minimal ( self ):
+      config_arg = self.add_argument_group (
+         'config', title='config file options'
+      )
+
+      config_arg (
+         '-c', '--config', dest='config_file', help='config_file',
+         type=is_fs_file_or_void,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_META_FILE,
+      )
+
+      return config_arg
+   # --- end of setup_config_minimal (...) ---
+
+   def parse_config ( self ):
+      if not self.parsed ['config_file']:
+         roverlay.core.die (
+            "No config file found.\n", roverlay.core.DIE.CONFIG
+         )
+   # --- end of parse_config (...) ---
+
+   def setup_config ( self ):
+      config_arg = self.setup_config_minimal()
+
+      config_arg (
+         '-F', '--field-definition', '--fdef', dest='field_definition',
+         default=argparse.SUPPRESS, type=is_fs_file,
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_FILE,
+         help="field definition file",
+      )
+
+      config_arg (
+         '-R', '--repo-config', dest='repo_config',
+         default=argparse.SUPPRESS, type=is_fs_file, action='append',
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_FILE,
+         help="repo config file(s)",
+      )
+
+      config_arg (
+         '-D', '--deprule-file', dest='deprule_file',
+         default=argparse.SUPPRESS, type=is_fs_file_or_dir,
+         action='append',
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_FILEDIR,
+         help="dependency rule file(s)",
+      )
+
+      config_arg (
+         '-P', '--package-rules', dest='package_rules',
+         default=argparse.SUPPRESS, type=is_fs_file_or_dir,
+         action='append',
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_FILEDIR,
+         help="package rule file(s)",
+      )
+
+      return config_arg
+   # --- end of setup_config (...) ---
+
+   def setup_overlay_minimal ( self ):
+      arg = self.add_argument_group (
+         'overlay', title='overlay options'
+      )
+      ## !!! INCREMENTAL_MUTEX
+
+      arg (
+         '-O', '--overlay', dest='overlay_dir',
+         default=argparse.SUPPRESS, type=couldbe_fs_dir,
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_DIR,
+         help="overlay directory (implies --write-overlay)",
+      )
+
+      arg (
+         '-N', '--overlay-name', dest='overlay_name',
+         default=argparse.SUPPRESS, metavar='<name>',
+         flags=self.ARG_ADD_DEFAULT,
+         help="overlay name",
+      )
+
+      arg (
+         '-A', '--additions-dir', dest='additions_dir',
+         default=argparse.SUPPRESS,
+         flags=self.ARG_ADD_DEFAULT|self.ARG_META_DIR,
+         type=is_fs_dir_or_void,
+         help="directory containing patches and hand-written ebuilds",
+      )
+
+      arg (
+         '--write-overlay', '--write', dest='write_overlay',
+         default=True, flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="allow overlay writing",
+      )
+      arg (
+         '--no-write-overlay', '--no-write', dest='write_overlay',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="forbid overlay writing",
+      )
+
+      arg (
+         '--show-overlay', '--show', dest='show_overlay',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="print the overlay to stdout",
+      )
+      arg (
+         '--no-show-overlay', '--no-show', dest='show_overlay',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="don\'t print the overlay",
+      )
+
+
+      return arg
+   # --- end of setup_overlay_minimal (...) ---
+
+   def setup_overlay ( self ):
+      arg = self.setup_overlay_minimal()
+
+      return arg
+   # --- end of setup_overlay (...) ---
+
+   def setup_overlay_creation ( self ):
+      arg = self.add_argument_group (
+         "overlay_creation", title='overlay creation options',
+      )
+
+      arg (
+         '--incremental', dest='incremental', default=True,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="scan for existing and do not recreate them",
+      )
+      arg (
+         '--no-incremental', dest='incremental',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="do not scan for existing ebuilds (recreate all)",
+      )
+
+      arg (
+         '--fixup-category-move', dest='fixup_category_move',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help=(
+            'remove packages from the default category if '
+            'they exist in another one'
+         ),
+      )
+      arg (
+         '--fixup-category-move-reverse', dest='fixup_category_move_reverse',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help=(
+            'remove packages from other categories if they exist in the '
+            'default one'
+         ),
+      )
+
+      arg (
+         '--distmap-verify', dest='distmap_verify',
+         default=argparse.SUPPRESS,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help=(
+            'check integrity of files in the mirror directory and '
+            'update the distmap file'
+         ),
+      )
+
+      arg (
+         '--revbump', dest='revbump', default=True,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="revbump on package file checksum change",
+      )
+      arg (
+         '--no-revbump', dest='revbump',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="disable revbump feature (saves time)",
+      )
+
+      arg (
+         '--immediate-ebuild-writes', dest='immediate_ebuild_writes',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help=(
+            'write ebuilds as soon as they\'re ready, which saves '
+            'memory but costs more time'
+         ),
+      )
+
+      arg (
+         '--manifest', dest='manifest', default=True,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="enable Manifest creation",
+      )
+      arg (
+         '--no-manifest', dest='manifest',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="skip Manifest creation (results in useless overlay)",
+      )
+
+      arg (
+         '-M', '--manifest-implementation', dest='manifest_implementation',
+         choices=( 'default', 'next', 'ebuild', 'e' ),
+         default=argparse.SUPPRESS, flags=self.ARG_WITH_DEFAULT,
+         help="choose how Manifest files are created (ebuild(1) or internal)",
+      )
+   # --- end of setup_overlay_creation (...) ---
+
+   def setup_remote_minimal ( self ):
+      arg = self.add_argument_group ( "remote", title="sync options" )
+
+      arg (
+         '--strict-sync', dest='strict_sync',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="exit if any repository cannot be used",
+      )
+
+      arg (
+         '--sync', dest='sync', default=argparse.SUPPRESS,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="allow syncing with remotes",
+      )
+      arg (
+         '--nosync', '--no-sync', dest='sync',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="forbid syncing with remotes (offline mode)",
+      )
+
+      return arg
+   # --- end of setup_remote_minimal (...) ---
+
+   def setup_remote ( self ):
+      arg = self.setup_remote_minimal()
+
+      arg (
+         '--sync-imports', dest='sync_imports',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help=(
+            'allow fetching of source files for imported ebuilds even if '
+            'sync is forbidden'
+         ),
+      )
+
+      arg (
+         '--distroot', dest='distroot', default=argparse.SUPPRESS,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_META_DIR,
+         type=couldbe_fs_dir,
+         help=(
+            'use %(metavar)s as distdir root directory for repositories '
+            'that don\'t declare their own package directory.'
+         ),
+      )
+
+      arg (
+         '--force-distroot', dest='force_distroot',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help='always use package directories in --distroot',
+      )
+
+      arg (
+         '--local-distdir', '--from', dest='local_distdirs',
+         action='append', default=argparse.SUPPRESS,
+         flags=self.ARG_META_DIR, type=is_fs_dir,
+         help=(
+            'ignore all repos and use packages from %(metavar)s for '
+            'ebuild creation. only useful for testing since SRC_URI '
+            'will be invalid. [disabled]'
+         ),
+      )
+
+      return arg
+   # --- end of setup_remote (...) ---
+
+   def setup_misc_minimal ( self ):
+      arg = self.add_argument_group ( "misc", title="misc options" )
+
+      arg (
+         '--strict', dest='strict',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="enable all --strict options",
+      )
+
+      arg (
+         '--stats', dest='print_stats', default=True,
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help="print some stats",
+      )
+      arg (
+         '--no-stats', dest='print_stats',
+         flags=self.ARG_SHARED_INVERSE|self.ARG_OPT_OUT,
+         help="don\'t print stats"
+      )
+
+      arg (
+         '--dump-stats', dest='dump_stats',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_OPT_IN,
+         help='print all stats to stdout at exit (raw format)',
+      )
+
+
+      return arg
+   # --- end of setup_misc_minimal (...) ---
+
+   def setup_misc ( self ):
+      return self.setup_misc_minimal()
+   # --- end of setup_misc (...) ---
+
+
+# --- end of RoverlayArgumentParserBase ---
+
+class RoverlayMainArgumentParser ( RoverlayArgumentParserBase ):
+
+   SETUP_TARGETS = (
+      'version', 'actions', 'config', 'overlay', 'remote',
+      'overlay_creation', 'setupdirs', 'additional_actions', 'misc',
+   )
+   PARSE_TARGETS = ( 'actions', 'config', )
+
+   COMMAND_DESCRIPTION = collections.OrderedDict ((
+      ( 'sync', 'sync repos' ),
+      (
+         'create',
+         'create the overlay (implies sync, override with --no-sync)'
+      ),
+      (
+         'depres_console',
+         'run an interactive depres console (highly experimental)'
+      ),
+      ( 'depres', 'this is an alias to \'depres_console\'' ),
+      ( 'nop', 'do nothing' ),
+      (
+         'apply_rules',
+         'apply package rules verbosely and exit afterwards'
+      ),
+      ( 'setupdirs', 'create configured directories etc.' ),
+   ))
+
+   DEFAULT_COMMAND = 'create'
+
+   def __init__ ( self, default_command=None, command_desc=None,**kwargs ):
+      super ( RoverlayMainArgumentParser, self ).__init__ ( **kwargs )
+
+      self.default_command = (
+         self.DEFAULT_COMMAND if default_command is None else default_command
+      )
+      self.command_desc = (
+         self.COMMAND_DESCRIPTION if command_desc is None else command_desc
+      )
+
+      self.command = None
+
+      assert self.default_command in self.command_desc
+   # --- end of __init__ (...) ---
+
+   def parse_actions ( self ):
+      command = self.parsed ['command']
+
+      if command == 'nop':
+         roverlay.core.die ( "Nothing to do!", roverlay.core.DIE.NOP )
+
+      elif command == 'setupdirs':
+         self.parsed ['want_logging']   = False
+         self.parsed ['load_main_only'] = True
+
+      else:
+         self.parsed ['want_logging']   = True
+         self.parsed ['load_main_only'] = False
+
+         if command == 'sync' and not self.parsed.get ( 'sync', True ):
+            roverlay.core.die (
+               "sync command blocked by --no-sync opt.", roverlay.core.DIE.ARG
+            )
+
+      self.command = command
+   # --- end of parse_actions (...) ---
+
+   def setup_actions ( self ):
+      arg = self.add_argument_group (
+         "actions", title="actions",
+         description=(
+            "\nKnown commands:\n" + '\n'.join (
+               # '* <space> <command> - <command description>'
+               '* {cmd} - {desc}'.format (
+                  cmd=cmd.ljust ( 15 ), desc=desc
+               ) for cmd, desc in self.command_desc.items()
+            )
+         )
+      )
+
+      arg (
+         'command', default=self.default_command, metavar='<action>',
+         nargs="?", choices=self.command_desc.keys(),
+         flags=self.ARG_HELP_DEFAULT,
+         help="action to perform"
+      )
+
+      return arg
+   # --- end of setup_actions (...) ---
+
+   def setup_setupdirs ( self ):
+      arg = self.add_argument_group (
+         'setupdirs', title='setupdirs options',
+      )
+
+      arg (
+         '--target-uid', dest='target_uid', default=os.getuid(),
+         metavar='<uid>', type=is_uid, flags=self.ARG_WITH_DEFAULT,
+         help='uid of the user that will run roverlay',
+      )
+      arg (
+         '--target-gid', dest='target_gid', default=os.getgid(),
+         metavar='<gid>', type=is_gid, flags=self.ARG_WITH_DEFAULT,
+         help='gid of the user that will run roverlay',
+      )
+
+
+      return arg
+   # --- end of setup_setupdirs (...) ---
+
+   def setup_additional_actions ( self ):
+      arg = self.add_argument_group (
+         "additional_actions", title='additional actions',
+      )
+
+      arg (
+         '--pc', '--print-config', dest='print_config',
+         flags=self.ARG_OPT_IN,
+         help="print config and exit",
+      )
+
+      arg (
+         '--ppr', '--print-package-rules', dest='print_package_rules',
+         flags=self.ARG_OPT_IN,
+         help="print package rules after parsing them and exit",
+      )
+
+      arg (
+         '--help-config', '--list-config-entries',
+         dest='list_config_entries', flags=self.ARG_OPT_IN,
+         help="list all known config entries and exit",
+      )
+
+
+      arg (
+         '--dump-file', dest='dump_file', default='-',
+         flags=self.ARG_WITH_DEFAULT|self.ARG_META_FILE,
+         type=couldbe_stdout_or_file,
+         help=(
+            'file or stdout (\"-\") target for dumping information. '
+            'Used by the \'apply_rules\' command.'
+         ),
+      )
+
+      return arg
+   # --- end of setup_additional_actions (...) ---
+# --- end of RoverlayMainArgumentParser ---

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 13f23df..8370b98 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -1,20 +1,14 @@
 # R overlay -- roverlay package, argutil
 # -*- coding: utf-8 -*-
-# Copyright (C) 2012 André Erdmann <dywi@mailerd.de>
+# Copyright (C) 2012, 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.
 
-"""provides arg parsing for the roverlay main script"""
-
-__all__ = [ 'parse_argv', ]
-
 import os
 import argparse
 import pwd
 import grp
 
-import roverlay.core
-
 def get_uid ( user ):
    try:
       return int ( user )
@@ -31,551 +25,266 @@ def get_gid ( group ):
       pass
    return grp.getgrnam ( group ).gr_gid
 
+def is_uid ( value ):
+   try:
+      return get_uid ( value )
+   except:
+      pass
+   raise argparse.ArgumentTypeError (
+      "no such user/uid: {}".format ( value )
+   )
 
-def get_parser ( command_map, default_config_file, default_command='create' ):
-   """Returns an arg parsers.
-
-   arguments:
-   * command_map         -- a dict ( <command> => <command description> )
-   * default_config_file -- the default config file (for --config)
-   * default_command     -- the default command
-   """
-
-   def is_uid ( value ):
-      try:
-         return get_uid ( value )
-      except:
-         pass
-      raise argparse.ArgumentTypeError (
-         "no such user/uid: {}".format ( value )
-      )
-
-   def is_gid ( value ):
-      try:
-         return get_gid ( value )
-      except:
-         pass
-      raise argparse.ArgumentTypeError (
-         "no such group/gid: {}".format ( value )
-      )
-
-   def is_fs_file ( value ):
-      f = os.path.abspath ( value )
-      if not os.path.isfile ( f ):
-         raise argparse.ArgumentTypeError (
-            "{!r} is not a file.".format ( value )
-         )
-      return f
-
-   def couldbe_fs_file ( value ):
-      if value:
-         f = os.path.abspath ( value )
-         if not os.path.exists ( f ) or os.path.isfile ( f ):
-            return f
+def is_gid ( value ):
+   try:
+      return get_gid ( value )
+   except:
+      pass
+   raise argparse.ArgumentTypeError (
+      "no such group/gid: {}".format ( value )
+   )
 
+def is_fs_file ( value ):
+   f = os.path.abspath ( value )
+   if not os.path.isfile ( f ):
       raise argparse.ArgumentTypeError (
          "{!r} is not a file.".format ( value )
       )
+   return f
 
-   def couldbe_stdout_or_file ( value ):
-      return value if value == "-" else couldbe_fs_file ( value )
-
-   def is_fs_dir ( value ):
-      d = os.path.abspath ( value )
-      if not os.path.isdir ( d ):
-         raise argparse.ArgumentTypeError (
-            "{!r} is not a directory.".format ( value )
-         )
-      return d
-
-   def is_fs_file_or_dir ( value ):
+def couldbe_fs_file ( value ):
+   if value:
       f = os.path.abspath ( value )
-      if os.path.isdir ( f ) or os.path.isfile ( f ):
+      if not os.path.exists ( f ) or os.path.isfile ( f ):
          return f
-      else:
-         raise argparse.ArgumentTypeError (
-            "{!r} is neither a file nor a directory.".format ( value )
-         )
-
-   def couldbe_fs_dir ( value ):
-      d = os.path.abspath ( value )
-      if os.path.exists ( d ) and not os.path.isdir ( d ):
-         raise argparse.ArgumentTypeError (
-            "{!r} cannot be a directory.".format ( value )
-         )
-      return d
-
-   def is_fs_dir_or_void ( value ):
-      if value:
-         return is_fs_dir ( value )
-      else:
-         return ''
-
-   def is_fs_file_or_void ( value ):
-      if value:
-         return is_fs_file ( value )
-      else:
-         return ''
-
-   parser = argparse.ArgumentParser (
-      description='\n'.join ((
-         roverlay.core.description_str, roverlay.core.license_str,
-      )),
-      epilog = 'Known commands:\n' + '\n'.join (
-         (
-            # '* <space> <command> - <command description>'
-            '* {cmd} - {desc}'.format (
-               cmd  = i [0].ljust ( 15 ),
-               desc = i [1]
-            ) for i in command_map.items()
-         )
-      ),
-      add_help=True,
-      formatter_class=argparse.RawDescriptionHelpFormatter,
-   )
-
-   incremental_mutex = parser.add_mutually_exclusive_group()
-
-   arg     = parser.add_argument
-   opt_in  = dict ( default=False, action='store_true' )
-   opt_out = dict ( default=True,  action='store_false' )
-
-   fs_file = dict ( type=is_fs_file, metavar="<file>" )
-
-   # adding args starts here
-
-   arg (
-      '-V', '--version', action='version', version=roverlay.core.version
-   )
-
-   arg (
-      'commands',
-      default=default_command,
-      help=(
-         'action to perform. choices are ' + ', '.join (command_map.keys())
-         + '. defaults to %(default)s.'
-      ),
-      nargs="*",
-      choices=command_map.keys(),
-      metavar="command"
-   )
-
-   arg (
-      '-c', '--config',
-      default=default_config_file,
-      help="config file",
-      type=is_fs_file_or_void, metavar="<file>"
-   )
-   arg (
-      '-F', '--field-definition', '--fdef', default=argparse.SUPPRESS,
-      help="field definition file",
-      **fs_file
-   )
-
-   arg (
-      '-R', '--repo-config', default=argparse.SUPPRESS,
-      action='append',
-      help="repo config file.",
-      **fs_file
-   )
-
-   arg (
-      '-D', '--deprule-file', default=argparse.SUPPRESS,
-      action='append',
-      help="simple rule file. can be specified more than once.",
-      type=is_fs_file_or_dir,
-      metavar='<file|dir>',
-   )
-
-   arg (
-      '-P', '--package-rules', default=argparse.SUPPRESS,
-      action='append',
-      help="package rule file, can be specified more than once.",
-      type=is_fs_file_or_dir,
-      metavar='<file|dir>',
-   )
-
-   arg (
-      '--local-distdir', '--from', default=argparse.SUPPRESS,
-      action='append',
-      help='''
-         use packages from %(metavar)s for ebuild creation (ignore all repos).
-         only useful for testing 'cause SRC_URI will be invalid in the created
-         ebuilds.
-      ''',
-      metavar="<DISTDIR>",
-      dest='distdirs',
-      type=is_fs_dir
-   )
-
-   arg (
-      '--distroot', default=argparse.SUPPRESS,
-      help='''
-         use %(metavar)s as distdir root for repos
-         that don't define their own package dir.
-      ''',
-      metavar="<DISTROOT>",
-      type=couldbe_fs_dir
-   )
-
-   arg (
-      '--overlay', '-O', default=argparse.SUPPRESS,
-      help='overlay directory to write (implies --write)',
-      metavar="<OVERLAY>",
-      type=couldbe_fs_dir
-   )
 
-   arg (
-      '--additions-dir', '-A', # '--patch-dir',  '--ebuild-dir',
-      default=argparse.SUPPRESS,
-      help="directory containing patches and hand-written ebuilds",
-      metavar="<dir>",
-      type=is_fs_dir_or_void
+   raise argparse.ArgumentTypeError (
+      "{!r} is not a file.".format ( value )
    )
 
-   arg (
-      '--overlay-name', '-N', default=argparse.SUPPRESS,
-      help="overlay name",
-      metavar="<name>",
-      dest="overlay_name"
-   )
+def couldbe_stdout_or_file ( value ):
+   return value if value == "-" else couldbe_fs_file ( value )
 
-   arg (
-      '--show-overlay', '--show',
-      help="print ebuilds and metadata to console",
-      dest="show_overlay",
-      default=False,
-      action="store_true",
-   )
+def is_fs_dir ( value ):
+   d = os.path.abspath ( value )
+   if not os.path.isdir ( d ):
+      raise argparse.ArgumentTypeError (
+         "{!r} is not a directory.".format ( value )
+      )
+   return d
 
-   arg (
-      '--no-show-overlay', '--no-show',
-      help="don't print ebuilds and metadata to console (default)",
-      dest="show_overlay",
-      action="store_false",
-   )
+def is_fs_file_or_dir ( value ):
+   f = os.path.abspath ( value )
+   if os.path.isdir ( f ) or os.path.isfile ( f ):
+      return f
+   else:
+      raise argparse.ArgumentTypeError (
+         "{!r} is neither a file nor a directory.".format ( value )
+      )
 
-   arg (
-      '--write-overlay', '--write',
-      help="write the overlay to filesystem",
-      dest="write_overlay",
-      default=True,
-      action="store_true",
-   )
+def couldbe_fs_dir ( value ):
+   d = os.path.abspath ( value )
+   if os.path.exists ( d ) and not os.path.isdir ( d ):
+      raise argparse.ArgumentTypeError (
+         "{!r} cannot be a directory.".format ( value )
+      )
+   return d
 
-   arg (
-      '--no-write-overlay', '--no-write',
-      help="don't write the overlay",
-      dest="write_overlay",
-      action="store_false",
-   )
+def is_fs_dir_or_void ( value ):
+   if value:
+      return is_fs_dir ( value )
+   else:
+      return ''
 
-   arg (
-      '--immediate-ebuild-writes',
-      help='write ebuilds as soon as they\'re ready, '
-         'which saves memory but costs more time',
-      dest='immediate_ebuild_writes',
-      default=False,
-      action='store_true',
-   )
+def is_fs_file_or_void ( value ):
+   if value:
+      return is_fs_file ( value )
+   else:
+      return ''
 
-   incremental_mutex.add_argument (
-      '--fixup-category-move',
-      help='''
-         remove packages from the default category
-         if they exist in another one
-      ''',
-      dest='fixup_category_move',
-      default=None,
-      action='store_true'
-   )
 
-   incremental_mutex.add_argument (
-      '--fixup-category-move-reverse',
-      help='''
-         remove packages from other categories if they exist in the
-         default one
-      ''',
-      default=None,
-      dest='fixup_category_move_rev',
-      action='store_true'
-   )
+class ArgumentParserError ( Exception ):
+   pass
 
-   arg (
-      '--distmap-verify', default=argparse.SUPPRESS,
-      help   = 'check integrity of files in OVERLAY_DISTDIR_ROOT',
-      dest   = 'distmap_verify',
-      action = 'store_true',
-   )
-
-   arg (
-      '--stats',
-      help="print some stats",
-      dest="stats",
-      default=True,
-      action="store_true",
-   )
+class ArgumentGroupExists ( ArgumentParserError ):
+   pass
 
-   arg (
-      '--no-stats',
-      help="don't print stats",
-      dest="stats",
-      action="store_false",
-   )
+class ArgumentFlagException ( ArgumentParserError ):
+   pass
 
-   arg (
-      '--dump-stats',
-      help='print all stats to stdout (raw format)',
-      default=False,
-      action='store_true',
-   )
-
-   arg (
-      '--strict',
-      help='enable all --strict-<sth> options',
-      default=False,
-      action='store_true',
-   )
 
-   arg (
-      '--strict-sync',
-      help='exit on any sync errors',
-      default=False,
-      action='store_true',
-   )
+class ArgumentParserProxy ( object ):
 
-   arg (
-      '--nosync', '--no-sync', default=argparse.SUPPRESS,
-      help="disable syncing with remotes (offline mode).",
-      action='store_true',
-   )
+   ARG_ADD_DEFAULT  = 2**0
+   # OPT_IN: store True
+   ARG_OPT_IN       = 2**1
+   # OPT_OUT: store False
+   ARG_OPT_OUT      = 2**2
+   ARG_SHARED       = 2**4
+   ARG_HELP_DEFAULT = 2**5
+   ARG_META_FILE    = 2**6
+   ARG_META_DIR     = 2**7
+   ARG_INVERSE      = 2**8
 
-   arg (
-      '--sync-imports',
-      default=None, dest='sync_imported',
-      help=(
-         'allow fetching src files for imported ebuilds even if sync '
-         'is forbidden'
-      ),
-      action='store_true',
-   )
+   ARG_SHARED_INVERSE = ARG_SHARED | ARG_INVERSE
+   ARG_META_FILEDIR   = ARG_META_FILE | ARG_META_DIR
+   ARG_WITH_DEFAULT   = ARG_ADD_DEFAULT | ARG_HELP_DEFAULT
 
-   arg (
-      '--force-distroot',
-      help="always use <DISTROOT>/<repo name> as repo distdir.",
-      **opt_in
-   )
+   STR_TRUE     = 'enabled'
+   STR_FALSE    = 'disabled'
+   STR_SUPPRESS = 'keep'
 
-   arg (
-      '--print-config', '--pc',
-      help="print config and exit",
-      **opt_in
-   )
 
-   arg (
-      '--print-package-rules', '--ppr',
-      help="print package rules after parsing them and exit",
-      **opt_in
-   )
 
-   arg (
-      '--list-config-entries', '--help-config',
-      help="list all known config entries",
-      **opt_in
-   )
 
-   # --write-desc
-   # --log-level, --log-console, --log...
+   def __init__ ( self, defaults=None, **kwargs ):
+      super ( ArgumentParserProxy, self ).__init__()
+      self.parser = argparse.ArgumentParser (**kwargs )
 
-   arg (
-      '--no-manifest',
-      help="skip Manifest creation (results in useless overlay)",
-      **opt_in
-   )
-
-   arg (
-      '--manifest-implementation', '-M', default=argparse.SUPPRESS,
-      help="choose how Manifest files are written (ebuild(1) or portage libs)",
-      metavar="<impl>",
-      choices=frozenset (( 'ebuild', 'e', 'next', )),
-   )
-
-   # FIXME: description of --no-incremental is not correct,
-   # --no-incremental currently means that an existing overlay won't be
-   # scanned for ebuilds (which means that ebuilds will be recreated),
-   # but old ebuilds won't be explicitly removed
-   incremental_mutex.add_argument (
-      '--no-incremental',
-      help="start overlay creation from scratch (ignore an existing overlay)",
-      dest='incremental',
-      default=True,
-      action='store_false',
-   )
+      if defaults is None:
+         self.defaults = dict()
+      elif isinstance ( defaults, dict ):
+         self.defaults = defaults
+      else:
+         self.defaults = dict ( defaults )
 
-   arg (
-      '--no-revbump',
-      help="disable revbump-on-tarball change (saves time)",
-      dest='revbump',
-      default=True,
-      action='store_false',
-   )
+      self._argument_groups = dict()
 
-   arg (
-      '--dump-file',
-      help='''
-         standard file or stdout target for dumping information
-         (defaults to '-'). Used by the 'apply_rules' action.
-      ''',
-      dest="dump_file",
-      default="-",
-      metavar="<file>",
-      type=couldbe_stdout_or_file,
-   )
+      self.parsed = None
+   # --- end of __init__ (...) ---
 
-   arg (
-      '--target-uid',
-      metavar="<uid>",
-      help="setupdirs command: uid of the user that will run roverlay",
-      default=os.getuid(),
-      type=is_uid,
-   )
+   def get_default ( self, key, *args ):
+      return self.defaults.get ( key, *args )
+   # --- end of get_default (...) ---
 
-   arg (
-      '--target-gid',
-      metavar="<gid>",
-      help="setupdirs command: gid of the user that will run roverlay",
-      default=os.getgid(),
-      type=is_gid,
-   )
+   def apply_arg_flags ( self, kwargs, flags ):
 
+      if flags & self.ARG_SHARED and 'default' not in kwargs:
+         kwargs ['default'] = argparse.SUPPRESS
 
-#   # TODO
-#   arg (
-#      '--debug',
-#      help='''
-#         Turn on debugging. This produces a lot of messages.
-#         (TODO: has no effect).
-#      ''',
-#      **opt_in
-#   )
-
-   return parser
-# --- end of get_parser (...) ---
-
-def parse_argv ( command_map, **kw ):
-   """Parses sys.argv and returns the result as tuple
-   (<commands to run>, <config file>,
-   <dict for config>, <extra options as dict>).
-
-   All args/keywords are passed to get_parser().
-   Passes all exceptions.
-   """
-   p = get_parser ( command_map=command_map, **kw ).parse_args()
-
-   def doconf ( value, path ):
-      pos = conf
-      if isinstance ( path, str ):
-         path = path.split ( '.' )
-      last = len ( path ) - 1
-      for i, k in enumerate ( path ):
-         if i == last:
-            pos [k.lower()] = value
+      if flags & self.ARG_OPT_IN:
+         if flags & self.ARG_OPT_OUT:
+            raise ArgumentFlagException (
+               "opt-in and opt-out are mutually exclusive."
+            )
          else:
-            k = k.upper()
-            if not k in pos:
-               pos [k] = dict()
-
-            pos = pos [k]
-   # --- end of doconf (...) ---
-
-   def given ( attr_name ):
-      return hasattr ( p, attr_name )
-   # --- end of given (...) ---
-
-   def doconf_simple ( attr_name, config_path ) :
-      value = getattr ( p, attr_name, None )
-      if value is not None:
-         doconf ( value, config_path )
-   # --- end of doconf_simple (...) ---
-
-   commands = (
-      ( p.commands, ) if isinstance ( p.commands, str ) else p.commands
-   )
-   conf  = dict()
-   extra = dict (
-# TODO: remove nosync entirely from extra
-#      nosync                  = p.nosync,
-#      debug                   = p.debug,
-      show_overlay            = p.show_overlay,
-      write_overlay           = p.write_overlay,
-      print_stats             = p.stats,
-      print_config            = p.print_config,
-      list_config             = p.list_config_entries,
-      print_package_rules     = p.print_package_rules,
-      force_distroot          = p.force_distroot,
-      skip_manifest           = p.no_manifest,
-      incremental             = p.incremental,
-      revbump                 = p.revbump,
-      immediate_ebuild_writes = p.immediate_ebuild_writes,
-      dump_file               = p.dump_file,
-      fixup_category_move     = p.fixup_category_move,
-      fixup_category_move_rev = p.fixup_category_move_rev,
-      target_uid              = p.target_uid,
-      target_gid              = p.target_gid,
-      dump_stats              = p.dump_stats,
-      sync_imported           = p.sync_imported,
-      strict                  = p.strict,
-      strict_sync             = p.strict_sync,
-   )
-
-
-   if given ( 'overlay' ):
-      doconf ( p.overlay, 'OVERLAY.dir' )
-      #extra ['write_overlay'] = True
+            kwargs ['action']  = 'store_true'
+            if 'default' not in kwargs:
+               kwargs ['default'] = False
+
+      elif flags & self.ARG_OPT_OUT:
+         kwargs ['action']  = 'store_false'
+         if 'default' not in kwargs:
+            kwargs ['default'] = True
+      # -- end if <opt-in/opt-out>
+
+      if flags & self.ARG_ADD_DEFAULT:
+         if 'defkey' in kwargs:
+            key = kwargs.pop ( 'defkey' )
+##         elif 'dest' in kwargs:
+         else:
+            key = kwargs ['dest']
+##         else:
+##            key = args[0].lstrip ( '-' ).lower().replace ( '-', '_' )
 
-   doconf_simple ( "additions_dir", "OVERLAY.additions_dir" )
+         if 'default' in kwargs:
+            fallback = kwargs.pop ( "default" )
+            kwargs ['default'] = self.defaults.get ( key, fallback )
+         else:
+            kwargs ['default'] = self.defaults [key]
 
-   if given ( 'overlay_name' ):
-      doconf ( p.overlay_name, 'OVERLAY.name' )
+      # -- end if <ARG_ADD_DEFAULT>
 
-   if given ( 'field_definition' ):
-      doconf ( p.field_definition, 'DESCRIPTION.field_definition_file' )
+      if flags & self.ARG_HELP_DEFAULT:
+         default = kwargs.get ( 'default', None )
+         if default is argparse.SUPPRESS:
+            default_str = self.STR_SUPPRESS
 
-   if given ( 'repo_config' ):
-      doconf ( p.repo_config, 'REPO.config_files' )
+         elif default in { True, False }:
+            if flags & self.ARG_INVERSE:
+               default_str = self.STR_FALSE if default else self.STR_TRUE
+            else:
+               default_str = self.STR_TRUE if default else self.STR_FALSE
 
-   if given ( 'package_rules' ):
-      doconf ( p.package_rules, 'PACKAGE_RULES.files' )
+         else:
+            default_str = '%(default)s'
+         # -- end if
+
+         if default_str:
+            if 'help' in kwargs:
+               kwargs ['help'] = kwargs ['help'] + ' [' + default_str + ']'
+            else:
+               kwargs ['help'] = '[' + default_str + ']'
+      # -- end if <append default value to help>
+
+      if flags & self.ARG_META_DIR:
+         if flags & self.ARG_META_FILE:
+            kwargs ['metavar'] = '<file|dir>'
+         else:
+            kwargs ['metavar'] = '<dir>'
+      elif flags & self.ARG_META_FILE:
+         kwargs ['metavar'] = '<file>'
+      # -- end if <metavar>
+
+      return kwargs
+   # --- end of apply_arg_flags (...) ---
+
+   def convert_kwargs ( self, kwargs, flags=0 ):
+      if 'flags' in kwargs:
+         kwargs_copy = dict ( kwargs )
+         my_flags    = kwargs_copy.pop ( "flags" ) | flags
+         return self.apply_arg_flags ( kwargs_copy, my_flags )
+      elif flags:
+         return self.apply_arg_flags ( dict ( kwargs ), flags )
+      else:
+         return kwargs
+   # --- end of convert_kwargs (...) ---
 
-   if given ( 'distroot' ):
-      doconf ( p.distroot, 'distfiles.root' )
+   def arg ( self, *args, **kwargs ):
+      return self.parser.add_argument (
+         *args, **self.convert_kwargs ( kwargs )
+      )
+   # --- end of arg (...) ---
 
-   if given ( 'distdirs' ):
-      if given ( 'distroot' ):
-         raise Exception ( "--distdir and --distroot are mutually exclusive!" )
+   def get_group_arg_adder ( self, key ):
+      def wrapped_group_arg ( *args, **kwargs ):
+         return self.group ( key ).add_argument (
+            *args, **self.convert_kwargs ( kwargs )
+         )
+      # --- end of wrapped_group_arg (...) ---
 
-      doconf ( (), 'REPO.config_files' )
-      extra ['distdirs'] = frozenset ( p.distdirs )
-      extra ['nosync']   = True
-      if 'create' in command_map:
-         commands.append ( "create" )
-   elif given ( 'nosync' ):
-      extra ['nosync'] = True
+      wrapped_group_arg.__doc__ = self.group_arg.__doc__
+      wrapped_group_arg.__name__ = self.group_arg.__name__
+      wrapped_group_arg.__dict__.update ( self.group_arg.__dict__ )
+      return wrapped_group_arg
+   # --- end of get_group_arg_adder (...) ---
 
-   if extra.get ( 'nosync', False ):
-      doconf ( True, 'nosync' )
+   def group_arg ( self, key, *args, **kwargs ):
+      return self.group ( key ).add_argument (
+         *args, **self.convert_kwargs ( kwargs )
+      )
+   # --- end of group_arg (...) ---
 
-   if given ( 'deprule_file' ):
-      doconf ( p.deprule_file, 'DEPRES.SIMPLE_RULES.files' )
+   def parse_args ( self, *args, **kwargs ):
+      self.parsed = self.parser.parse_args ( *args, **kwargs )
+      return self.parsed
+   # --- end of parse_args (...) ---
 
-   if given ( 'manifest_implementation' ):
-      doconf ( p.manifest_implementation, 'OVERLAY.manifest_implementation' )
+   def parse ( self, *args, **kwargs ):
+      return self.parse_args ( *args, **kwargs )
+   # --- end of parse (...) ---
 
-   if given ( 'distmap_verify' ):
-      doconf ( p.distmap_verify, 'OVERLAY.DISTDIR.verify' )
+   def add_argument_group ( self, key, **kwargs ):
+      if key in self._argument_groups:
+         raise ArgumentGroupExists ( key )
+      else:
+         self._argument_groups [key] = (
+            self.parser.add_argument_group ( **kwargs )
+         )
+         return self.get_group_arg_adder ( key )
+   # --- end of add_argument_group (...) ---
 
-   if not extra.get ( 'write_overlay', True ):
-      doconf ( True, "write_disabled" )
+   def group ( self, key ):
+      return self._argument_groups [key]
+   # --- end of group (...) ---
 
-   return ( commands, p.config, conf, extra )
-# --- end of parse_argv (...) ---
+# --- end of ArgumentParserProxy ---

diff --git a/roverlay/defaultscript.py b/roverlay/defaultscript.py
new file mode 100644
index 0000000..9d00e94
--- /dev/null
+++ b/roverlay/defaultscript.py
@@ -0,0 +1,426 @@
+# R overlay -- main()
+# -*- 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
+
+import os
+import sys
+import stat
+
+import roverlay.config.entrymap
+import roverlay.config.entryutil
+import roverlay.core
+import roverlay.console.depres
+import roverlay.hook
+import roverlay.overlay.creator
+import roverlay.packagerules.rules
+import roverlay.remote.repolist
+import roverlay.runtime
+import roverlay.tools.shenv
+import roverlay.util
+
+from roverlay.core import DIE, die
+
+
+# ===============
+#  main routines
+# ===============
+
+def main_installed ( *args, **kw ):
+   return main ( True, *args, **kw )
+# --- end of main_installed (...) ---
+
+def main ( installed, *args, **kw ):
+   main_env = roverlay.runtime.RuntimeEnvironment ( installed, *args, **kw )
+
+   if main_env.want_command ( 'setupdirs' ):
+      sys.exit ( run_setupdirs ( main_env ) )
+
+   elif run_early_commands ( main_env ):
+      sys.exit ( os.EX_OK )
+
+   elif (
+      main_env.want_command ( 'depres_console' ) or
+      main_env.want_command ( 'depres' )
+   ):
+      con = roverlay.console.depres.DepresConsole()
+      con.setup ( config=main_env.config )
+      try:
+         con.run_forever()
+      finally:
+         con.close()
+
+      sys.exit ( os.EX_OK )
+
+   elif main_env.want_command ( 'apply_rules' ):
+      sys.exit ( run_apply_package_rules ( main_env ) )
+
+   else:
+      roverlay.hook.setup()
+
+      retcode = os.EX_OK
+
+      if main_env.want_command ( 'sync' ):
+         retcode = run_sync ( main_env )
+      elif main_env.want_command ( 'create' ):
+         retcode = run_overlay_create ( main_env )
+      else:
+         die ( "unknown command: {!r}".format ( main_env.command ) )
+
+      if main_env.stats_db_file and main_env.want_db_commit:
+         main_env.stats.write_database()
+         roverlay.hook.run ( 'db_written' )
+
+      if main_env.options ['dump_stats']:
+         print ( "\n{:-^60}".format ( " stats dump " ) )
+         print ( main_env.stats )
+         print ( "{:-^60}".format ( " end stats dump " ) )
+
+      sys.exit ( retcode )
+# --- end of main (...) ---
+
+def run_script_main_installed ( *args, **kw ):
+   return run_script_main ( True, *args, **kw )
+# --- end of run_script_main_installed (...) ---
+
+def run_script_main ( installed ):
+   if len ( sys.argv ) < 2 or not sys.argv[0]:
+      die ( "no executable specified.", DIE.USAGE )
+
+   roverlay.core.default_helper_setup ( installed )
+   roverlay.tools.shenv.run_script_exec (
+      sys.argv[1], "runscript", sys.argv[1:], use_path=True
+   )
+# --- end of run_script_main (...) ---
+
+def run_shell_main_installed ( *args, **kw ):
+   return run_shell_main ( True, *args, **kw )
+
+def run_shell_main ( installed ):
+   config = roverlay.core.default_helper_setup ( installed )
+   shell  = config.get ( 'SHELL_ENV.shell', '/bin/sh' )
+   roverlay.tools.shenv.run_script_exec (
+      shell, "shell", [ shell, ] + sys.argv [1:], use_path=False
+   )
+# --- end of run_shell_main (...) ---
+
+
+# ==============
+#  sub routines
+# ==============
+
+def run_early_commands ( env ):
+   want_exit = False
+
+   if env.options ['list_config_entries']:
+      want_exit = True
+      print ( "== main config file ==\n" )
+      print ( roverlay.config.entryutil.list_entries() )
+
+   if env.options ['print_config']:
+      want_exit = True
+      env.config.visualize ( into=sys.stdout )
+
+   if env.options ['print_package_rules']:
+      want_exit = True
+      package_rules = (
+         roverlay.packagerules.rules.PackageRules.get_configured()
+      )
+      print ( env.HLINE )
+      print ( str ( package_rules ) )
+      print ( env.HLINE )
+
+   return want_exit
+# --- end of run_early_commands (...) ---
+
+
+def run_setupdirs ( env ):
+   config     = env.config
+   target_uid = env.options ['target_uid']
+   target_gid = env.options ['target_gid' ]
+
+   dodir            = roverlay.util.dodir
+   find_config_path = roverlay.config.entryutil.find_config_path
+
+   dirmode_private  = stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP
+   #clear_mode = ~(stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
+   #get_mode = lambda old, want_mode: ( old & clear_mode ) | want_mode
+
+   WANT_USERDIR = roverlay.config.entrymap.WANT_USERDIR
+   WANT_PRIVATE = roverlay.config.entrymap.WANT_PRIVATE
+   WANT_FILEDIR = roverlay.config.entrymap.WANT_FILEDIR
+
+   listlike    = lambda a: hasattr(a, '__iter__') and not isinstance(a, str)
+   iter_values = lambda b: () if b is None else (b if listlike(b) else ( b, ))
+
+   my_uid = os.getuid()
+   my_gid = os.getgid()
+   should_chown = my_uid != target_uid or my_gid != target_gid
+
+   # it's not necessary to create all of the listed dirs because some of
+   # them are automatically created at runtime, but doing so results in
+   # a (mostly) complete filesystem layout
+   #
+   for config_key, entry in roverlay.config.entrymap.CONFIG_ENTRY_MAP.items():
+      if isinstance ( entry, dict ) and 'want_dir_create' in entry:
+         for value in iter_values (
+            config.get ( find_config_path ( config_key ), None )
+         ):
+            dirmask = entry ['want_dir_create']
+            dirpath = (
+               os.path.dirname ( value.rstrip ( os.sep ) )
+               if dirmask & WANT_FILEDIR else value.rstrip ( os.sep )
+            )
+
+            if dirpath:
+               dodir ( dirpath )
+               if dirmask & WANT_PRIVATE:
+                  os.chmod ( dirpath, dirmode_private )
+               if dirmask & WANT_USERDIR and should_chown:
+                  os.chown ( dirpath, target_uid, target_gid )
+
+
+   return os.EX_OK
+# --- end of run_setupdirs (...) ---
+
+def run_sync ( env ):
+   if env.action_done ( 'sync' ):
+      return
+
+   STRICT_SYNC = env.option ( 'strict' ) or env.option ( 'strict_sync' )
+
+   try:
+      # set up the repo list
+      repo_list = env.get_repo_list()
+
+      ## extra_opts->distdir
+      if 'distdirs' in env.options:
+         repo_list.add_distdirs ( OPTION ( 'distdirs' ) )
+      else:
+         # default repo list
+         repo_list.load()
+
+      ## this runs _nosync() or _sync(), depending on extra_opts->nosync
+      sync_success = repo_list.sync ( fail_greedy=STRICT_SYNC )
+      env.set_action_done ( "sync" )
+
+   except KeyboardInterrupt:
+      die ( "Interrupted", DIE.INTERRUPT )
+   except:
+      if env.hide_exceptions:
+         die (
+            ( "no" if OPTION ( "nosync" ) else "" ) + "sync() failed!",
+            DIE.SYNC
+         )
+      else:
+         raise
+   else:
+      if not sync_success and STRICT_SYNC:
+         die ( "errors occured while syncing.", DIE.SYNC )
+# --- end of run_sync() ---
+
+def run_overlay_create ( env ):
+   if env.action_done ( "create" ):
+      return
+   run_sync ( env )
+
+   try:
+      repo_list       = env.get_repo_list()
+      overlay_creator = env.get_overlay_creator()
+
+      ebuild_import_nosync = env.option ( 'sync_imported' )
+      if ebuild_import_nosync is None:
+         ebuild_import_nosync = env.config.get_or_fail ( 'nosync' )
+
+
+      overlay_creator.overlay.import_ebuilds (
+         overwrite = not env.option ( 'incremental' ),
+         nosync    = ebuild_import_nosync,
+      )
+
+      repo_list.add_packages ( overlay_creator.add_package )
+      if env.options ['revbump']:
+         overlay_creator.enqueue_postponed()
+      else:
+         overlay_creator.discard_postponed()
+
+      overlay_creator.release_package_rules()
+
+      if env.options ['fixup_category_move']:
+         overlay_creator.remove_moved_ebuilds ( reverse=False )
+      elif env.options ['fixup_category_move_reverse']:
+         overlay_creator.remove_moved_ebuilds ( reverse=True )
+
+      # overlay creation should succeed after 2 runs, limit passno here
+      #
+      overlay_creator.run ( close_when_done=True, max_passno=2 )
+
+      if env.options ['write_overlay']:
+         overlay_creator.write_overlay()
+
+      if env.options ['show_overlay']:
+         overlay_creator.show_overlay()
+
+      if env.options ['print_stats']:
+         sys.stdout.write ( '\n' )
+         sys.stdout.write ( env.stats.get_creation_str() )
+         sys.stdout.write ( '\n\n' )
+         sys.stdout.flush()
+
+
+      # FIXME/TODO:
+      #  this hook should be called _after_ verifying the overlay
+      #  (verification is not implemented yet)
+      #
+      roverlay.hook.run ( 'overlay_success' )
+
+      env.want_db_commit = True
+      env.set_action_done ( "create" )
+
+   except KeyboardInterrupt:
+      die ( "Interrupted", DIE.INTERRUPT )
+   except:
+      if env.hide_exceptions:
+         die ( "Overlay creation failed.", DIE.OV_CREATE )
+      else:
+         raise
+   finally:
+      if 'overlay_creator' in locals() and not overlay_creator.closed:
+         # This is important 'cause it unblocks remaining ebuild creation
+         # jobs/threads, specifically waiting EbuildJobChannels in depres.
+         # It also writes the deps_unresolved file
+         overlay_creator.close()
+# --- end of run_overlay_create() ---
+
+def run_apply_package_rules ( env ):
+   if env.action_done ( 'apply_rules' ):
+      return
+   run_sync ( env )
+
+   dump_file = env.option ( "dump_file" )
+   FH        = None
+
+   prules = roverlay.packagerules.rules.PackageRules.get_configured()
+
+   # track package rules
+   prules.add_trace_actions()
+
+   NUM_MODIFIED = 0
+
+
+   BEGIN_RECEIVE_PACKAGE = ( 8 * '-' ) + " {header} " + ( 8 * '-' ) + '\n'
+   #END_RECEIVE_PACKAGE   = ( 31 * '-' ) + '\n\n'
+
+   get_header = lambda p : BEGIN_RECEIVE_PACKAGE.format (
+      header = ( p ['name'] + ' ' + p ['ebuild_verstr'] )
+   )
+   get_footer = lambda header : ( len ( header ) - 1 ) * '-' + '\n\n'
+
+   def tristate_counter ( f ):
+      """Wrapper that returns a 2-tuple (result_list, function f').
+      f' which increases result_list first, second or third
+      element depending on the return value of function f (True,False,None)
+
+      arguments:
+      * f -- function to wrap
+      """
+      result_list = [ 0, 0, 0 ]
+
+      def wrapped ( *args, **kwargs ):
+         result = f ( *args, **kwargs )
+         if result is None:
+            result_list [2] += 1
+         elif result:
+            result_list [0] += 1
+         else:
+            result_list [1] += 1
+         return result
+      # --- end of wrapped (...) ---
+
+      return result_list, wrapped
+   # --- end of tristate_counter (...) ---
+
+   def receive_package ( P ):
+      if prules.apply_actions ( P ):
+         if hasattr ( P, 'modified_by_package_rules' ):
+            # ^ that check is sufficient here
+            #if P.modified_by_package_rules
+
+            receive_header = get_header ( P )
+
+            FH.write ( receive_header )
+
+            evars = P.get_evars()
+            if evars:
+               FH.write ( "evars applied:\n" )
+               for evar in evars:
+                  FH.write ( "* {}\n".format ( evar ) )
+
+            if P.modified_by_package_rules is not True:
+               # ^ check needs to be changed when adding more trace actions
+               FH.write ( "trace marks:\n" )
+               for s in P.modified_by_package_rules:
+                  if s is not True:
+                     FH.write ( "* {}\n".format ( s ) )
+
+            FH.write ( "misc data:\n" )
+            for key in ( 'name', 'category', 'src_uri_dest', ):
+               FH.write (
+                  "{k:<12} = {v}\n".format (
+                     k=key, v=P.get ( key, "(undef)" )
+                  )
+               )
+
+            FH.write ( get_footer ( receive_header ) )
+
+            return True
+         else:
+            # not modified
+            return False
+      else:
+         receive_header = get_header ( P )
+         FH.write ( receive_header )
+         FH.write ( "filtered out!\n" )
+         FH.write ( get_footer ( receive_header ) )
+         return None
+
+   # --- end of receive_package (...) ---
+
+   modify_counter, receive_package_counting = (
+      tristate_counter ( receive_package )
+   )
+
+   try:
+      if dump_file == "-":
+         FH_SHARED = True
+         FH = sys.stdout
+      else:
+         FH_SHARED = False
+         FH = open ( dump_file, 'wt' )
+
+      env.get_repo_list().add_packages ( receive_package_counting )
+
+      if modify_counter [0] > 0:
+         FH.write ( "\n" )
+
+      #FH.write (
+      sys.stdout.write (
+         'done after {t:.2f} seconds\n'
+         '{p} packages processed in total, out of which\n'
+         '{m} have been modified and '
+         '{n} have been filtered out\n'.format (
+            t = env.stats.repo.queue_time.get_total(),
+            p = sum ( modify_counter ),
+            m = modify_counter [0],
+            n = modify_counter [2],
+         )
+      )
+
+   finally:
+      if FH and not FH_SHARED:
+         FH.close()
+
+# --- end of run_apply_package_rules (...) ---

diff --git a/roverlay/main.py b/roverlay/main.py
deleted file mode 100644
index 4a65aee..0000000
--- a/roverlay/main.py
+++ /dev/null
@@ -1,592 +0,0 @@
-# R overlay -- main()
-# -*- coding: utf-8 -*-
-# Copyright (C) 2012 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.
-
-"""main script for R overlay creation"""
-
-__all__ = [ 'main' ]
-
-import os
-import sys
-import stat
-
-import roverlay
-import roverlay.core
-import roverlay.argutil
-import roverlay.tools.shenv
-import roverlay.stats.collector
-import roverlay.util
-import roverlay.config.entrymap
-import roverlay.config.entryutil
-import roverlay.packagerules.rules
-
-
-DIE = roverlay.core.DIE
-die = roverlay.core.die
-
-def run_script_main_installed():
-   return run_script_main ( True )
-
-def run_script_main ( ROVERLAY_INSTALLED ):
-   if len ( sys.argv ) < 2 or not sys.argv[0]:
-      die ( "no executable specified.", DIE.USAGE )
-
-   roverlay.core.default_helper_setup ( ROVERLAY_INSTALLED )
-   roverlay.tools.shenv.run_script_exec (
-      sys.argv[1], "runscript", sys.argv[1:], use_path=True
-   )
-# --- end of run_script_main (...) ---
-
-def run_shell_main_installed():
-   return run_shell_main ( True )
-
-def run_shell_main ( ROVERLAY_INSTALLED ):
-   config = roverlay.core.default_helper_setup ( ROVERLAY_INSTALLED )
-   shell  = config.get ( 'SHELL_ENV.shell', '/bin/sh' )
-   roverlay.tools.shenv.run_script_exec (
-      shell, "shell", [ shell, ] + sys.argv [1:], use_path=False
-   )
-# --- end of run_shell_main (...) ---
-
-
-def run_setupdirs ( config, target_uid, target_gid ):
-
-   dodir            = roverlay.util.dodir
-   find_config_path = roverlay.config.entryutil.find_config_path
-
-   dirmode_private  = stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP
-   #clear_mode = ~(stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
-   #get_mode = lambda old, want_mode: ( old & clear_mode ) | want_mode
-
-   WANT_USERDIR = roverlay.config.entrymap.WANT_USERDIR
-   WANT_PRIVATE = roverlay.config.entrymap.WANT_PRIVATE
-   WANT_FILEDIR = roverlay.config.entrymap.WANT_FILEDIR
-
-   listlike    = lambda a: hasattr(a, '__iter__') and not isinstance(a, str)
-   iter_values = lambda b: () if b is None else (b if listlike(b) else ( b, ))
-
-   my_uid = os.getuid()
-   my_gid = os.getgid()
-   should_chown = my_uid != target_uid or my_gid != target_gid
-
-   # it's not necessary to create all of the listed dirs because some of
-   # them are automatically created at runtime, but doing so results in
-   # a (mostly) complete filesystem layout
-   #
-   for config_key, entry in roverlay.config.entrymap.CONFIG_ENTRY_MAP.items():
-      if isinstance ( entry, dict ) and 'want_dir_create' in entry:
-         for value in iter_values (
-            config.get ( find_config_path ( config_key ), None )
-         ):
-            dirmask = entry ['want_dir_create']
-            dirpath = (
-               os.path.dirname ( value.rstrip ( os.sep ) )
-               if dirmask & WANT_FILEDIR else value.rstrip ( os.sep )
-            )
-
-            if dirpath:
-               dodir ( dirpath )
-               if dirmask & WANT_PRIVATE:
-                  os.chmod ( dirpath, dirmode_private )
-               if dirmask & WANT_USERDIR and should_chown:
-                  os.chown ( dirpath, target_uid, target_gid )
-
-
-   return os.EX_OK
-# --- end of run_setupdirs (...) ---
-
-def main_installed():
-   return main ( ROVERLAY_INSTALLED=True )
-
-def main (
-   ROVERLAY_INSTALLED,
-   HIDE_EXCEPTIONS=False,
-   CONFIG_FILE_NAME=roverlay.core.DEFAULT_CONFIG_FILE_NAME
-):
-   """main() - parse args, run overlay creation, sync, ...
-
-   arguments:
-   * ROVERLAY_INSTALLED -- whether roverlay has been installed or not
-   * HIDE_EXCEPTIONS    -- hide exceptions? (optional, defaults to False)
-   * CONFIG_FILE_NAME   -- name of the config file (optional, defaults to
-                           "R-overlay.conf")
-   """
-   def optionally ( call, option, *args, **kw ):
-      if OPTION ( option ):
-         return call ( *args, **kw )
-   # --- end of optionally (...) ---
-
-   def run_sync():
-      if "sync" in actions_done: return
-
-      STRICT_SYNC = OPTION ( 'strict' ) or OPTION ( 'strict_sync' )
-
-      try:
-         # set up the repo list
-         global repo_list
-         repo_list = RepoList (
-            sync_enabled   = not conf.get_or_fail ( 'nosync' ),
-            force_distroot = OPTION ( 'force_distroot' )
-         )
-
-         ## extra_opts->distdir
-         if 'distdirs' in extra_opts:
-            repo_list.add_distdirs ( OPTION ( 'distdirs' ) )
-         else:
-            # default repo list
-            repo_list.load()
-
-         ## this runs _nosync() or _sync(), depending on extra_opts->nosync
-         sync_success = repo_list.sync ( fail_greedy=STRICT_SYNC )
-         set_action_done ( "sync" )
-
-      except KeyboardInterrupt:
-         die ( "Interrupted", DIE.INTERRUPT )
-      except:
-         if HIDE_EXCEPTIONS:
-            die (
-               ( "no" if OPTION ( "nosync" ) else "" ) + "sync() failed!",
-               DIE.SYNC
-            )
-         else:
-            raise
-      else:
-         if not sync_success and STRICT_SYNC:
-            die ( "errors occured while syncing.", DIE.SYNC )
-   # --- end of run_sync() ---
-
-   def run_apply_package_rules():
-      if "apply_rules" in actions_done: return
-
-      dump_file = OPTION ( "dump_file" )
-      FH        = None
-
-      prules = PackageRules.get_configured()
-
-      # track package rules
-      prules.add_trace_actions()
-
-      NUM_MODIFIED = 0
-
-
-      BEGIN_RECEIVE_PACKAGE = ( 8 * '-' ) + " {header} " + ( 8 * '-' ) + '\n'
-      #END_RECEIVE_PACKAGE   = ( 31 * '-' ) + '\n\n'
-
-      get_header = lambda p : BEGIN_RECEIVE_PACKAGE.format (
-         header = ( p ['name'] + ' ' + p ['ebuild_verstr'] )
-      )
-      get_footer = lambda header : ( len ( header ) - 1 ) * '-' + '\n\n'
-
-      def tristate_counter ( f ):
-         """Wrapper that returns a 2-tuple (result_list, function f').
-         f' which increases result_list first, second or third
-         element depending on the return value of function f (True,False,None)
-
-         arguments:
-         * f -- function to wrap
-         """
-         result_list = [ 0, 0, 0 ]
-
-         def wrapped ( *args, **kwargs ):
-            result = f ( *args, **kwargs )
-            if result is None:
-               result_list [2] += 1
-            elif result:
-               result_list [0] += 1
-            else:
-               result_list [1] += 1
-            return result
-         # --- end of wrapped (...) ---
-
-         return result_list, wrapped
-      # --- end of tristate_counter (...) ---
-
-      def receive_package ( P ):
-         if prules.apply_actions ( P ):
-            if hasattr ( P, 'modified_by_package_rules' ):
-               # ^ that check is sufficient here
-               #if P.modified_by_package_rules
-
-               receive_header = get_header ( P )
-
-               FH.write ( receive_header )
-
-               evars = P.get_evars()
-               if evars:
-                  FH.write ( "evars applied:\n" )
-                  for evar in evars:
-                     FH.write ( "* {}\n".format ( evar ) )
-
-               if P.modified_by_package_rules is not True:
-                  # ^ check needs to be changed when adding more trace actions
-                  FH.write ( "trace marks:\n" )
-                  for s in P.modified_by_package_rules:
-                     if s is not True:
-                        FH.write ( "* {}\n".format ( s ) )
-
-               FH.write ( "misc data:\n" )
-               for key in ( 'name', 'category', 'src_uri_dest', ):
-                  FH.write (
-                     "{k:<12} = {v}\n".format (
-                        k=key, v=P.get ( key, "(undef)" )
-                     )
-                  )
-
-               FH.write ( get_footer ( receive_header ) )
-
-               return True
-            else:
-               # not modified
-               return False
-         else:
-            receive_header = get_header ( P )
-            FH.write ( receive_header )
-            FH.write ( "filtered out!\n" )
-            FH.write ( get_footer ( receive_header ) )
-            return None
-
-      # --- end of receive_package (...) ---
-
-      modify_counter, receive_package_counting = (
-         tristate_counter ( receive_package )
-      )
-
-      try:
-         if dump_file == "-":
-            FH_SHARED = True
-            FH = sys.stdout
-         else:
-            FH_SHARED = False
-            FH = open ( dump_file, 'wt' )
-
-         repo_list.add_packages ( receive_package_counting )
-
-         if modify_counter [0] > 0:
-            FH.write ( "\n" )
-
-         #FH.write (
-         sys.stdout.write (
-            'done after {t:.2f} seconds\n'
-            '{p} packages processed in total, out of which\n'
-            '{m} have been modified and '
-            '{n} have been filtered out\n'.format (
-               t = roverlay.stats.collector.static.repo.queue_time.get_total(),
-               p = sum ( modify_counter ),
-               m = modify_counter [0],
-               n = modify_counter [2],
-            )
-         )
-
-      finally:
-         if 'FH' in locals() and not FH_SHARED:
-            FH.close()
-
-   # --- end of run_apply_package_rules (...) ---
-
-   def run_overlay_create():
-      if "create" in actions_done: return
-      #run_sync()
-      try:
-         global overlay_creator
-         overlay_creator = OverlayCreator (
-            skip_manifest           = OPTION ( 'skip_manifest' ),
-            incremental             = OPTION ( 'incremental' ),
-            allow_write             = OPTION ( 'write_overlay' ),
-            immediate_ebuild_writes = OPTION ( 'immediate_ebuild_writes' ),
-         )
-
-         if OPTION ( 'sync_imported' ) is False:
-            ebuild_import_nosync = True
-         elif OPTION ( 'sync_imported' ) is True:
-            ebuild_import_nosync = False
-         else:
-            ebuild_import_nosync = conf.get_or_fail ( 'nosync' )
-
-         overlay_creator.overlay.import_ebuilds (
-            overwrite = not OPTION ( 'incremental' ),
-            nosync    = ebuild_import_nosync,
-         )
-
-         repo_list.add_packages ( overlay_creator.add_package )
-         if OPTION ( 'revbump' ):
-            overlay_creator.enqueue_postponed()
-         else:
-            overlay_creator.discard_postponed()
-
-         overlay_creator.release_package_rules()
-
-         if OPTION ( 'fixup_category_move' ):
-            overlay_creator.remove_moved_ebuilds ( reverse=False )
-         elif OPTION ( 'fixup_category_move_rev' ):
-            overlay_creator.remove_moved_ebuilds ( reverse=True )
-
-         # overlay creation should succeed after 2 runs, limit passno here
-         #
-         overlay_creator.run ( close_when_done=True, max_passno=2 )
-
-         optionally ( overlay_creator.write_overlay, 'write_overlay' )
-         optionally ( overlay_creator.show_overlay,  'show_overlay'  )
-         if OPTION ( 'print_stats' ):
-            sys.stdout.write ( '\n' )
-            sys.stdout.write (
-               roverlay.stats.collector.static.get_creation_str()
-            )
-            sys.stdout.write ( '\n\n' )
-            sys.stdout.flush()
-
-
-         # FIXME/TODO:
-         #  this hook should be called _after_ verifying the overlay
-         #  (verification is not implemented yet)
-         #
-         roverlay.hook.run ( 'overlay_success' )
-
-         set_action_done ( "create" )
-
-      except KeyboardInterrupt:
-         die ( "Interrupted", DIE.INTERRUPT )
-      except:
-         if HIDE_EXCEPTIONS:
-            die ( "Overlay creation failed.", DIE.OV_CREATE )
-         else:
-            raise
-      finally:
-         if 'overlay_creator' in locals() and not overlay_creator.closed:
-            # This is important 'cause it unblocks remaining ebuild creation
-            # jobs/threads, specifically waiting EbuildJobChannels in depres.
-            # It also writes the deps_unresolved file
-            overlay_creator.close()
-   # --- end of run_overlay_create() ---
-
-   # ********************
-   #  main() starts here
-   # ********************
-
-   # get args
-   try:
-      # FIXME: why is the reimport of roverlay necessary?
-      import roverlay
-   except ImportError:
-      if HIDE_EXCEPTIONS:
-         die ( "Cannot import roverlay modules!", DIE.IMPORT )
-      else:
-         raise
-
-   COMMAND_DESCRIPTION = {
-      'sync'           : 'sync repos',
-      'create'         : 'create the overlay '
-                          '(implies sync, override with --nosync)',
-      'depres_console' : \
-         'run an interactive depres console (highly experimental)',
-      'depres'         : 'this is an alias to \'depres_console\'',
-      'nop'            : 'does nothing',
-      'apply_rules'    : 'apply package rules verbosely and exit afterwards',
-      'setupdirs'      : 'create configured directories etc.',
-   }
-
-
-   DEFAULT_CONFIG_FILE = roverlay.core.locate_config_file (
-      ROVERLAY_INSTALLED, CONFIG_FILE_NAME
-   )
-
-   commands, config_file, additional_config, extra_opts = (
-      roverlay.argutil.parse_argv (
-         command_map=COMMAND_DESCRIPTION,
-         default_config_file=DEFAULT_CONFIG_FILE,
-      )
-   )
-   additional_config ['installed'] = ROVERLAY_INSTALLED
-
-   OPTION = extra_opts.get
-
-
-   # -- determine commands to run
-   # (TODO) could replace this section when adding more actions
-   # imports roverlay.remote, roverlay.overlay.creator
-
-   actions = set ( filter ( lambda x : x != 'nop', commands ) )
-   actions_done = set()
-   set_action_done = actions_done.add
-
-   want_logging = True
-   do_setupdirs = False
-
-   if 'sync' in actions and OPTION ( 'nosync' ):
-      die ( "sync command blocked by --nosync opt.", DIE.ARG )
-
-   elif 'setupdirs' in actions:
-      do_setupdirs = True
-      want_logging = False
-      if len ( actions ) > 1:
-         die ( "setupdirs cannot be run with other commands!", DIE.USAGE )
-
-   del commands
-
-
-   if not actions:
-      # this happens if a command is nop
-      die ( "Nothing to do!", DIE.NOP )
-
-   # -- load config
-
-   # imports: roverlay, roverlay.config.entryutil (if --help-config)
-
-   try:
-      roverlay.stats.collector.static.time.begin ( "setup" )
-      roverlay.core.setup_initial_logger()
-
-      conf = roverlay.core.load_config_file (
-         config_file,
-         extraconf      = additional_config,
-         setup_logger   = want_logging,
-         load_main_only = do_setupdirs,
-      )
-      del config_file, additional_config
-   except:
-      if not config_file:
-         sys.stderr.write ( '!!! No config file found.\n' )
-
-      if HIDE_EXCEPTIONS:
-         die (
-            "Cannot load config file {!r}.".format ( config_file ), DIE.CONFIG
-         )
-      else:
-         raise
-   else:
-      roverlay.stats.collector.static.time.end ( "setup" )
-
-   if do_setupdirs:
-      sys.exit ( run_setupdirs (
-         conf, extra_opts['target_uid'], extra_opts['target_gid']
-      ) )
-   # -- end commands with partial config / without logging
-
-   if OPTION ( 'list_config' ):
-      try:
-         from roverlay.config.entryutil import list_entries
-         print ( "== main config file ==\n" )
-         print ( list_entries() )
-      except:
-         raise
-         die ( "Cannot list config entries!" )
-
-      EXIT_AFTER_CONFIG = True
-
-   if OPTION ( 'print_config' ):
-      try:
-         conf.visualize ( into=sys.stdout )
-      except:
-         die ( "Cannot print config!" )
-      EXIT_AFTER_CONFIG = True
-
-   if OPTION ( 'print_package_rules' ):
-      # no try-/catch block here
-
-      package_rules = (
-         roverlay.packagerules.rules.PackageRules.get_configured()
-      )
-
-      HLINE = "".rjust ( 79, '-' )
-      print ( HLINE )
-      print ( str ( package_rules ) )
-      print ( HLINE )
-
-      EXIT_AFTER_CONFIG = True
-
-   # -- end of EXIT_AFTER_CONFIG entries
-
-   if 'EXIT_AFTER_CONFIG' in locals() and EXIT_AFTER_CONFIG:
-      sys.exit ( os.EX_OK )
-
-   # switch to depres console
-   elif 'depres_console' in actions or 'depres' in actions:
-      if len ( actions ) != 1:
-         die ( "depres_console cannot be run with other commands!", DIE.USAGE )
-
-      try:
-         from roverlay.console.depres import DepresConsole
-         con = DepresConsole()
-         con.setup ( config=conf )
-         try:
-            con.run_forever()
-            set_action_done ( "depres_console" )
-         finally:
-            con.close()
-
-      except ImportError:
-         if HIDE_EXCEPTIONS:
-            die ( "Cannot import depres console!", DIE.IMPORT )
-         else:
-            raise
-      except:
-         if HIDE_EXCEPTIONS:
-            die ( "Exiting on console error!", DIE.ERR )
-         else:
-            raise
-
-   else:
-      # sync/create
-      # -- import roverlay modules
-
-      try:
-         from roverlay.remote          import RepoList
-         from roverlay.overlay.creator import OverlayCreator
-
-         import roverlay.config
-         import roverlay.hook
-      except ImportError:
-         if HIDE_EXCEPTIONS:
-            die ( "Cannot import roverlay modules!", DIE.IMPORT )
-         else:
-            raise
-
-      # -- run methods (and some vars)
-      # imports: package rules
-
-      #repo_list       = None
-      #overlay_creator = None
-
-      # -- run
-
-      # initialize roverlay.hook
-      roverlay.hook.setup()
-
-      # initialize database
-      STATS_DB_FILE = conf.get ( 'RRD_DB.file', None )
-      if STATS_DB_FILE:
-         roverlay.stats.collector.static.setup_database ( conf )
-         want_db_commit = False
-
-      # always run sync 'cause commands = {create,sync,apply_rules}
-      # and create,apply_rules implies (no)sync
-      run_sync()
-
-      if "apply_rules" in actions:
-         from roverlay.packagerules.rules import PackageRules
-         run_apply_package_rules()
-      elif 'create' in actions:
-         run_overlay_create()
-         want_db_commit = True
-
-
-      if STATS_DB_FILE and want_db_commit:
-         roverlay.stats.collector.static.write_database()
-         roverlay.hook.run ( 'db_written' )
-
-
-      # *** TEMPORARY ***
-      if OPTION ( 'dump_stats' ):
-         print ( "\n{:-^60}".format ( " stats dump " ) )
-         print ( roverlay.stats.collector.static )
-         print ( "{:-^60}".format ( " end stats dump " ) )
-      # *** END TEMPORARY ***
-
-
-   if len ( actions ) > len ( actions_done ):
-      die (
-         "Some actions (out of {!r}) could not be performed!".format (
-            actions ), DIE.CMD_LEFTOVER
-      )
-# --- end of main (...) ---

diff --git a/roverlay/runtime.py b/roverlay/runtime.py
new file mode 100644
index 0000000..f44dbad
--- /dev/null
+++ b/roverlay/runtime.py
@@ -0,0 +1,152 @@
+# R overlay -- runtime 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.
+
+import os
+import sys
+
+import roverlay.argparser
+import roverlay.core
+import roverlay.hook
+import roverlay.remote.repolist
+import roverlay.stats.collector
+
+from roverlay.core import DIE, die
+
+
+class RuntimeEnvironment ( object ):
+   def __init__ ( self,
+      installed,
+      hide_exceptions=False,
+      config_file_name=roverlay.core.DEFAULT_CONFIG_FILE_NAME
+   ):
+      super ( RuntimeEnvironment, self ).__init__()
+
+      self.HLINE             = 79 * '-'
+      self.stats             = roverlay.stats.collector.static
+      self.config            = None
+      self.additional_config = None
+      self.options           = None
+      self.actions_done      = set()
+      self.command           = None
+
+      self._repo_list        = None
+      self._overlay_creator  = None
+      self.stats_db_file     = None
+
+      self.want_db_commit    = False
+
+      self.hide_exceptions = hide_exceptions
+      if hide_exceptions:
+         try:
+            self.setup ( installed, config_file_name )
+         except:
+            die ( "failed to initialize runtime environment." )
+      else:
+         self.setup ( installed, config_file_name )
+   # --- end of __init__ (...) ---
+
+   def get_repo_list ( self ):
+      if self._repo_list is None:
+         self._repo_list = roverlay.remote.repolist.RepoList (
+            sync_enabled   = not self.config.get_or_fail ( 'nosync' ),
+            force_distroot = self.options.get ( 'force_distroot' )
+         )
+      return self._repo_list
+   # --- end of get_repo_list (...) ---
+
+   def get_overlay_creator ( self ):
+      if self._overlay_creator is None:
+         self._overlay_creator = roverlay.overlay.creator.OverlayCreator (
+            skip_manifest           = not self.options ['manifest'],
+            incremental             = self.options ['incremental'],
+            allow_write             = self.options ['write_overlay'],
+            immediate_ebuild_writes = self.options ['immediate_ebuild_writes'],
+         )
+      return self._overlay_creator
+   # --- end of get_overlay_creator (...) ---
+
+   def setup ( self, installed, config_file_name ):
+      roverlay.core.setup_initial_logger()
+      self.stats.time.begin ( "setup" )
+
+      parser = roverlay.argparser.RoverlayMainArgumentParser (
+         defaults={
+            'config_file': roverlay.core.locate_config_file (
+               installed, config_file_name
+            )
+         }
+      )
+      parser.setup()
+      parser.parse()
+      parser.do_extraconf ( installed, 'installed' )
+
+      command           = parser.command
+      options           = parser.parsed
+      additional_config = parser.extra_conf
+
+      del parser
+
+
+      try:
+         self.config = roverlay.core.load_config_file (
+            options ['config_file'],
+            extraconf      = additional_config,
+            setup_logger   = options ['want_logging'],
+            load_main_only = options ['load_main_only'],
+         )
+      except:
+         if self.hide_exceptions:
+            die (
+               "Cannot load config file {!r}".format (
+                  options ['config_file']
+               ),
+               DIE.CONFIG
+            )
+         else:
+            raise
+
+
+      self.stats_db_file  = self.config.get ( 'RRD_DB.file', None )
+      if self.stats_db_file:
+         self.stats.setup_database ( self.config )
+
+      self.command           = command
+      self.options           = options
+      self.additional_config = additional_config
+
+
+      # want_logging <=> <have a command that uses hooks>
+      if options ['want_logging']:
+         roverlay.hook.setup()
+
+      self.stats.time.end ( "setup" )
+   # --- end of setup (...) ---
+
+   def set_action_done ( self, action ):
+      self.actions_done.add ( action )
+   # --- end of set_action_done (...) ---
+
+   def action_done ( self, action ):
+      return action in self.actions_done
+   # --- end of action_done (...) ---
+
+   def want_command ( self, command ):
+      return command == self.command
+      ##and command not in self.actions_done
+   # --- end of want_command (...) ---
+
+   def option ( self, key, fallback=None ):
+      return self.options.get ( key, fallback )
+   # --- end of option (...) ---
+
+   def optionally ( self, func, key, *args, **kwargs ):
+      if self.options.get ( key, False ):
+         return func ( *args, **kwargs )
+      else:
+         return None
+   # --- end of optionally (...) ---
+
+# --- end of RuntimeEnvironment ---

diff --git a/setup.py b/setup.py
index e139559..8efc3cd 100755
--- a/setup.py
+++ b/setup.py
@@ -13,10 +13,10 @@ setup (
    url          = 'http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=summary',
    entry_points = {
       'console_scripts': [
-         'roverlay = roverlay.main:main_installed',
+         'roverlay = roverlay.defaultscript:main_installed',
+         'roverlay-sh = roverlay.defaultscript:run_shell_main_installed',
+         #'roverlay-exec = roverlay.defaultscript:run_script_main_installed',
          'roverlay-mkconfig = roverlay.config.mkconfig:make_config',
-         'roverlay-sh = roverlay.main:run_shell_main_installed',
-         #'roverlay-exec = roverlay.main:run_script_main_installed',
       ]
    },
    packages     = find_packages ( exclude=[ 'tests', 'tests.*' ] ),


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-07-11 17:11 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-07-11 17:11 UTC (permalink / raw
  To: gentoo-commits

commit:     4ac962ee2d1030896f42defdd84c42a408bc0e22
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul 11 17:09:08 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul 11 17:09:08 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=4ac962ee

R_Overlay 0.2.5

Notable changes since gsoc2013_start_coding:

* packages rules: relocate packages (category, name, SRC_URI)
* additions dir: patch ebuilds, import ebuilds
* R_SUGGESTS USE_EXPAND variable
* distmap: package file verification, revbump on checksum change
* hooks: run shell scripts when certain events like "overlay created" occur
-> create/maintain git history
-> create metadata cache
* test cases for dependency resolution
* dependency resolution
-> split dependency strings
-> fuzzy SLOT rules
-> selfdep validation
* ebuild creation
-> interruptible ebuild creation jobs which allows to implement
   breakpoints/multi-phase actions like selfdep validation
-> add LICENSE variable to ebuilds ("license map")
* fast Manifest file creation (newmanifest)
* R-overlay.conf file generation (roverlay-mkconfig)
* ebuild / setup.py up-to-date (setup.py uses setuptools now)
* misc fixes

doc/ reflects these changes only partially.

---
 roverlay/__init__.py | 2 +-
 setup.py             | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 7930c4a..175f2d1 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -13,7 +13,7 @@ load_config_file) and some information vars (version, name, ...).
 __all__ = [ 'setup_initial_logger', 'load_config_file', ]
 
 name        = "R_overlay"
-version     = "0.2.4"
+version     = "0.2.5"
 
 description_str = "R overlay creation (roverlay) " + version
 license_str=(

diff --git a/setup.py b/setup.py
index d42b159..d94e237 100755
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ from setuptools import setup, find_packages
 
 setup (
    name         = 'R_Overlay',
-   version      = '0.2.4',
+   version      = '0.2.5',
    description  = 'Automatically generated overlay of R packages (SoC2012)',
    author       = 'André Erdmann',
    author_email = 'dywi@mailerd.de',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-04-25 16:44 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-04-25 16:44 UTC (permalink / raw
  To: gentoo-commits

commit:     54487834aa0c77dcc941a01766234143838f5448
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Apr 25 16:23:49 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Apr 25 16:23:49 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=54487834

increase version to 0.2.4

Notable changes since 0.2.3:

* main script: "apply_rules" command for testing package rules
* package rules: evar action deduplication, trace action
* ebuild variables: added some protection against code injection
* portagemanifest (fix): dont fail if metadata.xml is missing
* metadata: also use older packages (version-wise)

---
 roverlay/__init__.py |    5 ++---
 setup.py             |    2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 5b0f63b..b24b539 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -13,13 +13,12 @@ load_config_file) and some information vars (__version__, name, ...).
 __all__ = [ 'setup_initial_logger', 'load_config_file', ]
 
 name        = "R_overlay"
-version     = ( 0, 2, 3 )
-#__version__ = "0.2.3"
+version     = ( 0, 2, 4 )
 __version__ = '.'.join ( str ( i ) for i in version )
 
 description_str = "R overlay creation (roverlay) " + __version__
 license_str=(
-	'Copyright (C) 2012 Andr\xc3\xa9 Erdmann\n'
+	'Copyright (C) 2012, 2013 Andr\xc3\xa9 Erdmann\n'
 	'Distributed under the terms of the GNU General Public License;\n'
 	'either version 2 of the License, or (at your option) any later version.\n'
 )

diff --git a/setup.py b/setup.py
index e4c2d0e..a9aaf6d 100755
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 from distutils import core
 
-VERSION = '0.2.3'
+VERSION = '0.2.4'
 
 core.setup (
 	name         = 'R_Overlay',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-02-09 20:45 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-02-09 20:45 UTC (permalink / raw
  To: gentoo-commits

commit:     2430edacd56761c7bb4d3bfc846c5b00054a53b1
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Sat Feb  9 19:31:37 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Sat Feb  9 20:08:15 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2430edac

move roverlay.py to roverlay/main.py

The roverlay main() function is now part of the roverlay modules,
which allows byte-compiling.

---
 roverlay.py                     |  338 +--------------------------------------
 roverlay.py => roverlay/main.py |   73 +++++----
 2 files changed, 48 insertions(+), 363 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index d18a987..31858a1 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -5,339 +5,11 @@
 # Distributed under the terms of the GNU General Public License;
 # either version 2 of the License, or (at your option) any later version.
 
-"""main script for R overlay creation"""
+import roverlay.main
 
-__all__ = [ 'DIE', 'roverlay_main' ]
-
-import os
-import sys
-
-# roverlay modules will be imported later
-
-ROVERLAY_INSTALLED  = False
-HIDE_EXCEPTIONS     = False
-CONFIG_FILE_NAME    = "R-overlay.conf"
-
-if ROVERLAY_INSTALLED:
-	# directories where the config file could be found, in order:
-	# * ${PWD}
-	# * user roverlay dir (${HOME}/roverlay)
-	# * system config dir /etc/roverlay
-	CONFIG_DIRS = tuple ((
-		'.',
-		(
-			( os.getenv ( 'HOME' ) or os.path.expanduser ( '~' ) )
-			+ os.sep + 'roverlay'
-		),
-		# os.sep is '/' if /etc exists, so don't care about that
-		'/etc/roverlay',
-	))
-
-
-
-class DIE ( object ):
-	"""Container class for various system exit 'events'."""
-	NOP          =  os.EX_OK
-	ERR          =  1
-	BAD_USAGE    =  os.EX_USAGE
-	USAGE        =  os.EX_USAGE
-	ARG          =  9
-	CONFIG       =  os.EX_CONFIG
-	OV_CREATE    =  20
-	SYNC         =  30
-	CMD_LEFTOVER =  90
-	IMPORT       =  91
-	UNKNOWN      =  95
-	INTERRUPT    = 130
-
-	@staticmethod
-	def die ( msg=None, code=None ):
-		"""
-		Calls syst.exit (code:=DIE.ERR) after printing a message (if any).
-		"""
-		code = DIE.ERR if code is None else code
-		if msg is not None:
-			sys.stderr.write ( msg + "\n" )
-#		else:
-#			sys.stderr.write ( "died.\n" )
-		sys.exit ( code )
-	# --- end of die (...) ---
-
-# --- DIE: exit codes ---
-die = DIE.die
-
-def roverlay_main():
-	"""roverlay.py main() - parse args, run overlay creation, sync, ..."""
-	def optionally ( call, option, *args, **kw ):
-		if OPTION ( option ):
-			return call ( *args, **kw )
-	# --- end of optionally (...) ---
-
-	def run_sync():
-		if "sync" in actions_done: return
-		try:
-			# set up the repo list
-			global repo_list
-			repo_list = RepoList (
-				sync_enabled   = not OPTION ( 'nosync' ),
-				force_distroot = OPTION ( 'force_distroot' )
-			)
-
-			## extra_opts->distdir ... TODO
-			if 'distdirs' in extra_opts:
-				repo_list.add_distdirs ( OPTION ( 'distdirs' ) )
-			else:
-				# default repo list
-				repo_list.load()
-
-			## this runs _nosync() or _sync(), depending on extra_opts->nosync
-			repo_list.sync()
-
-			set_action_done ( "sync" )
-
-		except KeyboardInterrupt:
-			die ( "Interrupted", DIE.INTERRUPT )
-		except:
-			if HIDE_EXCEPTIONS:
-					die (
-						"nosync() failed!" if OPTION ( "nosync" ) \
-							else "sync() failed!",
-						DIE.SYNC
-					)
-			else:
-				raise
-	# --- end of run_sync() ---
-
-	def run_overlay_create():
-		if "create" in actions_done: return
-		#run_sync()
-		try:
-			global overlay_creator
-			overlay_creator = OverlayCreator (
-				skip_manifest           = OPTION ( 'skip_manifest' ),
-				incremental             = OPTION ( 'incremental' ),
-				allow_write             = OPTION ( 'write_overlay' ),
-				immediate_ebuild_writes = OPTION ( 'immediate_ebuild_writes' ),
-			)
-
-			repo_list.add_packages ( overlay_creator.add_package )
-
-			overlay_creator.run ( close_when_done=True )
-
-			optionally ( overlay_creator.write_overlay, 'write_overlay' )
-			optionally ( overlay_creator.show_overlay,  'show_overlay'  )
-			if OPTION ( 'print_stats' ):
-				print ( "\n" + overlay_creator.stats_str() )
-
-			set_action_done ( "create" )
-
-		except KeyboardInterrupt:
-			die ( "Interrupted", DIE.INTERRUPT )
-		except:
-			if HIDE_EXCEPTIONS:
-				die ( "Overlay creation failed.", DIE.OV_CREATE )
-			else:
-				raise
-		finally:
-			if 'overlay_creator' in locals() and not overlay_creator.closed:
-				# This is important 'cause it unblocks remaining ebuild creation
-				# jobs/threads, specifically waiting EbuildJobChannels in depres.
-				# It also writes the deps_unresolved file
-				overlay_creator.close()
-	# --- end of run_overlay_create() ---
-
-	# get args
-	# imports roverlay.argutil (deleted when done)
-	try:
-		import roverlay.argutil
-	except ImportError:
-		if HIDE_EXCEPTIONS:
-			die ( "Cannot import roverlay modules!", DIE.IMPORT )
-		else:
-			raise
-
-	COMMAND_DESCRIPTION = {
-		'sync'           : 'sync repos',
-		'create'         : 'create the overlay '
-								  '(implies sync, override with --nosync)',
-		'depres_console' : \
-			'run an interactive depres console (highly experimental)',
-		'depres'         : 'this is an alias to \'depres_console\'',
-		'nop'            : 'does nothing',
-	}
-
-
-	DEFAULT_CONFIG_FILE = None
-	# search for the config file if roverlay has been installed
-	if ROVERLAY_INSTALLED:
-		cfg        = None
-		config_dir = None
-
-		for config_dir in CONFIG_DIRS:
-			cfg = config_dir + os.sep + CONFIG_FILE_NAME
-			if os.path.isfile ( cfg ):
-				DEFAULT_CONFIG_FILE = cfg
-				break
-
-		del config_dir, cfg
-	elif os.path.exists ( CONFIG_FILE_NAME ):
-		DEFAULT_CONFIG_FILE = CONFIG_FILE_NAME
-
-
-	commands, config_file, additional_config, extra_opts = \
-		roverlay.argutil.parse_argv (
-			command_map=COMMAND_DESCRIPTION,
-			default_config_file=DEFAULT_CONFIG_FILE,
-		)
-
-	OPTION = extra_opts.get
-
-	del roverlay.argutil
-
-	# -- determine commands to run
-	# (TODO) could replace this section when adding more actions
-	# imports roverlay.remote, roverlay.overlay.creator
-
-	actions = set ( filter ( lambda x : x != 'nop', commands ) )
-
-	if 'sync' in actions and OPTION ( 'nosync' ):
-		die ( "sync command blocked by --nosync opt.", DIE.ARG )
-
-	del commands
-
-
-	if not actions:
-		# this happens if a command is nop
-		die ( "Nothing to do!", DIE.NOP )
-
-	# -- load config
-
-	# imports: roverlay, roverlay.config.entryutil (if --help-config)
-
-	try:
-		import roverlay
-	except ImportError:
-		if HIDE_EXCEPTIONS:
-			die ( "Cannot import roverlay modules!", DIE.IMPORT )
-		else:
-			raise
-
-	try:
-		roverlay.setup_initial_logger()
-
-		conf = roverlay.load_config_file (
-			config_file,
-			extraconf=additional_config
-		)
-		del config_file, additional_config
-	except:
-		if not config_file:
-			sys.stderr.write ( '!!! No config file found.\n' )
-
-		if HIDE_EXCEPTIONS:
-			die (
-				"Cannot load config file {!r}.".format ( config_file ), DIE.CONFIG
-			)
-		else:
-			raise
-
-	if OPTION ( 'list_config' ):
-		try:
-			from roverlay.config.entryutil import list_entries
-			print ( "== main config file ==\n" )
-			print ( list_entries() )
-		except:
-			raise
-			die ( "Cannot list config entries!" )
-
-		EXIT_AFTER_CONFIG = True
-
-	if OPTION ( 'print_config' ):
-		try:
-			conf.visualize ( into=sys.stdout )
-		except:
-			die ( "Cannot print config!" )
-		EXIT_AFTER_CONFIG = True
-
-	if OPTION ( 'print_package_rules' ):
-		# no try-/catch block here
-
-		import roverlay.packagerules.rules
-
-		HLINE = "".rjust ( 79, '-' )
-		print ( HLINE )
-		print (
-			str ( roverlay.packagerules.rules.PackageRules.get_configured() )
-		)
-		print ( HLINE )
-
-		EXIT_AFTER_CONFIG = True
-
-	# -- end of EXIT_AFTER_CONFIG entries
-
-	if 'EXIT_AFTER_CONFIG' in locals() and EXIT_AFTER_CONFIG:
-		pass
-		#sys.exit ( os.EX_OK )
-
-	# switch to depres console
-	elif 'depres_console' in actions or 'depres' in actions:
-		if len ( actions ) != 1:
-			die ( "depres_console cannot be run with other commands!", DIE.USAGE )
-
-		try:
-			from roverlay.depres.simpledeprule.console import DepResConsole
-			con = DepResConsole()
-			con.run()
-			sys.exit ( os.EX_OK )
-		except ImportError:
-			if HIDE_EXCEPTIONS:
-				die ( "Cannot import depres console!", DIE.IMPORT )
-			else:
-				raise
-		except:
-			if HIDE_EXCEPTIONS:
-				die ( "Exiting on console error!", DIE.ERR )
-			else:
-				raise
-
-	else:
-		# sync/create
-		# -- import roverlay modules
-
-		try:
-			from roverlay.remote          import RepoList
-			from roverlay.overlay.creator import OverlayCreator
-		except ImportError:
-			if HIDE_EXCEPTIONS:
-				die ( "Cannot import roverlay modules!", DIE.IMPORT )
-			else:
-				raise
-
-		# -- run methods (and some vars)
-		# imports: nothing
-
-		#repo_list       = None
-		#overlay_creator = None
-
-		actions_done = set()
-		set_action_done = actions_done.add
-
-		# -- run
-
-		# always run sync 'cause commands = {create,sync}
-		# and create implies (no)sync
-		run_sync()
-
-		if 'create' in actions: run_overlay_create()
-
-		if len ( actions ) > len ( actions_done ):
-			die (
-				"Some actions (out of {!r}) could not be performed!".format (
-					actions ), DIE.CMD_LEFTOVER
-			)
-# --- end of main() ---
+ROVERLAY_INSTALLED = False
 
 if __name__ == '__main__':
-	roverlay_main()
-elif not 'pydoc' in sys.modules:
-	die ( "Please don't import this script...", DIE.BAD_USAGE )
+	roverlay.main.main (
+      ROVERLAY_INSTALLED = ROVERLAY_INSTALLED
+   )

diff --git a/roverlay.py b/roverlay/main.py
old mode 100755
new mode 100644
similarity index 85%
copy from roverlay.py
copy to roverlay/main.py
index d18a987..b525ffe
--- a/roverlay.py
+++ b/roverlay/main.py
@@ -1,38 +1,35 @@
-#!/usr/bin/python -OO
+# R overlay -- main()
 # -*- coding: utf-8 -*-
-# R overlay -- main script
 # Copyright (C) 2012 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.
 
 """main script for R overlay creation"""
 
-__all__ = [ 'DIE', 'roverlay_main' ]
+__all__ = [ 'main' ]
 
 import os
 import sys
+import time
 
 # roverlay modules will be imported later
 
-ROVERLAY_INSTALLED  = False
-HIDE_EXCEPTIONS     = False
-CONFIG_FILE_NAME    = "R-overlay.conf"
-
-if ROVERLAY_INSTALLED:
-	# directories where the config file could be found, in order:
-	# * ${PWD}
-	# * user roverlay dir (${HOME}/roverlay)
-	# * system config dir /etc/roverlay
-	CONFIG_DIRS = tuple ((
-		'.',
-		(
-			( os.getenv ( 'HOME' ) or os.path.expanduser ( '~' ) )
-			+ os.sep + 'roverlay'
-		),
-		# os.sep is '/' if /etc exists, so don't care about that
-		'/etc/roverlay',
-	))
+DEFAULT_CONFIG_FILE_NAME = "R-overlay.conf"
 
+# directories where the config file could be found if roverlay has been
+# installed, in order:
+# * ${PWD}
+# * user roverlay dir (${HOME}/roverlay)
+# * system config dir /etc/roverlay
+CONFIG_DIRS = tuple ((
+	'.',
+	(
+		( os.getenv ( 'HOME' ) or os.path.expanduser ( '~' ) )
+		+ os.sep + 'roverlay'
+	),
+	# os.sep is '/' if /etc exists, so don't care about that
+	'/etc/roverlay',
+))
 
 
 class DIE ( object ):
@@ -66,8 +63,19 @@ class DIE ( object ):
 # --- DIE: exit codes ---
 die = DIE.die
 
-def roverlay_main():
-	"""roverlay.py main() - parse args, run overlay creation, sync, ..."""
+def main (
+	ROVERLAY_INSTALLED,
+	HIDE_EXCEPTIONS=False,
+	CONFIG_FILE_NAME=DEFAULT_CONFIG_FILE_NAME
+):
+	"""main() - parse args, run overlay creation, sync, ...
+
+	arguments:
+	* ROVERLAY_INSTALLED -- whether roverlay has been installed or not
+	* HIDE_EXCEPTIONS    -- hide exceptions? (optional, defaults to False)
+	* CONFIG_FILE_NAME   -- name of the config file (optional, defaults to
+	                        "R-overlay.conf")
+	"""
 	def optionally ( call, option, *args, **kw ):
 		if OPTION ( option ):
 			return call ( *args, **kw )
@@ -83,7 +91,7 @@ def roverlay_main():
 				force_distroot = OPTION ( 'force_distroot' )
 			)
 
-			## extra_opts->distdir ... TODO
+			## extra_opts->distdir
 			if 'distdirs' in extra_opts:
 				repo_list.add_distdirs ( OPTION ( 'distdirs' ) )
 			else:
@@ -91,7 +99,10 @@ def roverlay_main():
 				repo_list.load()
 
 			## this runs _nosync() or _sync(), depending on extra_opts->nosync
+			t_start = time.time()
 			repo_list.sync()
+			global sync_time
+			sync_time = time.time() - t_start
 
 			set_action_done ( "sync" )
 
@@ -120,7 +131,14 @@ def roverlay_main():
 				immediate_ebuild_writes = OPTION ( 'immediate_ebuild_writes' ),
 			)
 
+			if 'sync_time' in globals():
+				overlay_creator.set_timestats ( 'sync_packages', sync_time )
+
+			t_start = time.time()
 			repo_list.add_packages ( overlay_creator.add_package )
+			overlay_creator.set_timestats (
+				'add_packages', time.time() - t_start
+			)
 
 			overlay_creator.run ( close_when_done=True )
 
@@ -335,9 +353,4 @@ def roverlay_main():
 				"Some actions (out of {!r}) could not be performed!".format (
 					actions ), DIE.CMD_LEFTOVER
 			)
-# --- end of main() ---
-
-if __name__ == '__main__':
-	roverlay_main()
-elif not 'pydoc' in sys.modules:
-	die ( "Please don't import this script...", DIE.BAD_USAGE )
+# --- end of main (...) ---


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-02-05 17:48 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-02-05 17:48 UTC (permalink / raw
  To: gentoo-commits

commit:     d269d111a7b37dae7824594a8c2f8c060a7a67a5
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Feb  5 17:46:27 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Feb  5 17:46:27 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d269d111

roverlay: --print-package-rules (--ppr)

Added new arg --print-package-rules (--ppr) that prints the package rules
to stdout after reading them. Similar to --print-config, roverlay will
exit afterwards.

---
 roverlay.py         |   15 +++++++++++++++
 roverlay/argutil.py |   18 ++++++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index a13be00..d18a987 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -259,6 +259,21 @@ def roverlay_main():
 			die ( "Cannot print config!" )
 		EXIT_AFTER_CONFIG = True
 
+	if OPTION ( 'print_package_rules' ):
+		# no try-/catch block here
+
+		import roverlay.packagerules.rules
+
+		HLINE = "".rjust ( 79, '-' )
+		print ( HLINE )
+		print (
+			str ( roverlay.packagerules.rules.PackageRules.get_configured() )
+		)
+		print ( HLINE )
+
+		EXIT_AFTER_CONFIG = True
+
+	# -- end of EXIT_AFTER_CONFIG entries
 
 	if 'EXIT_AFTER_CONFIG' in locals() and EXIT_AFTER_CONFIG:
 		pass

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index ceb8baa..d7d8444 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -127,6 +127,14 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
 	)
 
 	arg (
+		'-P', '--package-rules', default=argparse.SUPPRESS,
+		action='append',
+		help="package rule file, can be specified more than once.",
+		type=is_fs_file_or_dir,
+		metavar='<file|dir>',
+	)
+
+	arg (
 		'--distdir', '--from', default=argparse.SUPPRESS,
 		action='append',
 		help='''
@@ -236,6 +244,12 @@ def get_parser ( command_map, default_config_file, default_command='create' ):
 	)
 
 	arg (
+		'--print-package-rules', '--ppr',
+		help="print package rules after parsing them and exit",
+		**opt_in
+	)
+
+	arg (
 		'--list-config-entries', '--help-config',
 		help="list all known config entries",
 		**opt_in
@@ -320,6 +334,7 @@ def parse_argv ( command_map, **kw ):
 		print_stats             = p.stats,
 		print_config            = p.print_config,
 		list_config             = p.list_config_entries,
+		print_package_rules     = p.print_package_rules,
 		force_distroot          = p.force_distroot,
 		skip_manifest           = p.no_manifest,
 		incremental             = p.incremental,
@@ -339,6 +354,9 @@ def parse_argv ( command_map, **kw ):
 	if given ( 'repo_config' ):
 		doconf ( p.repo_config, 'REPO.config_files' )
 
+	if given ( 'package_rules' ):
+		doconf ( p.package_rules, 'PACKAGE_RULES.files' )
+
 	if given ( 'distroot' ):
 		doconf ( p.distroot, 'distfiles.root' )
 


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-01-28 23:54 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-01-28 23:54 UTC (permalink / raw
  To: gentoo-commits

commit:     62ffeca1024a39a7bf0d5f83af1cb73eadaa7a90
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jan 28 23:50:27 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jan 28 23:50:27 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=62ffeca1

increase version number to 0.2.3

Notable changes:
* use portage libs directly for Manifest file creation
* SymlinkDistroot/SymlinkDistdir for safe per-package DISTDIRs during
  Manifest file creation (currently only used by the portage implementation)

---
 roverlay/__init__.py |    4 ++--
 setup.py             |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 0f1a850..5b0f63b 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -13,8 +13,8 @@ load_config_file) and some information vars (__version__, name, ...).
 __all__ = [ 'setup_initial_logger', 'load_config_file', ]
 
 name        = "R_overlay"
-version     = ( 0, 2, 2 )
-#__version__ = "0.2.2"
+version     = ( 0, 2, 3 )
+#__version__ = "0.2.3"
 __version__ = '.'.join ( str ( i ) for i in version )
 
 description_str = "R overlay creation (roverlay) " + __version__

diff --git a/setup.py b/setup.py
index 77659a9..0e55746 100755
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 from distutils import core
 
-VERSION = '0.2'
+VERSION = '0.2.3'
 
 core.setup (
 	name         = 'R_Overlay',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2013-01-09 19:15 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2013-01-09 19:15 UTC (permalink / raw
  To: gentoo-commits

commit:     53fe8b51062310a111e8ece22dcef8a32cedb0aa
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jan  9 18:42:10 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jan  9 18:49:16 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=53fe8b51

roverlay.py: proper config file searching

This commit fixes a case where an installed version of roverlay cannot find
the system-wide config file /etc/roverlay/R-overlay.conf.

Other changes:
* the user config file is now expected at ${HOME}/roverlay/R-overlay.conf
  instead of ${HOME}/.R-overlay.conf
* bumped version to 0.2.2

---
 roverlay.py          |   43 +++++++++++++++++++++++++++++++++++--------
 roverlay/__init__.py |    4 ++--
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index 51dfeec..a13be00 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -18,6 +18,23 @@ ROVERLAY_INSTALLED  = False
 HIDE_EXCEPTIONS     = False
 CONFIG_FILE_NAME    = "R-overlay.conf"
 
+if ROVERLAY_INSTALLED:
+	# directories where the config file could be found, in order:
+	# * ${PWD}
+	# * user roverlay dir (${HOME}/roverlay)
+	# * system config dir /etc/roverlay
+	CONFIG_DIRS = tuple ((
+		'.',
+		(
+			( os.getenv ( 'HOME' ) or os.path.expanduser ( '~' ) )
+			+ os.sep + 'roverlay'
+		),
+		# os.sep is '/' if /etc exists, so don't care about that
+		'/etc/roverlay',
+	))
+
+
+
 class DIE ( object ):
 	"""Container class for various system exit 'events'."""
 	NOP          =  os.EX_OK
@@ -149,16 +166,23 @@ def roverlay_main():
 		'nop'            : 'does nothing',
 	}
 
-	DEFAULT_CONFIG_FILE = CONFIG_FILE_NAME
 
+	DEFAULT_CONFIG_FILE = None
 	# search for the config file if roverlay has been installed
-	if ROVERLAY_INSTALLED and not os.path.exists ( DEFAULT_CONFIG_FILE ):
-		c = os.path.expanduser ( '~' ) + os.sep + '.' + CONFIG_FILE_NAME
-		if os.path.isfile ( c ):
-			DEFAULT_CONFIG_FILE = c
-		elif os.path.isfile ( '/etc/roverlay' + CONFIG_FILE_NAME ):
-			# os.sep is '/' if /etc exists, so don't care about that
-			DEFAULT_CONFIG_FILE = '/etc/roverlay' + CONFIG_FILE_NAME
+	if ROVERLAY_INSTALLED:
+		cfg        = None
+		config_dir = None
+
+		for config_dir in CONFIG_DIRS:
+			cfg = config_dir + os.sep + CONFIG_FILE_NAME
+			if os.path.isfile ( cfg ):
+				DEFAULT_CONFIG_FILE = cfg
+				break
+
+		del config_dir, cfg
+	elif os.path.exists ( CONFIG_FILE_NAME ):
+		DEFAULT_CONFIG_FILE = CONFIG_FILE_NAME
+
 
 	commands, config_file, additional_config, extra_opts = \
 		roverlay.argutil.parse_argv (
@@ -207,6 +231,9 @@ def roverlay_main():
 		)
 		del config_file, additional_config
 	except:
+		if not config_file:
+			sys.stderr.write ( '!!! No config file found.\n' )
+
 		if HIDE_EXCEPTIONS:
 			die (
 				"Cannot load config file {!r}.".format ( config_file ), DIE.CONFIG

diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index f39c3a5..0f1a850 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -13,8 +13,8 @@ load_config_file) and some information vars (__version__, name, ...).
 __all__ = [ 'setup_initial_logger', 'load_config_file', ]
 
 name        = "R_overlay"
-version     = ( 0, 2, 1 )
-#__version__ = "0.2.1"
+version     = ( 0, 2, 2 )
+#__version__ = "0.2.2"
 __version__ = '.'.join ( str ( i ) for i in version )
 
 description_str = "R overlay creation (roverlay) " + __version__


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2012-08-20 14:04 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2012-08-20 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     6cf80c72f1300d77c458866636a8090e667c5ddc
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Aug 20 13:58:22 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Aug 20 13:58:22 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=6cf80c72

R Overlay 0.2

---
 roverlay/__init__.py |    6 +++---
 setup.py             |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/roverlay/__init__.py b/roverlay/__init__.py
index 22f24c9..ba8c032 100644
--- a/roverlay/__init__.py
+++ b/roverlay/__init__.py
@@ -13,11 +13,11 @@ load_config_file) and some information vars (__version__, name, ...).
 __all__ = [ 'setup_initial_logger', 'load_config_file', ]
 
 name        = "R_overlay"
-version     = ( 0, 0, 1 )
-__version__ = "0.0.1"
+version     = ( 0, 2 )
+__version__ = "0.2"
 #__version__ = '.'.join ( str ( i ) for i in version )
 
-description_str = "R overlay creation " + __version__
+description_str = "R overlay creation (roverlay) " + __version__
 license_str=(
 	'Copyright (C) 2012 Andr\xc3\xa9 Erdmann\n'
 	'Distributed under the terms of the GNU General Public License;\n'

diff --git a/setup.py b/setup.py
index 82919da..77659a9 100755
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 from distutils import core
 
-VERSION = '0.1'
+VERSION = '0.2'
 
 core.setup (
 	name         = 'R_Overlay',


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2012-07-30 15:53 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2012-07-30 15:53 UTC (permalink / raw
  To: gentoo-commits

commit:     da7273ecc3c7a7865cfeb830d89831c32c4458bf
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Jul 30 15:46:13 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Jul 30 15:53:31 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=da7273ec

main script: --no-manifest

---
 roverlay.py         |    5 ++++-
 roverlay/argutil.py |    7 +++++++
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/roverlay.py b/roverlay.py
index 3504fab..3297325 100755
--- a/roverlay.py
+++ b/roverlay.py
@@ -221,7 +221,10 @@ def run_overlay_create():
 	#run_sync()
 	try:
 		global overlay
-		overlay = OverlayCreator ( allow_write=OPTION ( 'write_overlay' ) )
+		overlay = OverlayCreator (
+			skip_manifest=OPTION ( 'skip_manifest' ),
+			allow_write=OPTION ( 'write_overlay' )
+		)
 
 		repo_list.add_packages ( overlay.add_package )
 

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 98a0406..4cefdbd 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -186,6 +186,12 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 	# --write-desc
 	# --log-level, --log-console, --log...
 
+	arg (
+		'--no-manifest',
+		help="skip Manifest creation (results in useless overlay)",
+		**opt_in
+	)
+
 	# TODO
 	arg (
 		'--debug',
@@ -238,6 +244,7 @@ def parse_argv ( *args, **kw ):
 		print_config   = p.print_config,
 		list_config    = p.list_config_entries,
 		force_distroot = p.force_distroot,
+		skip_manifest  = p.no_manifest,
 	)
 
 	if given ( 'overlay' ):


^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2012-07-06 22:19 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2012-07-06 22:19 UTC (permalink / raw
  To: gentoo-commits

commit:     8119905e27e78619ea226205d20874f220f5bb37
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul  6 22:14:41 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul  6 22:14:41 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=8119905e

main script: --help-config, --overlay

	modified:   main.py
	modified:   roverlay/argutil.py

---
 main.py             |   29 ++++++++++++++++++++++++++---
 roverlay/argutil.py |   19 +++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/main.py b/main.py
index df76b32..ce1189f 100755
--- a/main.py
+++ b/main.py
@@ -26,7 +26,7 @@ class DIE ( object ):
 		if msg is not None:
 			sys.stderr.write ( msg + "\n" )
 #		else:
-#			sys.stderr.write ( "died." )
+#			sys.stderr.write ( "died.\n" )
 		sys.exit ( code )
 	# --- end of die (...) ---
 
@@ -39,6 +39,9 @@ if __name__ != '__main__':
 
 
 # get args
+# imports roverlay.argutil (deleted when done)
+
+
 try:
 	import roverlay.argutil
 except ImportError:
@@ -49,7 +52,8 @@ except ImportError:
 
 COMMAND_DESCRIPTION = {
 	'sync'           : 'sync repos',
-	'create'         : 'create the overlay',
+	'create'         : 'create the overlay '
+	                    '(implies sync, override with --nosync)',
 #	'depres_console' : 'run an interactive depres console; TODO/REMOVE',
 	'nop'            : 'does nothing',
 }
@@ -66,6 +70,8 @@ del roverlay.argutil
 
 # -- load config
 
+# imports: roverlay, roverlay.config.entryutil (if --help-config)
+
 try:
 	import roverlay
 except ImportError:
@@ -82,20 +88,36 @@ try:
 	del config_file, additional_config
 except:
 	if HIDE_EXCEPTIONS:
-		die ( "Cannot load config file %r." % config_file, DIE.CONFIG )
+		die ( "Cannot load config file {!r}.".format ( config_file ), DIE.CONFIG )
 	else:
 		raise
 
+if OPTION ( 'list_config' ):
+	try:
+		from roverlay.config.entryutil import list_entries
+		print ( "== main config file ==\n" )
+		print ( list_entries() )
+	except:
+		raise
+		die ( "Cannot list config entries!" )
+
+	EXIT_AFTER_CONFIG = True
+
 if OPTION ( 'print_config' ):
 	try:
 		conf.visualize ( into=sys.stdout )
 	except:
 		die ( "Cannot print config!" )
+	EXIT_AFTER_CONFIG = True
+
+
+if 'EXIT_AFTER_CONFIG' in locals() and EXIT_AFTER_CONFIG:
 	sys.exit ( os.EX_OK )
 
 
 # -- determine commands to run
 # (TODO) could replace this section when adding more actions
+# imports roverlay.remote, roverlay.overlay.creator
 
 actions = set ( filter ( lambda x : x != 'nop', commands ) )
 
@@ -124,6 +146,7 @@ except ImportError:
 
 
 # -- run methods (and some vars)
+# imports: nothing
 
 actions_done = set()
 set_action_done = actions_done.add

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 540743a..4750d15 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -113,6 +113,14 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 	)
 
 	arg (
+		'--overlay', '-O', default=argparse.SUPPRESS,
+		help='overlay directory to write (implies --write)',
+		metavar="<OVERLAY>",
+		type=couldbe_fs_dir
+	)
+
+
+	arg (
 		'--show-overlay', '--show',
 		help="print ebuilds and metadata to console",
 		**opt_in
@@ -157,6 +165,12 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 		**opt_in
 	)
 
+	arg (
+		'--list-config-entries', '--help-config',
+		help="list all known config entries",
+		**opt_in
+	)
+
 	# --write-desc
 	# --log-level, --log-console, --log...
 
@@ -210,9 +224,14 @@ def parse_argv ( *args, **kw ):
 		write_overlay  = p.write_overlay,
 		print_stats    = p.stats,
 		print_config   = p.print_config,
+		list_config    = p.list_config_entries,
 		force_distroot = p.force_distroot,
 	)
 
+	if given ( 'overlay' ):
+		doconf ( p.overlay, 'OVERLAY.dir' )
+		extra ['write_overlay'] = True
+
 	if given ( 'field_definition' ):
 		doconf ( p.field_definition, 'DESCRIPTION.field_definition_file' )
 



^ permalink raw reply related	[flat|nested] 18+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/
@ 2012-07-05 16:00 André Erdmann
  0 siblings, 0 replies; 18+ messages in thread
From: André Erdmann @ 2012-07-05 16:00 UTC (permalink / raw
  To: gentoo-commits

commit:     51c037ec3f153398db7f2e10c3c5961d328617b1
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul  5 15:50:15 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul  5 15:50:15 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=51c037ec

main script: --print-config

	modified:   main.py
	modified:   roverlay/argutil.py

---
 main.py             |   24 ++++++++++++++++++------
 roverlay/argutil.py |   12 +++++++++++-
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/main.py b/main.py
index a4f2227..df76b32 100755
--- a/main.py
+++ b/main.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+import os
 import sys
 
 # roverlay modules will be imported later
@@ -7,11 +8,11 @@ import sys
 HIDE_EXCEPTIONS = False
 
 class DIE ( object ):
-	NOP          =   0
-	ERR          =   1
-	BAD_USAGE    =   3
-	ARG          =   9
-	CONFIG       =  10
+	NOP          =  os.EX_OK
+	ERR          =  1
+	BAD_USAGE    =  os.EX_USAGE
+	ARG          =  9
+	CONFIG       =  os.EX_CONFIG
 	OV_CREATE    =  20
 	SYNC         =  30
 	CMD_LEFTOVER =  90
@@ -74,7 +75,10 @@ except ImportError:
 		raise
 
 try:
-	roverlay.load_config_file ( config_file, extraconf=additional_config )
+	conf = roverlay.load_config_file (
+		config_file,
+		extraconf=additional_config
+	)
 	del config_file, additional_config
 except:
 	if HIDE_EXCEPTIONS:
@@ -82,6 +86,14 @@ except:
 	else:
 		raise
 
+if OPTION ( 'print_config' ):
+	try:
+		conf.visualize ( into=sys.stdout )
+	except:
+		die ( "Cannot print config!" )
+	sys.exit ( os.EX_OK )
+
+
 # -- determine commands to run
 # (TODO) could replace this section when adding more actions
 

diff --git a/roverlay/argutil.py b/roverlay/argutil.py
index 8e37694..540743a 100644
--- a/roverlay/argutil.py
+++ b/roverlay/argutil.py
@@ -151,12 +151,21 @@ def get_parser ( CMD_DESC, DEFAULT_CONFIG ):
 		**opt_in
 	)
 
+	arg (
+		'--print-config', '--pc',
+		help="print config and exit",
+		**opt_in
+	)
+
+	# --write-desc
+	# --log-level, --log-console, --log...
+
 	# TODO
 	arg (
 		'--debug',
 		help='''
 			Turn on debugging. This produces a lot of messages.
-			(TODO: always on).
+			(TODO: has no effect).
 		''',
 		**opt_in
 	)
@@ -200,6 +209,7 @@ def parse_argv ( *args, **kw ):
 		show_overlay   = p.show_overlay,
 		write_overlay  = p.write_overlay,
 		print_stats    = p.stats,
+		print_config   = p.print_config,
 		force_distroot = p.force_distroot,
 	)
 



^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2024-08-23  7:28 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-02 15:14 [gentoo-commits] proj/R_overlay:master commit in: /, roverlay/ André Erdmann
  -- strict thread matches above, loose matches on Subject: below --
2024-08-23  7:28 Benda XU
2014-08-23 19:03 André Erdmann
2014-07-29 20:26 André Erdmann
2014-08-23 19:03 ` André Erdmann
2013-09-23 15:30 André Erdmann
2013-08-19 15:42 André Erdmann
2013-08-09 10:18 André Erdmann
2013-07-11 17:11 André Erdmann
2013-04-25 16:44 André Erdmann
2013-02-09 20:45 André Erdmann
2013-02-05 17:48 André Erdmann
2013-01-28 23:54 André Erdmann
2013-01-09 19:15 André Erdmann
2012-08-20 14:04 André Erdmann
2012-07-30 15:53 André Erdmann
2012-07-06 22:19 André Erdmann
2012-07-05 16:00 André Erdmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox