diff --git a/docs/contributing.rst b/docs/contributing.rst index 8a27d565e..36dff01b9 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -157,7 +157,7 @@ Plugin-architecture Let's Encrypt has a plugin architecture to facilitate support for different webservers, other TLS servers, and operating systems. The interfaces available for plugins to implement are defined in -`interfaces.py`_. +`interfaces.py`_ and `plugins/common.py`_. The most common kind of plugin is a "Configurator", which is likely to implement the `~letsencrypt.interfaces.IAuthenticator` and @@ -168,6 +168,7 @@ There are also `~letsencrypt.interfaces.IDisplay` plugins, which implement bindings to alternative UI libraries. .. _interfaces.py: https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/interfaces.py +.. _plugins/common.py: https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/plugins/common.py#L34 Authenticators diff --git a/letsencrypt/plugins/common.py b/letsencrypt/plugins/common.py index f18b1fb3b..bf996ba5e 100644 --- a/letsencrypt/plugins/common.py +++ b/letsencrypt/plugins/common.py @@ -41,6 +41,36 @@ class Plugin(object): self.config = config self.name = name + @jose_util.abstractclassmethod + def add_parser_arguments(cls, add): + """Add plugin arguments to the CLI argument parser. + + :param callable add: Function that proxies calls to + `argparse.ArgumentParser.add_argument` prepending options + with unique plugin name prefix. + + NOTE: if you add argpase arguments such that users setting them can + create a config entry that python's bool() would consider false (ie, + the use might set the variable to "", [], 0, etc), please ensure that + cli._set_by_cli() works for your variable. + + """ + + @classmethod + def inject_parser_options(cls, parser, name): + """Inject parser options. + + See `~.IPlugin.inject_parser_options` for docs. + + """ + # dummy function, doesn't check if dest.startswith(self.dest_namespace) + def add(arg_name_no_prefix, *args, **kwargs): + # pylint: disable=missing-docstring + return parser.add_argument( + "--{0}{1}".format(option_namespace(name), arg_name_no_prefix), + *args, **kwargs) + return cls.add_parser_arguments(add) + @property def option_namespace(self): """ArgumentParser options namespace (prefix of all options).""" @@ -64,32 +94,6 @@ class Plugin(object): def conf(self, var): """Find a configuration value for variable ``var``.""" return getattr(self.config, self.dest(var)) - - @classmethod - def inject_parser_options(cls, parser, name): - """Inject parser options. - - See `~.IPlugin.inject_parser_options` for docs. - - """ - # dummy function, doesn't check if dest.startswith(self.dest_namespace) - def add(arg_name_no_prefix, *args, **kwargs): - # pylint: disable=missing-docstring - return parser.add_argument( - "--{0}{1}".format(option_namespace(name), arg_name_no_prefix), - *args, **kwargs) - return cls.add_parser_arguments(add) - - @jose_util.abstractclassmethod - def add_parser_arguments(cls, add): - """Add plugin arguments to the CLI argument parser. - - :param callable add: Function that proxies calls to - `argparse.ArgumentParser.add_argument` prepending options - with unique plugin name prefix. - - """ - # other