config file parsing

This commit is contained in:
BJ Dierkes 2010-02-21 03:33:34 -05:00
parent e4dc57db98
commit 0733ba190c
9 changed files with 49 additions and 112 deletions

View File

@ -5,13 +5,12 @@
+ Namespace config dictionaries are overwritten by [namespace] section of
primary applications configuration files. Meaning, a namespace called
'example' reads configurations from [example] in the applications config
files. Note: the [namespace] section is required.
files. Additionally, Plugin configs can now exist in main application
configs under [plugin], as well as the typical plugins.d directory.
+ Added new 'bootstrap' directory where all application setup happens for
each namespace, and refactored 'plugins' around this bootstrap layout.
Along with that, discarded the 'plugins' directory. Plugins are now
simply optional namespaces.
+ Plugin configs can now exist in main application configs under [plugin],
as well as the typical plugins.d directory.
+ Plugins can now be enabled by the [root] 'enabled_plugins' list, or under
a [plugin] config by setting 'enable_plugin=true'.

View File

@ -117,6 +117,7 @@ def set_config_opts_per_file(namespace, section, config_file):
cnf = ConfigObj(config_file)
try:
config.update(cnf[section])
cnf.update(config)
except KeyError:
# FIX ME: can't log here...
# log.debug('missing section %s in %s.' % (section, config_file))

View File

@ -12,6 +12,28 @@ from cement.core.opt import init_parser
log = get_logger(__name__)
def get_namespace(namespace):
"""
Return the namespace object whose label is 'namespace'.
Required Arguments:
namespace
The label of the namespace object to return
"""
if namespaces.has_key(namespace):
return namespaces[namespace]
else:
log.fatal("the namespace '%s' doesn't exist" % namespace)
def get_config(namespace):
"""Get a namespace's config dictionary."""
if namespaces.has_key(namespace):
return namespaces[namespace].config
else:
log.fatal("the namespace '%s' doesn't exist" % namespace)
def register_namespaceOLD(**kwargs):
"""
Decorator function to register a namespace. Alternative to registering

View File

@ -9,7 +9,8 @@ from cement.core.exc import CementConfigError, CementRuntimeError
from cement.core.log import get_logger
from cement.core.hook import run_hooks
from cement.core.configuration import set_config_opts_per_file, t_f_pass
from cement.core.namespace import CementNamespace, define_namespace
from cement.core.namespace import CementNamespace, define_namespace, \
get_namespace
from cement.core.configuration import ensure_api_compat
log = get_logger(__name__)
@ -26,13 +27,14 @@ def get_enabled_plugins_per_files():
Uses the namespaces['root'].config dictionary.
"""
for file in os.listdir(namespaces['root'].config['plugin_config_dir']):
cnf = ConfigObj(os.path.join(namespaces['root'].config['plugin_config_dir'], file))
_n = get_namespace('root')
for file in os.listdir(_n.config['plugin_config_dir']):
cnf = ConfigObj(os.path.join(_n.config['plugin_config_dir'], file))
for sect in cnf.sections:
if sect != 'root' and cnf[sect].has_key('enable_plugin') \
and t_f_pass(cnf[sect]['enable_plugin']) == True \
and not sect in namespaces['root'].config['enabled_plugins']:
namespaces['root'].config['enabled_plugins'].append(sect)
and not sect in _n.config['enabled_plugins']:
_n.config['enabled_plugins'].append(sect)
def register_pluginOLD(**kwargs):
"""

View File

@ -1,6 +1,6 @@
"""This is the Example controller for {{package}}."""
from cement import namespaces
from cement.core.namespace import get_config
from cement.core.log import get_logger
from cement.core.controller import CementController, expose
from cement.core.hook import run_hooks
@ -20,6 +20,12 @@ class ExampleController(CementController):
"""
# You can get the root application config like this:
config = get_config('root')
# Or you can get your example namespace config like this:
config = get_config('example')
# You can print or log output however you like since this function
# does not render out to a template.

View File

@ -15,6 +15,7 @@ from cement.core.app_setup import lay_cement
from cement.core.configuration import ensure_api_compat
from cement.core.command import run_command
from cement.core.namespace import get_config
from helloworld.config import default_config
REQUIRED_CEMENT_API = '0.7-0.8:20100210'
@ -35,7 +36,7 @@ def main():
sys.argv.append('default')
run_command(sys.argv[1])
print get_config('root')
except CementArgumentError, e:
print("CementArgumentError > %s" % e)
sys.exit(e.code)

View File

@ -1,6 +1,6 @@
"""This is the Example controller for helloworld."""
from cement import namespaces
from cement.core.namespace import get_config
from cement.core.log import get_logger
from cement.core.controller import CementController, expose
from cement.core.hook import run_hooks
@ -20,8 +20,15 @@ class ExampleController(CementController):
"""
# You can get the root application config like this:
config = get_config('root')
# Or you can get your example namespace config like this:
config = get_config('example')
# You can print or log output however you like since this function
# does not render out to a template.
# Commands are all passed the cli_opts, cli_args from the command line.
# So if you have added cli options in your helloworld.bootstrap.example

View File

@ -1 +0,0 @@
__import__('pkg_resources').declare_namespace(__name__)

View File

@ -1,100 +0,0 @@
"""This is an example plugin for helloworld."""
import sys, os
import logging
from cement import namespaces
from cement.core.log import get_logger
from cement.core.opt import init_parser
from cement.core.hook import define_hook, register_hook
from cement.core.plugin import CementPlugin, register_plugin
from helloworld.appmain import VERSION, BANNER
log = get_logger(__name__)
REQUIRED_CEMENT_API = '0.7-0.8:20100210'
@register_plugin()
class ExamplePlugin(CementPlugin):
# This is how we define a hook that we will honor later (see the example
# controller). Hooks allow other plugins to tie into your namespace.
define_hook('my_example_hook')
def __init__(self):
CementPlugin.__init__(self,
label='example',
version=VERSION,
description='Example plugin for helloworld',
required_api=REQUIRED_CEMENT_API,
banner=BANNER,
controller = 'ExampleController', # from helloworld.controllers.example
)
# plugin configurations can be setup this way
self.config['example_option'] = False
# plugin cli options can be setup this way. Generally, cli options
# are used to set config options... so if you probably want to
# add your options to both.
self.options.add_option('-E', '--example', action='store',
dest='example_option', default=None, help='Example Plugin Option'
)
#
# HOOKS: Usually defined in the main plugin file (here). Functions
# that you decorate with @register_hook() will be run whenever/wherever
# run_hooks('the_hook_name') is called.
#
@register_hook()
def options_hook(*args, **kwargs):
"""
Use this hook to add options to other namespaces. An OptParse object is
expected on return, and any options will be merged into the root options.
root options can also be used as local options by setting the config
option 'merge_root_options = true' in the plugin config.
"""
root_options = init_parser()
root_options.add_option('-G', '--root-option', action ='store_true',
dest='root_option', default=None, help='Example root option'
)
# return the namespace and the root options to add.
return ('root', root_options)
@register_hook()
def options_hook(*args, **kwargs):
"""
We can also use the options hook to tie into other plugins, or even our
own. This is an alternateway of adding options for your [or other]
plugins.
"""
my_options = init_parser()
my_options.add_option('--new-local', action ='store',
dest='newlocal_option', default=None, help='Example Local option'
)
# return the namespace and the root options to add.
return ('example', my_options)
@register_hook()
def post_options_hook(*args, **kwargs):
"""
Use this hook if any operations need to be performed if a root
option is passed. Notice that we set a root option of -G in our
root_options_hook above. Here we can access that value from the
root namespace configuration.
"""
cnf = namespaces['root'].config
if cnf.has_key('root_option'):
print "root_option => %s", cnf['root_option']
# then do something with it
@register_hook()
def my_example_hook(*args, **kwargs):
"""This is an example hook, that I define in my plugin config above."""
return "I'm in my_example_hook"