From 059f2a334e8c9505d8306dd651d1e3da12c0d49a Mon Sep 17 00:00:00 2001 From: BJ Dierkes Date: Fri, 11 Dec 2009 00:06:16 -0600 Subject: [PATCH] global config, no longer pass around the config dict --- cement/__init__.py | 2 + cement/core/__init__.py | 2 +- cement/core/app_setup.py | 46 +++++++++---------- cement/core/{config.py => configuration.py} | 31 ++++++++----- cement/core/log.py | 4 +- cement/core/options.py | 22 ++++----- examples/CementExample/cement_example/core.py | 11 +++-- .../cement/__init__.py | 2 +- .../cement/plugins/clibasic.py | 41 +++++++++++------ plugins/cement-plugins-clibasic/setup.py | 2 +- 10 files changed, 94 insertions(+), 69 deletions(-) rename cement/core/{config.py => configuration.py} (57%) diff --git a/cement/__init__.py b/cement/__init__.py index d91dab46..918f4548 100644 --- a/cement/__init__.py +++ b/cement/__init__.py @@ -1,2 +1,4 @@ """Cement top level module""" __import__('pkg_resources').declare_namespace(__name__) + +from cement.core.configuration import config diff --git a/cement/core/__init__.py b/cement/core/__init__.py index d49a770f..67bd98db 100644 --- a/cement/core/__init__.py +++ b/cement/core/__init__.py @@ -1,2 +1,2 @@ """Cement core module, holds all core framework code.""" -__import__('pkg_resources').declare_namespace(__name__) \ No newline at end of file +__import__('pkg_resources').declare_namespace(__name__) diff --git a/cement/core/app_setup.py b/cement/core/app_setup.py index 5c2b0de7..1cce2df2 100644 --- a/cement/core/app_setup.py +++ b/cement/core/app_setup.py @@ -3,17 +3,17 @@ import os from pkg_resources import get_distribution from cement import plugins as cement_plugins +from cement import config from cement.core.log import setup_logging from cement.core.options import init_parser, parse_options -from cement.core.config import set_config_opts_per_file +from cement.core.configuration import set_config_opts_per_file from cement.core.options import set_config_opts_per_cli_opts from cement.core.exc import CementConfigError, CementRuntimeError CEMENT_ABI = "20091207" class CementCommand(object): - def __init__(self, config, cli_opts=None, cli_args=None, handlers=None): - self.config = config + def __init__(self, cli_opts=None, cli_args=None, handlers=None): self.cli_opts = cli_opts self.cli_args = cli_args self.handlers = handlers @@ -28,7 +28,7 @@ class CementCommand(object): class CementPlugin(object): - def __init__(self, config): + def __init__(self): self.version = None self.description = "" self.commands = {} @@ -41,7 +41,7 @@ def get_abi_version(): return CEMENT_ABI -def lay_cement(config, version_banner=None): +def lay_cement(default_app_config=None, version_banner=None): """ Primary method to setup an application for Cement. @@ -50,28 +50,26 @@ def lay_cement(config, version_banner=None): config => dict containing application config. version_banner => Option txt displayed for --version """ - dcf = {} # default config - dcf['config_source'] = ['defaults'] - dcf['enabled_plugins'] = [] # no default plugins, add via the config file - dcf['debug'] = False - dcf['show_plugin_load'] = True + - dcf.update(config) # override the actual defaults - config = dcf # take the new config with changes + #dcf.update(config) # override the actual defaults + #config = dcf # take the new config with changes + global config + config.update(default_app_config) validate_config(config) if not version_banner: version_banner = get_distribution(config['app_egg_name']).version for cf in config['config_files']: - config = set_config_opts_per_file(config, config['app_module'], cf) + set_config_opts_per_file(config, config['app_module'], cf) - options = init_parser(config, version_banner) - (config, commands, handlers, options) = load_all_plugins(config, options) - (config, cli_opts, cli_args) = parse_options(config, options, commands) + options = init_parser(version_banner) + (commands, handlers, options) = load_all_plugins(options) + (cli_opts, cli_args) = parse_options(options, commands) config = set_config_opts_per_cli_opts(config, cli_opts) - setup_logging(config) - return (config, cli_opts, cli_args, commands, handlers) + setup_logging() + return (cli_opts, cli_args, commands, handlers) def ensure_abi_compat(module_name, required_abi): @@ -102,7 +100,7 @@ def validate_config(config): os.makedirs(d) -def load_plugin(config, plugin): +def load_plugin(plugin): """ Load a cement type plugin. @@ -135,7 +133,7 @@ def load_plugin(config, plugin): raise CementConfigError, \ 'failed to load %s plugin: %s' % (plugin, e) - plugin_cls = pluginobj.register_plugin(config) + plugin_cls = pluginobj.register_plugin() ensure_abi_compat(plugin_cls.__module__, plugin_cls.required_abi) @@ -147,7 +145,7 @@ def load_plugin(config, plugin): return plugin_cls -def load_all_plugins(config, options): +def load_all_plugins(options): """ Attempt to load all enabled plugins. Passes the existing config and options object to each plugin and allows them to add/update each. @@ -155,7 +153,7 @@ def load_all_plugins(config, options): plugin_commands = {} plugin_handlers = {} for plugin in config['enabled_plugins']: - plugin_cls = load_plugin(config, plugin) + plugin_cls = load_plugin(plugin) # add the plugin commands for key in plugin_cls.commands: @@ -178,9 +176,11 @@ def load_all_plugins(config, options): for opt in plugin_cls.options.parser._get_all_options(): if opt.get_opt_string() == '--help': pass + elif opt.get_opt_string() == '--version': + pass else: options.parser.add_option(opt) - return (config, plugin_commands, plugin_handlers, options) + return (plugin_commands, plugin_handlers, options) \ No newline at end of file diff --git a/cement/core/config.py b/cement/core/configuration.py similarity index 57% rename from cement/core/config.py rename to cement/core/configuration.py index 68e0bed2..67370312 100644 --- a/cement/core/config.py +++ b/cement/core/configuration.py @@ -4,26 +4,36 @@ from configobj import ConfigObj from cement.core.exc import CementConfigError -def set_config_opts_per_file(config, section, config_file): +def get_default_config(): + dcf = {} + dcf['config_source'] = ['defaults'] + dcf['enabled_plugins'] = [] + dcf['debug'] = False + dcf['show_plugin_load'] = True + return dcf +# global config dictionary +config = get_default_config() + +def set_config_opts_per_file(tmpconfig, section, config_file): """ Parse config file options for into config dict. Will do nothing if the config file does not exist. Arguments: - config => dict containing application configurations. + config => dict containing configurations. section => section of the configuration file to read. config_file => The config file to parse. """ - if not config.has_key('config_source'): - config['config_source'] = [] + if not tmpconfig.has_key('config_source'): + tmpconfig['config_source'] = [] if os.path.exists(config_file): - config['config_source'].append(config_file) - config['config_file'] = config_file + tmpconfig['config_source'].append(config_file) + tmpconfig['config_file'] = config_file cnf = ConfigObj(config_file) try: - config.update(cnf[section]) + tmpconfig.update(cnf[section]) except KeyError: raise CementConfigError, \ 'missing section %s in %s.' % (section, config_file) @@ -31,9 +41,8 @@ def set_config_opts_per_file(config, section, config_file): for option in cnf[section]: if cnf[section][option] in ['True', 'true', True, 'yes', 'Yes', '1']: - config[option] = True + tmpconfig[option] = True elif cnf[section][option] in ['False', 'false', False, 'no', 'No', '0']: - config[option] = False - - return config \ No newline at end of file + tmpconfig[option] = False + return tmpconfig \ No newline at end of file diff --git a/cement/core/log.py b/cement/core/log.py index 3959e037..dfbe5b59 100644 --- a/cement/core/log.py +++ b/cement/core/log.py @@ -3,7 +3,9 @@ import logging from logging.handlers import RotatingFileHandler -def setup_logging(config): +from cement import config + +def setup_logging(): """ Primary Cement method to setup logging. diff --git a/cement/core/options.py b/cement/core/options.py index 65358c0a..8b1e6575 100644 --- a/cement/core/options.py +++ b/cement/core/options.py @@ -3,13 +3,14 @@ from optparse import OptionParser, IndentedHelpFormatter import sys, os +from cement import config + class Options(object): """ This class is used to setup the OptParse object for later use, and is the object that is passed around thoughout the application. """ - def __init__(self, config, version_banner): - self.config = config + def __init__(self, version_banner): fmt = IndentedHelpFormatter( indent_increment=4, max_help_position=32, width=77, short_first=1 ) @@ -24,7 +25,7 @@ class Options(object): pass -def init_parser(config, version_banner=None): +def init_parser(version_banner=None): """ Sets up the Options object and returns it for use throughout the application. @@ -34,11 +35,10 @@ def init_parser(config, version_banner=None): config => dict containing the application configurations version_banner => option txt to be display for --version. """ - o = Options(config, version_banner) + o = Options(version_banner) return o - -def parse_options(config, options_obj, commands=None): +def parse_options(options_obj, commands=None): """ The actual method that parses the command line options and args. @@ -79,21 +79,21 @@ Help? try [COMMAND]-help""" % (config['app_name'], cmd_txt) o.add_default_options() (opts, args) = o.parser.parse_args() - return (config, opts, args) + return (opts, args) -def set_config_opts_per_cli_opts(config, cli_opts): +def set_config_opts_per_cli_opts(tmpconfig, cli_opts): """ Determine if any config optons were passed via cli options, and if so override the config option. Returns the updated config dict. """ - for opt in config: + for opt in tmpconfig: try: val = getattr(cli_opts, opt) if val: - config[opt] = val + tmpconfig[opt] = val except AttributeError: pass - return config \ No newline at end of file + return tmpconfig \ No newline at end of file diff --git a/examples/CementExample/cement_example/core.py b/examples/CementExample/cement_example/core.py index 3eb0f91c..24ec5574 100644 --- a/examples/CementExample/cement_example/core.py +++ b/examples/CementExample/cement_example/core.py @@ -1,8 +1,9 @@ """An example application using the Cement framework.""" -import os +import sys, os import re +from cement import config from cement.core.log import get_logger from cement.core.app_setup import lay_cement, ensure_abi_compat from cement.core.exc import CementArgumentError @@ -32,8 +33,8 @@ def main(): dcf['plugin_dir'] = '%s/plugins.d' % dcf['statedir'] dcf['plugins'] = {} - (config, cli_opts, cli_args, commands, handlers) = lay_cement(dcf) - + (cli_opts, cli_args, commands, handlers) = lay_cement(dcf) + log = get_logger(__name__) log.debug("Cement Framework Initialized!") @@ -46,7 +47,7 @@ def main(): if m: # command matches a plugin command help, run help() if commands.has_key(m.group(1)): - cmd = commands[m.group(1)](config, cli_opts, cli_args) + cmd = commands[m.group(1)](cli_opts, cli_args) cmd.help() else: raise CementArgumentError, "Unknown command, see --help?" @@ -54,7 +55,7 @@ def main(): elif commands.has_key(cli_args[0]): # commands are all the plugin commands that have been registered. # if cli_args[0] matches a plugin command then we execute it. - cmd = commands[cli_args[0]](config, cli_opts, cli_args, handlers) + cmd = commands[cli_args[0]](cli_opts, cli_args, handlers) cmd.run() else: diff --git a/plugins/cement-plugins-clibasic/cement/__init__.py b/plugins/cement-plugins-clibasic/cement/__init__.py index b0d64337..27e6d49b 100644 --- a/plugins/cement-plugins-clibasic/cement/__init__.py +++ b/plugins/cement-plugins-clibasic/cement/__init__.py @@ -1 +1 @@ -__import__('pkg_resources').declare_namespace(__name__) \ No newline at end of file +#__import__('pkg_resources').declare_namespace(__name__) \ No newline at end of file diff --git a/plugins/cement-plugins-clibasic/cement/plugins/clibasic.py b/plugins/cement-plugins-clibasic/cement/plugins/clibasic.py index 9a8a6da7..e8dea048 100644 --- a/plugins/cement-plugins-clibasic/cement/plugins/clibasic.py +++ b/plugins/cement-plugins-clibasic/cement/plugins/clibasic.py @@ -5,19 +5,20 @@ This is a simple plugin to add some basic functionality. import os from pkg_resources import get_distribution +from cement import config from cement.core.log import get_logger from cement.core.app_setup import CementCommand, CementPlugin from cement.core.options import init_parser log = get_logger(__name__) -def register_plugin(global_config): - return CLIBasicPlugin(global_config) +def register_plugin(): + return CLIBasicPlugin() class CLIBasicPlugin(CementPlugin): - def __init__(self, global_config): - CementPlugin.__init__(self, global_config) - self.version = get_distribution('cement').version + def __init__(self): + CementPlugin.__init__(self) + self.version = '0.1' self.required_abi = '20091207' self.description = "Basic CLI Commands for Cement Applications" self.config = { @@ -28,23 +29,33 @@ class CLIBasicPlugin(CementPlugin): 'listplugins' : ListPluginsCommand } self.handlers = {} - self.options = init_parser(global_config) - self.options.parser.add_option('--debug', action ='store_true', - dest='debug', default=None, help='toggle debug output' - ) + def global_option_hook(self): + """ + Pass back an OptParse object, options will be merged into the global + options. + Example: + + options = + """ + #global_options = init_parser() + #global_options.parser.add_option('--debug', action ='store_true', + # dest='debug', default=None, help='toggle debug output' + # ) + #return global_options + class GetConfigCommand(CementCommand): def run(self): if len(self.cli_args) == 2: config_key = self.cli_args[1] - if self.config.has_key(config_key): + if config.has_key(config_key): print('') - print('config[%s] => %s' % (config_key, self.config[config_key])) + print('config[%s] => %s' % (config_key, config[config_key])) print('') else: - for i in self.config: - print("config[%s] => %s" % (i, self.config[i])) + for i in config: + print("config[%s] => %s" % (i, config[i])) def help(self): print('') @@ -67,8 +78,8 @@ class ListPluginsCommand(CementCommand): print "%-18s %-7s %-50s" % ('plugin', 'ver', 'description') print "%-18s %-7s %-50s" % ('-'*18, '-'*7, '-'*50) - for plugin in self.config['plugins']: - plugin_cls = self.config['plugins'][plugin] + for plugin in config['plugins']: + plugin_cls = config['plugins'][plugin] print "%-18s %-7s %-50s" % ( plugin, plugin_cls.version, plugin_cls.description ) diff --git a/plugins/cement-plugins-clibasic/setup.py b/plugins/cement-plugins-clibasic/setup.py index 322504d1..f1bb3dc0 100644 --- a/plugins/cement-plugins-clibasic/setup.py +++ b/plugins/cement-plugins-clibasic/setup.py @@ -23,5 +23,5 @@ setup(name='CementPluginsCLIBasic', test_suite='nose.collector', entry_points=""" """, - namespace_packages=['cement', 'cement.plugins'], + namespace_packages=['cement.plugins'], )