commit
b8a9f6a809
|
@ -11,3 +11,7 @@ targets:
|
|||
- "docs/source/conf.py": "docs/source/myconf.py.jj2"
|
||||
- "docs/source/index.rst": "docs/source/index.rst.jj2"
|
||||
- test.sh: test.sh.jj2
|
||||
- "lml/_version.py": _version.py.jj2
|
||||
- output: CHANGELOG.rst
|
||||
configuration: changelog.yml
|
||||
template: CHANGELOG.rst.jj2
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
Change log
|
||||
===========
|
||||
================================================================================
|
||||
|
||||
0.0.2 - 23.10.2017
|
||||
0.0.3 - 12/06/2018
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
#. pyexcel `#103 <https://github.com/pyexcel/pyexcel/issues/103>`_, include
|
||||
Added
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. `dict` can be a pluggable type in addition to `function`, `class`
|
||||
#. get primary tag of your tag, helping you find out which category of plugins
|
||||
your tag points to
|
||||
|
||||
0.0.2 - 23/10/2017
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Updated
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. `pyexcel#103 <https://github.com/pyexcel/pyexcel/issues/103>`_: include
|
||||
LICENSE in tar ball
|
||||
|
||||
0.0.1 - 30/05/2017
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
first release
|
||||
Added
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. First release
|
||||
|
|
10
README.rst
10
README.rst
|
@ -1,12 +1,13 @@
|
|||
================================================================================
|
||||
lml - Load me later. A lazy loading plugin management system.
|
||||
lml - Load me later. A lazy plugin management system.
|
||||
================================================================================
|
||||
|
||||
.. image:: https://api.travis-ci.org/chfw/lml.svg?branch=master
|
||||
.. image:: https://api.travis-ci.org/chfw/lml.svg
|
||||
:target: http://travis-ci.org/chfw/lml
|
||||
|
||||
.. image:: https://codecov.io/gh/chfw/lml/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/chfw/lml
|
||||
.. image:: https://codecov.io/github/chfw/lml/coverage.png
|
||||
:target: https://codecov.io/github/chfw/lml
|
||||
|
||||
|
||||
.. image:: https://readthedocs.org/projects/lml/badge/?version=latest
|
||||
:target: http://lml.readthedocs.org/en/latest/
|
||||
|
@ -54,4 +55,3 @@ License
|
|||
================================================================================
|
||||
|
||||
New BSD
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
name: lml
|
||||
organisation: chfw
|
||||
releases:
|
||||
- changes:
|
||||
- action: Added
|
||||
details:
|
||||
- "`dict` can be a pluggable type in addition to `function`, `class`"
|
||||
- get primary tag of your tag, helping you find out which category of plugins your tag points to
|
||||
date: 12/06/2018
|
||||
version: 0.0.3
|
||||
- changes:
|
||||
- action: Updated
|
||||
details:
|
||||
- "`pyexcel#103 <https://github.com/pyexcel/pyexcel/issues/103>`_: include LICENSE in tar ball"
|
||||
date: 23/10/2017
|
||||
version: 0.0.2
|
||||
- changes:
|
||||
- action: Added
|
||||
details:
|
||||
- First release
|
||||
date: 30/05/2017
|
||||
version: 0.0.1
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
DESCRIPTION = (
|
||||
'Load me later. A lazy loading plugin management system.' +
|
||||
'Load me later. A loading plugin management system.' +
|
||||
''
|
||||
)
|
||||
extensions = [
|
||||
|
@ -17,9 +17,9 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
|
||||
project = u'lml'
|
||||
copyright = u'2017 Onni Software Ltd.'
|
||||
version = '0.0.2'
|
||||
release = '0.0.2'
|
||||
copyright = u'2017-2018 Onni Software Ltd.'
|
||||
version = '0.0.3'
|
||||
release = '0.0.3'
|
||||
exclude_patterns = []
|
||||
pygments_style = 'sphinx'
|
||||
html_theme = 'default'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
`lml` - Load me later. A lazy loading plugin management system.
|
||||
`lml` - Load me later. A loading plugin management system.
|
||||
================================================================================
|
||||
|
||||
|
||||
|
|
12
lml.yml
12
lml.yml
|
@ -1,13 +1,13 @@
|
|||
name: "lml"
|
||||
full_name: "Load me later. A lazy loading plugin management system."
|
||||
full_name: "Load me later. A lazy plugin management system."
|
||||
organisation: "chfw"
|
||||
author: "C.W."
|
||||
contact: "wangc_2011@hotmail.com"
|
||||
company: "Onni Software Ltd."
|
||||
version: "0.0.2"
|
||||
current_version: "0.0.2"
|
||||
release: "0.0.2"
|
||||
copyright_year: 2017
|
||||
version: "0.0.3"
|
||||
current_version: "0.0.3"
|
||||
release: "0.0.3"
|
||||
copyright_year: 2017-2018
|
||||
license: New BSD
|
||||
dependencies: []
|
||||
description: "Load me later. A lazy loading plugin management system."
|
||||
description: "Load me later. A loading plugin management system."
|
|
@ -4,10 +4,12 @@
|
|||
|
||||
Load me later. A lazy loading plugin management system.
|
||||
|
||||
:copyright: (c) 2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2017-2018 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
import logging
|
||||
from lml._version import __version__ # flake8: noqa
|
||||
from lml._version import __author__ # flake8: noqa
|
||||
|
||||
try:
|
||||
from logging import NullHandler
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
__version__ = '0.0.3'
|
||||
__author__ = 'C.W.'
|
|
@ -6,7 +6,7 @@
|
|||
and pyinstaller. :func:`~lml.loader.scan_plugins` is expected to be
|
||||
called in the main package of yours at an earliest time of convenience.
|
||||
|
||||
:copyright: (c) 2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2017-2018 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
import pkgutil
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
can be overridden to help its matching :class:`~lml.plugin.PluginManager`
|
||||
to look itself up.
|
||||
|
||||
:copyright: (c) 2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2017-2018 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
import logging
|
||||
|
@ -204,6 +204,7 @@ class PluginManager(object):
|
|||
def __init__(self, plugin_type):
|
||||
self.plugin_name = plugin_type
|
||||
self.registry = defaultdict(list)
|
||||
self.tag_groups = dict()
|
||||
self._logger = logging.getLogger(
|
||||
self.__class__.__module__ + '.' + self.__class__.__name__)
|
||||
_register_class(self)
|
||||
|
@ -273,7 +274,7 @@ class PluginManager(object):
|
|||
if __key in self.registry:
|
||||
for plugin_info in self.registry[__key]:
|
||||
cls = self.dynamic_load_library(plugin_info)
|
||||
module_name = _get_me_pypi_package_name(cls.__module__)
|
||||
module_name = _get_me_pypi_package_name(cls)
|
||||
if library and module_name != library:
|
||||
continue
|
||||
else:
|
||||
|
@ -316,10 +317,19 @@ class PluginManager(object):
|
|||
plugin_info:
|
||||
a instance of plugin info
|
||||
"""
|
||||
self._logger.debug("register " + plugin_cls.__name__)
|
||||
for key in plugin_info.tags():
|
||||
self._logger.debug("register %s",
|
||||
_show_me_your_name(plugin_cls))
|
||||
primary_tag = None
|
||||
for index, key in enumerate(plugin_info.tags()):
|
||||
plugin_info.cls = plugin_cls
|
||||
self.registry[key.lower()].append(plugin_info)
|
||||
if index == 0:
|
||||
primary_tag = key.lower()
|
||||
self.tag_groups[key.lower()] = primary_tag
|
||||
|
||||
def get_primary_key(self, key):
|
||||
__key = key.lower()
|
||||
return self.tag_groups.get(__key, None)
|
||||
|
||||
|
||||
def _register_class(cls):
|
||||
|
@ -335,7 +345,7 @@ def _register_class(cls):
|
|||
plugin_info.absolute_import_path)
|
||||
else:
|
||||
log.debug("load cached plugin info: %s",
|
||||
plugin_info.cls.__name__)
|
||||
_show_me_your_name(plugin_info.cls))
|
||||
cls.load_me_later(plugin_info)
|
||||
|
||||
del CACHED_PLUGIN_INFO[cls.plugin_name]
|
||||
|
@ -348,7 +358,8 @@ def _register_a_plugin(plugin_info, plugin_cls):
|
|||
manager.register_a_plugin(plugin_cls, plugin_info)
|
||||
else:
|
||||
# let's cache it and wait the manager to be registered
|
||||
log.debug("caching %s", plugin_cls.__name__)
|
||||
log.debug("caching %s",
|
||||
_show_me_your_name(plugin_cls.__name__))
|
||||
CACHED_PLUGIN_INFO[plugin_info.plugin_type].append(plugin_info)
|
||||
|
||||
|
||||
|
@ -365,6 +376,17 @@ def _load_me_later(plugin_info):
|
|||
CACHED_PLUGIN_INFO[plugin_info.plugin_type].append(plugin_info)
|
||||
|
||||
|
||||
def _get_me_pypi_package_name(module_name):
|
||||
root_module_name = module_name.split('.')[0]
|
||||
return root_module_name.replace('_', '-')
|
||||
def _get_me_pypi_package_name(module):
|
||||
try:
|
||||
module_name = module.__module__
|
||||
root_module_name = module_name.split('.')[0]
|
||||
return root_module_name.replace('_', '-')
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
|
||||
def _show_me_your_name(cls_func_or_data_type):
|
||||
try:
|
||||
return cls_func_or_data_type.__name__
|
||||
except AttributeError:
|
||||
return str(type(cls_func_or_data_type))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
json utils for dump plugin info class
|
||||
|
||||
:copyright: (c) 2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2017-2018 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
import sys
|
||||
|
|
37
setup.py
37
setup.py
|
@ -1,4 +1,6 @@
|
|||
# Template by setupmobans
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Template by pypi-mobans
|
||||
import os
|
||||
import sys
|
||||
import codecs
|
||||
|
@ -9,23 +11,20 @@ PY26 = PY2 and sys.version_info[1] < 7
|
|||
|
||||
NAME = 'lml'
|
||||
AUTHOR = 'C.W.'
|
||||
VERSION = '0.0.2'
|
||||
VERSION = '0.0.3'
|
||||
EMAIL = 'wangc_2011@hotmail.com'
|
||||
LICENSE = 'New BSD'
|
||||
DESCRIPTION = (
|
||||
'Load me later. A lazy loading plugin management system.' +
|
||||
''
|
||||
'Load me later. A loading plugin management system.'
|
||||
)
|
||||
URL = 'https://github.com/chfw/lml'
|
||||
DOWNLOAD_URL = '%s/archive/0.0.2.tar.gz' % URL
|
||||
FILES = ['README.rst', 'CHANGELOG.rst']
|
||||
DOWNLOAD_URL = '%s/archive/0.0.3.tar.gz' % URL
|
||||
FILES = ['README.rst', 'CHANGELOG.rst']
|
||||
KEYWORDS = [
|
||||
'python'
|
||||
]
|
||||
|
||||
CLASSIFIERS = [
|
||||
'Topic :: Office/Business',
|
||||
'Topic :: Utilities',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Programming Language :: Python',
|
||||
'Intended Audience :: Developers',
|
||||
|
@ -39,6 +38,7 @@ CLASSIFIERS = [
|
|||
|
||||
INSTALL_REQUIRES = [
|
||||
]
|
||||
SETUP_COMMANDS = {}
|
||||
|
||||
|
||||
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
|
||||
|
@ -46,11 +46,12 @@ EXTRAS_REQUIRE = {}
|
|||
# You do not need to read beyond this line
|
||||
PUBLISH_COMMAND = '{0} setup.py sdist bdist_wheel upload -r pypi'.format(
|
||||
sys.executable)
|
||||
GS_COMMAND = ('gs lml v0.0.2 ' +
|
||||
"Find 0.0.2 in changelog for more details")
|
||||
GS_COMMAND = ('gs lml v0.0.3 ' +
|
||||
"Find 0.0.3 in changelog for more details")
|
||||
NO_GS_MESSAGE = ('Automatic github release is disabled. ' +
|
||||
'Please install gease to enable it.')
|
||||
UPLOAD_FAILED_MSG = ('Upload failed. please run "%s" yourself.')
|
||||
UPLOAD_FAILED_MSG = (
|
||||
'Upload failed. please run "%s" yourself.' % PUBLISH_COMMAND)
|
||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
|
@ -75,6 +76,8 @@ class PublishCommand(Command):
|
|||
try:
|
||||
self.status('Removing previous builds...')
|
||||
rmtree(os.path.join(HERE, 'dist'))
|
||||
rmtree(os.path.join(HERE, 'build'))
|
||||
rmtree(os.path.join(HERE, 'lml.egg-info'))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
@ -91,6 +94,11 @@ class PublishCommand(Command):
|
|||
sys.exit()
|
||||
|
||||
|
||||
SETUP_COMMANDS.update({
|
||||
'publish': PublishCommand
|
||||
})
|
||||
|
||||
|
||||
def has_gease():
|
||||
"""
|
||||
test if github release command is installed
|
||||
|
@ -115,7 +123,8 @@ def read_files(*files):
|
|||
|
||||
def read(afile):
|
||||
"""Read a file into setup"""
|
||||
with codecs.open(afile, 'r', 'utf-8') as opened_file:
|
||||
the_relative_file = os.path.join(HERE, afile)
|
||||
with codecs.open(the_relative_file, 'r', 'utf-8') as opened_file:
|
||||
content = filter_out_test_code(opened_file)
|
||||
content = "".join(list(content))
|
||||
return content
|
||||
|
@ -164,7 +173,5 @@ if __name__ == '__main__':
|
|||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
classifiers=CLASSIFIERS,
|
||||
cmdclass={
|
||||
'publish': PublishCommand,
|
||||
}
|
||||
cmdclass=SETUP_COMMANDS
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from mock import patch
|
||||
from lml.plugin import PluginManager, PLUG_IN_MANAGERS
|
||||
from lml.plugin import PluginInfo
|
||||
from lml.plugin import PluginInfo, _show_me_your_name
|
||||
from lml.plugin import CACHED_PLUGIN_INFO
|
||||
from nose.tools import eq_, raises
|
||||
|
||||
|
@ -140,5 +140,38 @@ def test_register_a_plugin_function_2():
|
|||
assert non_existent_plugin in CACHED_PLUGIN_INFO
|
||||
|
||||
|
||||
def test_primary_key():
|
||||
manager = PluginManager("test plugin2")
|
||||
|
||||
@PluginInfo('test plugin2', tags=['primary key', 'key 1', 'key 2'])
|
||||
class MyPlugin(object):
|
||||
pass
|
||||
|
||||
pk = manager.get_primary_key('key 1')
|
||||
eq_(pk, 'primary key')
|
||||
|
||||
|
||||
def test_dict_as_plugin_payload():
|
||||
manager = PluginManager("test plugin3")
|
||||
|
||||
plugin = PluginInfo('test plugin3', tags=['primary key', 'key 1', 'key 2'])
|
||||
plugin(dict(B=1))
|
||||
|
||||
instance = manager.load_me_now('key 1')
|
||||
eq_(instance, dict(B=1))
|
||||
|
||||
|
||||
def test_show_me_your_name():
|
||||
|
||||
class Test(object):
|
||||
pass
|
||||
|
||||
name = _show_me_your_name(Test)
|
||||
eq_(name, 'Test')
|
||||
|
||||
name2 = _show_me_your_name(dict(A=1))
|
||||
assert 'dict' in name2
|
||||
|
||||
|
||||
def make_me_a_plugin_info(plugin_name):
|
||||
return PluginInfo(plugin_name, 'abs_path', custom='property')
|
||||
|
|
Loading…
Reference in New Issue