mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 04:39:26 +01:00
Fixes and tests to supybot-plugin-create; modernize the plugin template (#1340)
* supybot-plugin-create: compactify import statements in the template * supybot-plugin-create: prefer importlib over imp on Python >= 3.4 The imp module is deprecated as of Python 3.4[1], with importlib being the successor. However, importlib is only available in Python 2.7+ and 3.1+, so we should still use a fallback. [1]: https://docs.python.org/3.6/library/imp.html * test: add test cases for supybot-plugin-create * -plugin-create: fix errors when only a subset of args are given * -plugin-create: rename --real-name to --author/-a These days, working under a pseudonym or alias is not unheard of, so putting emphasis on real names feels somewhat out of place. * -plugin-create: add -d as an alias to --desc for consistency
This commit is contained in:
parent
72c4801bb9
commit
11d4015f71
@ -92,11 +92,8 @@ license = license.lstrip()
|
|||||||
pluginTemplate = '''
|
pluginTemplate = '''
|
||||||
%s
|
%s
|
||||||
|
|
||||||
import supybot.utils as utils
|
from supybot import utils, plugins, ircutils, callbacks
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
import supybot.plugins as plugins
|
|
||||||
import supybot.ircutils as ircutils
|
|
||||||
import supybot.callbacks as callbacks
|
|
||||||
try:
|
try:
|
||||||
from supybot.i18n import PluginInternationalization
|
from supybot.i18n import PluginInternationalization
|
||||||
_ = PluginInternationalization('%s')
|
_ = PluginInternationalization('%s')
|
||||||
@ -120,8 +117,7 @@ Class = %s
|
|||||||
configTemplate = '''
|
configTemplate = '''
|
||||||
%s
|
%s
|
||||||
|
|
||||||
import supybot.conf as conf
|
from supybot import conf, registry
|
||||||
import supybot.registry as registry
|
|
||||||
try:
|
try:
|
||||||
from supybot.i18n import PluginInternationalization
|
from supybot.i18n import PluginInternationalization
|
||||||
_ = PluginInternationalization('%s')
|
_ = PluginInternationalization('%s')
|
||||||
@ -157,8 +153,9 @@ __init__Template = '''
|
|||||||
%s: %s
|
%s: %s
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
import supybot
|
import supybot
|
||||||
import supybot.world as world
|
from supybot import world
|
||||||
|
|
||||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||||
# in here if you're keeping the plugin in CVS or some similar system.
|
# in here if you're keeping the plugin in CVS or some similar system.
|
||||||
@ -176,7 +173,10 @@ __url__ = ''
|
|||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from . import plugin
|
from . import plugin
|
||||||
from imp import reload
|
if sys.version_info >= (3, 4):
|
||||||
|
from importlib import reload
|
||||||
|
else:
|
||||||
|
from imp import reload
|
||||||
# In case we're being reloaded.
|
# In case we're being reloaded.
|
||||||
reload(config)
|
reload(config)
|
||||||
reload(plugin)
|
reload(plugin)
|
||||||
@ -219,20 +219,15 @@ def main():
|
|||||||
help='sets the name for the plugin.')
|
help='sets the name for the plugin.')
|
||||||
parser.add_option('-t', '--thread', action='store_true', dest='threaded',
|
parser.add_option('-t', '--thread', action='store_true', dest='threaded',
|
||||||
help='makes the plugin threaded.')
|
help='makes the plugin threaded.')
|
||||||
parser.add_option('', '--real-name', action='store', dest='realName',
|
parser.add_option('-a', '--author', '--real-name', action='store',
|
||||||
help='Determines what real name the copyright is '
|
dest='realName', help='Determines who the copyright is '
|
||||||
'assigned to.')
|
'assigned to.')
|
||||||
parser.add_option('', '--desc', action='store', dest='desc',
|
parser.add_option('-d', '--desc', action='store', dest='desc',
|
||||||
help='Short description of plugin.')
|
help='Short description of plugin.')
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
if options.name:
|
if options.name:
|
||||||
name = options.name
|
name = options.name
|
||||||
if options.threaded:
|
threaded = options.threaded
|
||||||
threaded = True
|
|
||||||
else:
|
|
||||||
threaded = False
|
|
||||||
if options.realName:
|
|
||||||
realName = options.realName
|
|
||||||
else:
|
else:
|
||||||
name = something('What should the name of the plugin be?')
|
name = something('What should the name of the plugin be?')
|
||||||
if name.endswith('.py'):
|
if name.endswith('.py'):
|
||||||
@ -255,8 +250,11 @@ def main():
|
|||||||
print()
|
print()
|
||||||
threaded = yn('Does your plugin need to be threaded?')
|
threaded = yn('Does your plugin need to be threaded?')
|
||||||
|
|
||||||
|
if options.realName:
|
||||||
|
realName = options.realName
|
||||||
|
else:
|
||||||
realName = something(textwrap.dedent("""
|
realName = something(textwrap.dedent("""
|
||||||
What is your real name, so I can fill in the copyright and license
|
What is your name, so I can fill in the copyright and license
|
||||||
appropriately?
|
appropriately?
|
||||||
""").strip())
|
""").strip())
|
||||||
|
|
||||||
|
106
test/test_plugin_create.py
Normal file
106
test/test_plugin_create.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2018, James Lu <james@overdrivenetworks.com>
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
###
|
||||||
|
|
||||||
|
import supybot
|
||||||
|
from supybot.test import *
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import unittest
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import compileall
|
||||||
|
|
||||||
|
TEST_PLUGIN_NAME = "TestPlugin"
|
||||||
|
|
||||||
|
class PluginCreateTestCase(SupyTestCase):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _communicate(proc, text):
|
||||||
|
outs, errs = proc.communicate(input=text)
|
||||||
|
|
||||||
|
supybot.log.info("testPluginCreate: supybot-plugin-create outs:")
|
||||||
|
for line in outs.splitlines():
|
||||||
|
supybot.log.info(" %s", line.decode())
|
||||||
|
supybot.log.info("testPluginCreate: supybot-plugin-create errs:")
|
||||||
|
for line in errs.splitlines():
|
||||||
|
supybot.log.info(" %s", line.decode())
|
||||||
|
|
||||||
|
def _makeplugin(self):
|
||||||
|
proc = subprocess.Popen(['supybot-plugin-create'], stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
# In order: plugin name, threaded?, author, use Supybot license?, description
|
||||||
|
cmdinput = TEST_PLUGIN_NAME.encode() + b"""
|
||||||
|
n
|
||||||
|
Test Case Runner
|
||||||
|
y
|
||||||
|
Dummy test plugin
|
||||||
|
"""
|
||||||
|
self._communicate(proc, cmdinput)
|
||||||
|
|
||||||
|
def testPluginCreate(self):
|
||||||
|
tmpdir = conf.supybot.directories.data.tmp()
|
||||||
|
curdir = os.getcwd()
|
||||||
|
try:
|
||||||
|
os.chdir(tmpdir)
|
||||||
|
if TEST_PLUGIN_NAME in os.listdir('.'):
|
||||||
|
supybot.log.info("testPluginCreate: Removing old TestPlugin directory")
|
||||||
|
shutil.rmtree(TEST_PLUGIN_NAME)
|
||||||
|
|
||||||
|
self._makeplugin()
|
||||||
|
|
||||||
|
self.assertIn(TEST_PLUGIN_NAME, os.listdir('.'))
|
||||||
|
|
||||||
|
# Make sure that out generated plugin is valid
|
||||||
|
compileall.compile_dir(TEST_PLUGIN_NAME)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
os.chdir(curdir)
|
||||||
|
|
||||||
|
class PluginCreateNoninteractiveTestCase(PluginCreateTestCase):
|
||||||
|
def _makeplugin(self):
|
||||||
|
with open(os.devnull, 'w') as devnull: # Compat with Python < 3.3
|
||||||
|
retcode = subprocess.call(['supybot-plugin-create', '-n', TEST_PLUGIN_NAME,
|
||||||
|
'--author=skynet', '--desc=Some description'],
|
||||||
|
stdin=devnull)
|
||||||
|
self.assertFalse(retcode) # Check that the return code is 0
|
||||||
|
|
||||||
|
class PluginCreatePartialArgsTestCase(PluginCreateTestCase):
|
||||||
|
def _makeplugin(self):
|
||||||
|
# We passed in a subset of args, so the script should only prompt for the
|
||||||
|
# ones not given
|
||||||
|
proc = subprocess.Popen(['supybot-plugin-create', '-n', TEST_PLUGIN_NAME],
|
||||||
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
# In order: threaded?, author, use Supybot license?, description
|
||||||
|
cmdinput = TEST_PLUGIN_NAME.encode() + b"""
|
||||||
|
Test Case Runner
|
||||||
|
y
|
||||||
|
Dummy test plugin
|
||||||
|
"""
|
||||||
|
self._communicate(proc, cmdinput)
|
Loading…
Reference in New Issue
Block a user