Browse Source

lightningd: allow plugin commands and options to mark themselves deprecated.

This lets us handle it the same way we handle builtin commands, and also
lets us warn if they use deprecated apis and allow-deprecated-apis=false.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Plugins: can now mark their options and commands deprecated.
bump-pyln-proto
Rusty Russell 5 years ago
parent
commit
7a7a849fc2
  1. 18
      doc/PLUGINS.md
  2. 34
      lightningd/plugin.c
  3. 1
      lightningd/plugin.h

18
doc/PLUGINS.md

@ -58,9 +58,10 @@ interface.
### The `getmanifest` method
The `getmanifest` method is required for all plugins and will be
called on startup with optionsl parameters (in particular, it may have
`allow-deprecated-apis: false`, but you should accept others). It
MUST return a JSON object similar to this example:
called on startup with optional parameters (in particular, it may have
`allow-deprecated-apis: false`, but you should accept, and ignore,
other parameters). It MUST return a JSON object similar to this
example:
```json
{
@ -69,7 +70,8 @@ MUST return a JSON object similar to this example:
"name": "greeting",
"type": "string",
"default": "World",
"description": "What name should I call you?"
"description": "What name should I call you?",
"deprecated": false
}
],
"rpcmethods": [
@ -82,7 +84,8 @@ MUST return a JSON object similar to this example:
"name": "gettime",
"usage": "",
"description": "Returns the current time in {timezone}",
"long_description": "Returns the current time in the timezone that is given as the only parameter.\nThis description may be quite long and is allowed to span multiple lines."
"long_description": "Returns the current time in the timezone that is given as the only parameter.\nThis description may be quite long and is allowed to span multiple lines.",
"deprecated": false
}
],
"subscriptions": [
@ -116,6 +119,11 @@ are mandatory, while the `long_description` can be omitted (it'll be
set to `description` if it was not provided). `usage` should surround optional
parameter names in `[]`.
`options` and `rpcmethods` can mark themselves `deprecated: true` if
you plan on removing them: this will disable them if the user sets
`allow-deprecated-apis` to false (which every developer should do,
right?).
The `dynamic` indicates if the plugin can be managed after `lightningd`
has been started. Critical plugins that should not be stopped should set it
to false.

34
lightningd/plugin.c

@ -587,6 +587,10 @@ char *plugin_opt_set(const char *arg, struct plugin_opt *popt)
char *endp;
long long l;
/* Warn them that this is deprecated */
if (popt->deprecated && !deprecated_apis)
return tal_fmt(tmpctx, "deprecated option (will be removed!)");
tal_free(popt->value->as_str);
popt->value->as_str = tal_strdup(popt, arg);
@ -630,12 +634,13 @@ static void destroy_plugin_opt(struct plugin_opt *opt)
static const char *plugin_opt_add(struct plugin *plugin, const char *buffer,
const jsmntok_t *opt)
{
const jsmntok_t *nametok, *typetok, *defaulttok, *desctok;
const jsmntok_t *nametok, *typetok, *defaulttok, *desctok, *deptok;
struct plugin_opt *popt;
nametok = json_get_member(buffer, opt, "name");
typetok = json_get_member(buffer, opt, "type");
desctok = json_get_member(buffer, opt, "description");
defaulttok = json_get_member(buffer, opt, "default");
deptok = json_get_member(buffer, opt, "deprecated");
if (!typetok || !nametok || !desctok) {
return tal_fmt(plugin,
@ -648,6 +653,15 @@ static const char *plugin_opt_add(struct plugin *plugin, const char *buffer,
popt->name = tal_fmt(popt, "--%.*s", nametok->end - nametok->start,
buffer + nametok->start);
popt->description = NULL;
if (deptok) {
if (!json_to_bool(buffer, deptok, &popt->deprecated))
return tal_fmt(plugin,
"%s: invalid \"deprecated\" field %.*s",
popt->name,
deptok->end - deptok->start,
buffer + deptok->start);
} else
popt->deprecated = false;
if (json_tok_streq(buffer, typetok, "string")) {
popt->type = "string";
@ -837,7 +851,8 @@ static const char *plugin_rpcmethod_add(struct plugin *plugin,
const char *buffer,
const jsmntok_t *meth)
{
const jsmntok_t *nametok, *categorytok, *desctok, *longdesctok, *usagetok;
const jsmntok_t *nametok, *categorytok, *desctok, *longdesctok,
*usagetok, *deptok;
struct json_command *cmd;
const char *usage;
@ -846,6 +861,7 @@ static const char *plugin_rpcmethod_add(struct plugin *plugin,
desctok = json_get_member(buffer, meth, "description");
longdesctok = json_get_member(buffer, meth, "long_description");
usagetok = json_get_member(buffer, meth, "usage");
deptok = json_get_member(buffer, meth, "deprecated");
if (!nametok || nametok->type != JSMN_STRING) {
return tal_fmt(plugin,
@ -891,7 +907,16 @@ static const char *plugin_rpcmethod_add(struct plugin *plugin,
} else
usage = "[params]";
cmd->deprecated = false;
if (deptok) {
if (!json_to_bool(buffer, deptok, &cmd->deprecated))
return tal_fmt(plugin,
"%s: invalid \"deprecated\" field %.*s",
cmd->name,
deptok->end - deptok->start,
buffer + deptok->start);
} else
cmd->deprecated = false;
cmd->dispatch = plugin_rpcmethod_dispatch;
if (!jsonrpc_command_add(plugin->plugins->ld->jsonrpc, cmd, usage)) {
return tal_fmt(plugin,
@ -1491,6 +1516,9 @@ void json_add_opt_plugins_array(struct json_stream *response,
if (!list_empty(&p->plugin_opts)) {
json_object_start(response, "options");
list_for_each(&p->plugin_opts, opt, list) {
if (!deprecated_apis && opt->deprecated)
continue;
/* Trim the `--` that we added before */
opt_name = opt->name + 2;
if (opt->value->as_bool) {

1
lightningd/plugin.h

@ -137,6 +137,7 @@ struct plugin_opt {
const char *type;
const char *description;
struct plugin_opt_value *value;
bool deprecated;
};
/**

Loading…
Cancel
Save