mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 14:24:09 +01:00
plugins: get usage from plugins (required unless deprecated_apis == True).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
a8d1588154
commit
53c0a21d2c
3 changed files with 34 additions and 6 deletions
|
@ -70,10 +70,12 @@ this example:
|
|||
"rpcmethods": [
|
||||
{
|
||||
"name": "hello",
|
||||
"usage": "[name]",
|
||||
"description": "Returns a personalized greeting for {greeting} (set via options)."
|
||||
},
|
||||
{
|
||||
"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."
|
||||
}
|
||||
|
@ -93,9 +95,10 @@ currently only string options are supported.*
|
|||
The `rpcmethods` are methods that will be exposed via `lightningd`'s
|
||||
JSON-RPC over Unix-Socket interface, just like the builtin
|
||||
commands. Any parameters given to the JSON-RPC calls will be passed
|
||||
through verbatim. Notice that the `name` and the `description` fields
|
||||
through verbatim. Notice that the `name`, `description` and `usage` fields
|
||||
are mandatory, while the `long_description` can be omitted (it'll be
|
||||
set to `description` if it was not provided).
|
||||
set to `description` if it was not provided). `usage` should surround optional
|
||||
parameter names in `[]`.
|
||||
|
||||
Plugins are free to register any `name` for their `rpcmethod` as long
|
||||
as the name was not previously registered. This includes both built-in
|
||||
|
@ -149,11 +152,13 @@ called `hello` and `gettime`:
|
|||
"rpcmethods": [
|
||||
{
|
||||
"name": "hello",
|
||||
"usage": "[name]",
|
||||
"description": "Returns a personalized greeting for {greeting} (set via options)."
|
||||
},
|
||||
{
|
||||
"name": "gettime",
|
||||
"description": "Returns the current time in {timezone}",
|
||||
"usage": "",
|
||||
"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."
|
||||
}
|
||||
],
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <lightningd/json.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/notification.h>
|
||||
#include <lightningd/options.h>
|
||||
#include <lightningd/plugin_hook.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -633,12 +634,14 @@ static bool plugin_rpcmethod_add(struct plugin *plugin,
|
|||
const char *buffer,
|
||||
const jsmntok_t *meth)
|
||||
{
|
||||
const jsmntok_t *nametok, *desctok, *longdesctok;
|
||||
const jsmntok_t *nametok, *desctok, *longdesctok, *usagetok;
|
||||
struct json_command *cmd;
|
||||
const char *usage;
|
||||
|
||||
nametok = json_get_member(buffer, meth, "name");
|
||||
desctok = json_get_member(buffer, meth, "description");
|
||||
longdesctok = json_get_member(buffer, meth, "long_description");
|
||||
usagetok = json_get_member(buffer, meth, "usage");
|
||||
|
||||
if (!nametok || nametok->type != JSMN_STRING) {
|
||||
plugin_kill(plugin,
|
||||
|
@ -662,6 +665,13 @@ static bool plugin_rpcmethod_add(struct plugin *plugin,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (usagetok && usagetok->type != JSMN_STRING) {
|
||||
plugin_kill(plugin,
|
||||
"\"usage\" is not a string: %.*s",
|
||||
meth->end - meth->start, buffer + meth->start);
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd = notleak(tal(plugin, struct json_command));
|
||||
cmd->name = json_strdup(cmd, buffer, nametok);
|
||||
cmd->description = json_strdup(cmd, buffer, desctok);
|
||||
|
@ -669,12 +679,18 @@ static bool plugin_rpcmethod_add(struct plugin *plugin,
|
|||
cmd->verbose = json_strdup(cmd, buffer, longdesctok);
|
||||
else
|
||||
cmd->verbose = cmd->description;
|
||||
if (usagetok)
|
||||
usage = json_strdup(tmpctx, buffer, usagetok);
|
||||
else if (!deprecated_apis) {
|
||||
plugin_kill(plugin,
|
||||
"\"usage\" not provided by plugin");
|
||||
return false;
|
||||
} else
|
||||
usage = "[params]";
|
||||
|
||||
cmd->deprecated = false;
|
||||
cmd->dispatch = plugin_rpcmethod_dispatch;
|
||||
if (!jsonrpc_command_add(plugin->plugins->ld->jsonrpc, cmd,
|
||||
/* FIXME */
|
||||
"[params]")) {
|
||||
if (!jsonrpc_command_add(plugin->plugins->ld->jsonrpc, cmd, usage)) {
|
||||
log_broken(plugin->log,
|
||||
"Could not register method \"%s\", a method with "
|
||||
"that name is already registered",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
from fixtures import * # noqa: F401,F403
|
||||
from lightning import RpcError
|
||||
from utils import only_one
|
||||
|
||||
import pytest
|
||||
import subprocess
|
||||
|
@ -47,6 +48,8 @@ def test_rpc_passthrough(node_factory):
|
|||
cmd = [hlp for hlp in n.rpc.help()['help'] if 'hello' in hlp['command']]
|
||||
assert(len(cmd) == 1)
|
||||
|
||||
# Make sure usage message is present.
|
||||
assert only_one(n.rpc.help('hello')['help'])['command'] == 'hello [name]'
|
||||
# While we're at it, let's check that helloworld.py is logging
|
||||
# correctly via the notifications plugin->lightningd
|
||||
assert n.daemon.is_in_log('Plugin helloworld.py initialized')
|
||||
|
@ -119,3 +122,7 @@ def test_pay_plugin(node_factory):
|
|||
|
||||
with pytest.raises(RpcError, match=r'missing required parameter'):
|
||||
l1.rpc.call('pay')
|
||||
|
||||
# Make sure usage messages are present.
|
||||
assert only_one(l1.rpc.help('pay')['help'])['command'] == 'pay bolt11 [msatoshi] [description] [riskfactor] [maxfeepercent] [retry_for] [maxdelay] [exemptfee]'
|
||||
assert only_one(l1.rpc.help('paystatus')['help'])['command'] == 'paystatus [bolt11]'
|
||||
|
|
Loading…
Add table
Reference in a new issue