Changed ABI to API

This commit is contained in:
BJ Dierkes 2010-01-14 23:44:02 -06:00
parent 3f289d9a0b
commit b48d317777
30 changed files with 66 additions and 414 deletions

View File

@ -122,7 +122,7 @@ commit f2b0844434e35b6d87dd47154c7b6707521072fd
Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Date: Tue Jan 5 19:17:32 2010 -0600
Adding better install_requires to templates in lack of having an abi compat feature in setuptools
Adding better install_requires to templates in lack of having an api compat feature in setuptools
commit d4768967fecc635a5464018247f7570cd132895c
Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
@ -140,13 +140,13 @@ commit c1b005b63df8c5955589582ecf37783ece47c6ee
Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Date: Wed Dec 30 23:22:23 2009 -0600
added the ability to hide namespaces, even if all commands aren't hidden
added the apility to hide namespaces, even if all commands aren't hidden
commit 328ad7cb775d24630df8c866ff6e66e960860326
Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Date: Wed Dec 30 23:22:16 2009 -0600
added the ability to hide namespaces, even if all commands aren't hidden
added the apility to hide namespaces, even if all commands aren't hidden
commit c604ac4046bdbbb33c012c5be6367fc4d926d8a0
Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
@ -315,7 +315,7 @@ Author: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Date: Mon Dec 7 03:56:29 2009 -0600
Reworked plugin framework.
Added ABI checking
Added API checking
Need to finish porting the other example plugins to new plugin format.
commit 0461dad1109d3f0c66b29dcf68d0ae69f14948d2

View File

@ -26,7 +26,7 @@ summary of the changes made to Cement CLI Application Framework for Python.
to Licensee on an "AS IS" basis. BJ Dierkes MAKES NO REPRESENTATIONS OR
WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BJ
Dierkes MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF
MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
MERCHANTAPILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
CEMENT CLI APPLICATION FOR PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. BJ Dierkes SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF CEMENT

View File

@ -43,7 +43,7 @@ def lay_cement(default_app_config=None, version_banner=None):
namespace = CementNamespace(
label = 'global',
version = get_distribution(default_app_config['app_egg_name']).version,
required_abi = CEMENT_ABI,
required_api = CEMENT_API,
config = get_default_config(),
version_banner = vb,
)

View File

@ -4,7 +4,7 @@ from configobj import ConfigObj, Section
from cement.core.exc import CementConfigError
CEMENT_ABI = "20091211"
CEMENT_API = "20091211"
def get_default_config():
dcf = {}
@ -22,16 +22,16 @@ hooks = {}
namespaces = {}
def get_abi_version():
return CEMENT_ABI
def get_api_version():
return CEMENT_API
def ensure_abi_compat(module_name, required_abi):
if int(required_abi) == int(CEMENT_ABI):
def ensure_api_compat(module_name, required_api):
if int(required_api) == int(CEMENT_API):
pass
else:
raise CementRuntimeError, \
"%s requires abi version %s which differs from cement(abi) %s." % \
(module_name, required_abi, CEMENT_ABI)
"%s requires api version %s which differs from cement(api) %s." % \
(module_name, required_api, CEMENT_API)
def set_config_opts_per_file(namespace, section, config_file):
"""

View File

@ -3,10 +3,10 @@ from cement import namespaces
from cement.core.opt import init_parser
class CementNamespace(object):
def __init__(self, label, version, required_abi, **kw):
def __init__(self, label, version, required_api, **kw):
self.label = label
self.version = version
self.required_abi = required_abi
self.required_api = required_api
self.description = kw.get('description', '')
self.commands = kw.get('commands', {})
self.config = kw.get('config', {'config_source': ['defaults']})
@ -29,4 +29,4 @@ def define_namespace(namespace, namespace_obj):
"""
if namespaces.has_key(namespace):
raise CementRuntimeError, "Namespace '%s' already defined!" % namespace
namespaces[namespace] = namespace_obj
namespaces[namespace] = namespace_obj

View File

@ -7,7 +7,7 @@ from cement.core.log import get_logger
from cement.core.hook import run_hooks
from cement.core.configuration import set_config_opts_per_file
from cement.core.namespace import CementNamespace, define_namespace
from cement.core.configuration import ensure_abi_compat
from cement.core.configuration import ensure_api_compat
log = get_logger(__name__)
@ -26,7 +26,7 @@ def register_plugin(**kwargs):
def decorate(func):
nms = func.__module__.split('.')
ensure_abi_compat(func.__name__, func().required_abi)
ensure_api_compat(func.__name__, func().required_api)
if kwargs.get('name', None):
plugin_name = kwargs['name']
elif nms[-1] == 'pluginmain':
@ -160,4 +160,4 @@ def load_all_plugins():
pass
else:
namespaces[namespace].options.add_option(opt)

View File

@ -43,7 +43,7 @@ from paste.script import create_distro
beginning_letter = re.compile(r"^[^a-z]*")
valid_only = re.compile(r"[^a-z0-9_]")
from cement.core.configuration import CEMENT_ABI
from cement.core.configuration import CEMENT_API
CEMENT_VERSION = pkg_resources.get_distribution('cement').version
@ -127,7 +127,7 @@ Example usage::
for template in self.templates.split():
cmd_args.append("--template=%s" % template)
cmd_args.append(self.name)
cmd_args.append("cement_abi=%s" % CEMENT_ABI)
cmd_args.append("cement_api=%s" % CEMENT_API)
cmd_args.append("cement_version=%s" % CEMENT_VERSION)
cmd_args.append("cement_next_version=%s" % CEMENT_NEXT_VERSION)
command.run(cmd_args)
@ -229,7 +229,7 @@ Example usage::
cmd_args.append(self.name)
cmd_args.append("project=%s" % self.project)
cmd_args.append("plugin=%s" % self.plugin)
cmd_args.append("cement_abi=%s" % CEMENT_ABI)
cmd_args.append("cement_api=%s" % CEMENT_API)
cmd_args.append("cement_version=%s" % CEMENT_VERSION)
cmd_args.append("cement_next_version=%s" % CEMENT_NEXT_VERSION)
@ -340,4 +340,4 @@ Example usage::
for base, path, files in os.walk("./"):
for file in files:
if file == "empty":
os.remove(os.path.join(base, file))
os.remove(os.path.join(base, file))

View File

@ -6,7 +6,7 @@ from tempita import paste_script_template_renderer
import pkg_resources
from pkg_resources import get_distribution
from cement.core.configuration import CEMENT_ABI
from cement.core.configuration import CEMENT_API
class CementAppTemplate(templates.Template):
"""
@ -17,7 +17,7 @@ class CementAppTemplate(templates.Template):
summary = 'Cement Standard Template'
egg_plugins = ['PasteScript', 'Cement']
vars = [
templates.var("cement_abi", "Cement ABI Version", default=CEMENT_ABI),
templates.var("cement_api", "Cement API Version", default=CEMENT_API),
templates.var("cement_version", "Cement version", default=None),
templates.var("cement_next_version", "Cement Next Version", default=None)
]
@ -37,7 +37,7 @@ class CementPluginTemplate(templates.Template):
vars = [
templates.var("plugin", "cement plugin name", default=None),
templates.var("project", "Parent application this plugin is for", default=None),
templates.var("cement_abi", "Cement ABI Version", default=CEMENT_ABI),
templates.var("cement_api", "Cement API Version", default=CEMENT_API),
templates.var("cement_version", "Cement version", default=None),
templates.var("cement_next_version", "Cement Next Version", default=None)
]
@ -63,4 +63,4 @@ class CementHelperTemplate(templates.Template):
def pre(self, command, output_dir, vars):
"""Called before template is applied."""
pass
pass

View File

@ -2,7 +2,7 @@
This is the application's core code. Unless you know the "ins-and-outs" of
The Cement CLI Application Framework, you probably should not modify this file.
Keeping all customizations outside of core.py means that you can easily
upgrade to a newer version of the CEMENT_ABI by simply replacing this
upgrade to a newer version of the CEMENT_API by simply replacing this
file.
"""
@ -11,15 +11,15 @@ import sys
from cement.core.exc import *
from cement.core.log import get_logger
from cement.core.app_setup import lay_cement
from cement.core.configuration import ensure_abi_compat
from cement.core.configuration import ensure_api_compat
from cement.core.command import run_command
from {{project}} import default_config
REQUIRED_CEMENT_ABI = '{{cement_abi}}'
REQUIRED_CEMENT_API = '{{cement_api}}'
def main():
ensure_abi_compat(__name__, REQUIRED_CEMENT_ABI)
ensure_api_compat(__name__, REQUIRED_CEMENT_API)
# Warning: You shouldn't modify below this point unless you know what
# you're doing.

View File

@ -12,7 +12,7 @@ from cement.core.plugin import CementPlugin, register_plugin
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '{{cement_abi}}'
REQUIRED_CEMENT_API = '{{cement_api}}'
# Optional: Allows you to customize the output of --version
BANNER = """
@ -26,7 +26,7 @@ class {{package}}Plugin(CementPlugin):
label = '{{package}}',
version = VERSION,
description = 'Core plugin for {{package}}',
required_abi = REQUIRED_CEMENT_ABI,
required_api = REQUIRED_CEMENT_API,
version_banner = BANNER,
)

View File

@ -18,7 +18,7 @@ from cement.core.plugin import CementPlugin, register_plugin
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '{{cement_abi}}'
REQUIRED_CEMENT_API = '{{cement_api}}'
# Optional: Allows you to customize the output of --version
BANNER = """
@ -33,7 +33,7 @@ class ExamplePlugin(CementPlugin):
label = 'example',
version = VERSION,
description = 'Example plugin for {{package}}',
required_abi = REQUIRED_CEMENT_ABI,
required_api = REQUIRED_CEMENT_API,
version_banner=BANNER,
)
@ -164,4 +164,4 @@ class ex3Command(CementCommand):
print "This is Example3Command.run()"
def help(self):
print "This is Example3Command.help()"
print "This is Example3Command.help()"

View File

@ -14,10 +14,10 @@ from cement.core.plugin import CementPlugin, register_plugin
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '{{cement_abi}}'
REQUIRED_CEMENT_API = '{{cement_api}}'
BANNER = """
{{plugin}} v%s (abi:%s)
""" % (VERSION, REQUIRED_CEMENT_ABI)
{{plugin}} v%s (api:%s)
""" % (VERSION, REQUIRED_CEMENT_API)
@register_plugin()
class {{plugin}}Plugin(CementPlugin):
@ -26,7 +26,7 @@ class {{plugin}}Plugin(CementPlugin):
label = '{{plugin}}',
version = VERSION,
description = '{{plugin}} plugin for {{project}}',
required_abi = REQUIRED_CEMENT_ABI,
required_api = REQUIRED_CEMENT_API,
version_banner=BANNER
)

View File

@ -7,7 +7,7 @@
# list of plugin names to load (comma separated). These can be plugins
# from within your application, or a core Cement plugin that is installed.
enabled_plugins = helloworld_core, apples,
enabled_plugins = helloworld_core,
# these should probably be changed for production installations if you
# follow the FHS (and you should).
@ -26,6 +26,9 @@ plugin_dir = ./var/lib/helloworld/plugins.d
# toggle debug output... can be true, false, yes, no, 1, 0
debug = false
# toggle the log level... can be info, warn, error, fatal, debug
log_level = warn
# add any config options you'd like here
#
# myoption = this is my option
# myoption = this is my option

View File

@ -2,15 +2,15 @@
# This is an example of a cement plugin configuration file. Once parsed, the
# values from here will be accessible from:
#
# namespaces['example'].config['param'] = value
# namespaces[{{plugin}}].config['param'] = value
#
#
# Some options are built into cement (suchas merge_global_options) and
# Some options are built into cement (such as merge_global_options) and
# some are not.
#
# Whether or not to merge global options
merge_global_options = false
merge_global_options = true
debug = false
param1 = value1

View File

@ -1,6 +1,10 @@
[helloworld_core]
# helloworld_core plugin configurations
#
# This is an example of a cement plugin configuration file. Once parsed, the
# values from here will be accessible from:
#
# namespaces[helloworld].config['param'] = value
#
# Whether or not to merge global options
merge_global_options = false
merge_global_options = true

View File

@ -2,7 +2,7 @@
This is the application's core code. Unless you know the "ins-and-outs" of
The Cement CLI Application Framework, you probably should not modify this file.
Keeping all customizations outside of core.py means that you can easily
upgrade to a newer version of the CEMENT_ABI by simply replacing this
upgrade to a newer version of the CEMENT_API by simply replacing this
file.
"""
@ -11,15 +11,15 @@ import sys
from cement.core.exc import *
from cement.core.log import get_logger
from cement.core.app_setup import lay_cement
from cement.core.configuration import ensure_abi_compat
from cement.core.configuration import ensure_api_compat
from cement.core.command import run_command
from helloworld import default_config
REQUIRED_CEMENT_ABI = '20091211'
REQUIRED_CEMENT_API = '20091211'
def main():
ensure_abi_compat(__name__, REQUIRED_CEMENT_ABI)
ensure_api_compat(__name__, REQUIRED_CEMENT_API)
# Warning: You shouldn't modify below this point unless you know what
# you're doing.

View File

@ -1,167 +0,0 @@
"""This is an example plugin for helloworld."""
"""
This is a simple plugin to add some basic functionality.
"""
import sys, os
from pkg_resources import get_distribution
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.command import CementCommand, register_command
from cement.core.plugin import CementPlugin, register_plugin
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '20091211'
# Optional: Allows you to customize the output of --version
BANNER = """
helloworld.plugins.example v%s
""" % (VERSION)
@register_plugin()
class ExamplePlugin(CementPlugin):
def __init__(self):
CementPlugin.__init__(self,
label = 'example',
version = VERSION,
description = 'Example plugin for helloworld',
required_abi = REQUIRED_CEMENT_ABI,
version_banner=BANNER,
)
# 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'
)
@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 global options.
Global options can also be used as local options by setting the config
option 'merge_global_options = true' in the plugin config.
"""
global_options = init_parser()
global_options.add_option('-G', '--global-option', action ='store_true',
dest='global_option', default=None, help='Example Global option'
)
# return the namespace and the global options to add.
return ('global', global_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 global 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 global
option is passed. Notice that we set a global option of -G in our
global_options_hook above. Here we can access that value from the
global namespace configuration.
"""
cnf = namespaces['global'].config
if cnf.has_key('global_option'):
print "global_option => %s", cnf['global_option']
# then do something with it
@register_command(name='ex1', namespace='example')
class ex1Command(CementCommand):
"""
This is how to add a local/plugin subcommand because it will be
under the 'example' namespace. You would access this subcommand as:
$ myapp example ex1
"""
def run(self):
print "This is Example1Command.run()"
def help(self):
print "This is Example1Command.help()"
@register_command(name='ex2', namespace='global')
class ex2Command(CementCommand):
def run(self):
"""
This is an example global command. See --help. When commands are
called, they are passed the cli options and args passed after it.
These are then forwarded onto the command class where they can be
called as self.cli_args, and self.cli_opts.
Notice that you can specify the namespace via the decorator parameters.
If a plugin has any non-global commands they are grouped under a
single command to the base cli application. For example, you will
see global commands and namespaces* when you execute:
myapp --help
For example, if 'myplugin' has local commands, you will
see 'myplugin*' show up in the global commands list, and then the
plugin subcommands will be seen under:
myapp myplugin --help
This is done to give different options in how your application works.
"""
print "This is Example2Command.run()."
# you can then see if options where passed:
if self.cli_opts.global_option:
print "You passed --global-options!"
def help(self):
"""
All commands have a hidden -help option as well. Here you can
provide examples or other helpful information.
"""
print "This is Example2Command.help()"
@register_command(name='ex3', namespace='helloworld_core')
class ex3Command(CementCommand):
"""
This is how to add a local/plugin subcommand to another namespace. It
is possible to use this in conjunction with the options_hook() to add
additional functionality to a completely other namespace:
$ myapp helloworld ex3
"""
def run(self):
print "This is Example3Command.run()"
def help(self):
print "This is Example3Command.help()"

View File

@ -1,34 +0,0 @@
"""This is the core plugin for helloworld."""
import sys, os
from pkg_resources import get_distribution
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.command import CementCommand, register_command
from cement.core.plugin import CementPlugin, register_plugin
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '20091211'
# Optional: Allows you to customize the output of --version
BANNER = """
helloworld.plugins.helloworld_core v%s
""" % (VERSION)
@register_plugin()
class helloworldPlugin(CementPlugin):
def __init__(self):
CementPlugin.__init__(self,
label = 'helloworld',
version = VERSION,
description = 'Core plugin for helloworld',
required_abi = REQUIRED_CEMENT_ABI,
version_banner=BANNER,
)

View File

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

View File

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

View File

@ -1,16 +0,0 @@
"""
myhelper for the helloworld application.
"""
import os
from cement.core.log import get_logger
log = get_logger(__name__)
def myhelper_helper_method():
# fill in helper code. Import as:
#
# from helloworld.helpers.myhelper import myhelper_helper_method()
#
pass

View File

@ -1,28 +0,0 @@
from setuptools import setup, find_packages
import sys, os
# You probably want to change the name, this is a healthy default for paster
setup(name='helloworld_helpers_myhelper',
version='0.1',
description='',
classifiers=[],
keywords='',
author='',
author_email='',
url='',
license='',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
"ConfigObj",
"cement == 0.4",
],
setup_requires=[
"PasteScript >= 1.7"
],
test_suite='nose.collector',
entry_points="""
""",
namespace_packages=['helloworld', 'helloworld.helpers'],
)

View File

@ -1,15 +0,0 @@
[myplugin]
# This is a cement plugin configuration file. Once parsed, the
# values from here will be accessible from:
#
# config['plugins']['myplugin']['param'] = value
#
param1 = value1
param2 = value two
# true/false equate to True/False in python
param3 = true
# equates to ['my', 'list', 'of', 'values']
param5 = my, list, of, values,

View File

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

View File

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

View File

@ -1,63 +0,0 @@
"""
myplugin for the helloworld application.
"""
import os
from cement.core.log import get_logger
from cement.core.app_setup import CementCommand, CementPlugin, register_hook, \
register_command, register_plugin
from cement.core.options import init_parser
log = get_logger(__name__)
VERSION = '0.1'
REQUIRED_CEMENT_ABI = '20091211'
BANNER = """
myplugin v%s (abi:%s)
""" % (VERSION, REQUIRED_CEMENT_ABI)
@register_plugin()
class mypluginPlugin(CementPlugin):
def __init__(self):
CementPlugin.__init__(self,
label = 'myplugin',
version = VERSION,
description = 'myplugin Plugin for Applications using Cement Framework',
required_abi = REQUIRED_CEMENT_ABI,
version_banner=BANNER
)
@register_hook()
def global_options_hook(*args, **kwargs):
"""
Register global options.
"""
global_options = init_parser()
global_options.add_option('--myplugin-global-option', action ='store_true',
dest='myplugin_global_option', default=None, help='example global option'
)
return global_options
@register_command(name='myplugin-command')
class mypluginCommand(CementCommand):
"""
Register global commands.
"""
def run(self):
print "myplugin global command run() method."
def help(self):
print "myplugin global command help() method."
@register_command(name='myplugin_command', namespace='myplugin')
class mypluginLocalCommand(CementCommand):
"""
Register local commands.
"""
def run(self):
print "myplugin local command run() method."
def help(self):
print "myplugin local command help() method."

View File

@ -1,30 +0,0 @@
from setuptools import setup, find_packages
import sys, os
# You probably want to change the name, this is a healthy default for paster
setup(name='helloworld_plugins_myplugin',
version='0.1',
description='',
classifiers=[],
keywords='',
author='',
author_email='',
url='',
license='',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
"ConfigObj",
"cement == 0.4",
"helloworld",
],
setup_requires=[
"PasteScript >= 1.7",
"ConfigObj",
],
test_suite='nose.collector',
entry_points="""
""",
namespace_packages=['helloworld', 'helloworld.plugins'],
)

View File

@ -15,7 +15,9 @@ setup(name='helloworld',
zip_safe=False,
install_requires=[
"ConfigObj",
"cement == 0.4",
"Cement >=0.4.5, <0.5",
# Uncomment if you want to use shared cement plugins.
#"CementPlugins",
],
setup_requires=[
"PasteScript >= 1.7"

View File

@ -20,7 +20,7 @@ class ExamplePlugin(CementPlugin):
def __init__(self, global_config):
CementPlugin.__init__(self, global_config)
self.version = '0.1'
self.required_abi = '20091207'
self.required_api = '20091207'
self.description = "Example Plugin for a Cement Application."
self.config = {
'config_source': ['defaults']
@ -108,4 +108,4 @@ class ExampleCommand(CementCommand):
for any module command by adding it like this.
"""
print 'help content for cement.plugins.example.ExampleCommand().run()'

View File

@ -84,10 +84,10 @@ setup(name='Cement',
"ConfigObj",
"PasteScript >= 1.7",
],
# FIX ME: This installs, but requiring CementABI == 0.4.20091211 doesn't
# FIX ME: This installs, but requiring CementAPI == 0.4.20091211 doesn't
# work.
#provides=[
# "CementABI (0.4.20091211)",
# "CementAPI (0.4.20091211)",
# ],
entry_points="""
[paste.global_paster_command]