This commit is contained in:
Iliyan Angelov
2025-09-19 11:58:53 +03:00
parent 306b20e24a
commit 6b247e5b9f
11423 changed files with 1500615 additions and 778 deletions

View File

@@ -0,0 +1,61 @@
"""
An extension module for click to enable registering CLI commands via setuptools
entry-points.
from pkg_resources import iter_entry_points
import click
from click_plugins import with_plugins
@with_plugins(iter_entry_points('entry_point.name'))
@click.group()
def cli():
'''Commandline interface for something.'''
@cli.command()
@click.argument('arg')
def subcommand(arg):
'''A subcommand for something else'''
"""
from click_plugins.core import with_plugins
__version__ = '1.1.1.2'
__author__ = 'Kevin Wurster, Sean Gillies'
__email__ = 'wursterk@gmail.com, sean.gillies@gmail.com'
__source__ = 'https://github.com/click-contrib/click-plugins'
__license__ = '''
New BSD License
Copyright (c) 2015-2025, Kevin D. Wurster, Sean C. Gillies
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 click-plugins nor the names of its contributors may not be used to
endorse or promote products derived from this software without specific prior
written permission.
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 HOLDER 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.
'''

View File

@@ -0,0 +1,92 @@
"""
Core components for click_plugins
"""
import click
import os
import sys
import traceback
def with_plugins(plugins):
"""
A decorator to register external CLI commands to an instance of
`click.Group()`.
Parameters
----------
plugins : iter
An iterable producing one `pkg_resources.EntryPoint()` per iteration.
attrs : **kwargs, optional
Additional keyword arguments for instantiating `click.Group()`.
Returns
-------
click.Group()
"""
def decorator(group):
if not isinstance(group, click.Group):
raise TypeError("Plugins can only be attached to an instance of click.Group()")
for entry_point in plugins or ():
try:
group.add_command(entry_point.load())
except Exception:
# Catch this so a busted plugin doesn't take down the CLI.
# Handled by registering a dummy command that does nothing
# other than explain the error.
group.add_command(BrokenCommand(entry_point.name))
return group
return decorator
class BrokenCommand(click.Command):
"""
Rather than completely crash the CLI when a broken plugin is loaded, this
class provides a modified help message informing the user that the plugin is
broken and they should contact the owner. If the user executes the plugin
or specifies `--help` a traceback is reported showing the exception the
plugin loader encountered.
"""
def __init__(self, name):
"""
Define the special help messages after instantiating a `click.Command()`.
"""
click.Command.__init__(self, name)
util_name = os.path.basename(sys.argv and sys.argv[0] or __file__)
if os.environ.get('CLICK_PLUGINS_HONESTLY'): # pragma no cover
icon = u'\U0001F4A9'
else:
icon = u'\u2020'
self.help = (
"\nWarning: entry point could not be loaded. Contact "
"its author for help.\n\n\b\n"
+ traceback.format_exc())
self.short_help = (
icon + " Warning: could not load plugin. See `%s %s --help`."
% (util_name, self.name))
def invoke(self, ctx):
"""
Print the traceback instead of doing nothing.
"""
click.echo(self.help, color=ctx.color)
ctx.exit(1)
def parse_args(self, ctx, args):
return args