From 719db14ec78d9da1c8abe3577cb77019c4c61eb3 Mon Sep 17 00:00:00 2001 From: guybe7 Date: Sun, 10 Apr 2022 10:41:31 +0200 Subject: [PATCH] COMMAND DOCS shows module name, where applicable (#10544) Add field to COMMAND DOCS response to denote the name of the module that added that command. COMMAND LIST can filter by module, but if you get the full commands list, you may still wanna know which command belongs to which module. The alternative would be to do MODULE LIST, and then multiple calls to COMMAND LIST --- src/module.c | 8 ++++++++ src/server.c | 5 +++++ src/server.h | 1 + tests/unit/moduleapi/cmdintrospection.tcl | 1 + tests/unit/moduleapi/subcommands.tcl | 4 ++-- 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/module.c b/src/module.c index 59b432d7d3..c4ec3f7277 100644 --- a/src/module.c +++ b/src/module.c @@ -6082,6 +6082,14 @@ const char *moduleTypeModuleName(moduleType *mt) { return mt->module->name; } +/* Return the module name from a module command */ +const char *moduleNameFromCommand(struct redisCommand *cmd) { + serverAssert(cmd->proc == RedisModuleCommandDispatcher); + + RedisModuleCommand *cp = (void*)(unsigned long)cmd->getkeys_proc; + return cp->module->name; +} + /* Create a copy of a module type value using the copy callback. If failed * or not supported, produce an error reply and return NULL. */ diff --git a/src/server.c b/src/server.c index 84f21fed3e..21c96a4538 100644 --- a/src/server.c +++ b/src/server.c @@ -4562,6 +4562,7 @@ void addReplyCommandDocs(client *c, struct redisCommand *cmd) { long maplen = 1; if (cmd->summary) maplen++; if (cmd->since) maplen++; + if (cmd->flags & CMD_MODULE) maplen++; if (cmd->complexity) maplen++; if (cmd->doc_flags) maplen++; if (cmd->deprecated_since) maplen++; @@ -4588,6 +4589,10 @@ void addReplyCommandDocs(client *c, struct redisCommand *cmd) { addReplyBulkCString(c, "complexity"); addReplyBulkCString(c, cmd->complexity); } + if (cmd->flags & CMD_MODULE) { + addReplyBulkCString(c, "module"); + addReplyBulkCString(c, moduleNameFromCommand(cmd)); + } if (cmd->doc_flags) { addReplyBulkCString(c, "doc_flags"); addReplyDocFlagsForCommand(c, cmd); diff --git a/src/server.h b/src/server.h index edfea2226c..02c00de5c7 100644 --- a/src/server.h +++ b/src/server.h @@ -2349,6 +2349,7 @@ int moduleGetCommandChannelsViaAPI(struct redisCommand *cmd, robj **argv, int ar moduleType *moduleTypeLookupModuleByID(uint64_t id); void moduleTypeNameByID(char *name, uint64_t moduleid); const char *moduleTypeModuleName(moduleType *mt); +const char *moduleNameFromCommand(struct redisCommand *cmd); void moduleFreeContext(struct RedisModuleCtx *ctx); void unblockClientFromModule(client *c); void moduleHandleBlockedClients(void); diff --git a/tests/unit/moduleapi/cmdintrospection.tcl b/tests/unit/moduleapi/cmdintrospection.tcl index 375b3e406a..8ac49ed9ff 100644 --- a/tests/unit/moduleapi/cmdintrospection.tcl +++ b/tests/unit/moduleapi/cmdintrospection.tcl @@ -36,6 +36,7 @@ start_server {tags {"modules"}} { # Compare the maps. We need to pop "group" first. dict unset redis_reply group dict unset module_reply group + dict unset module_reply module assert_equal $redis_reply $module_reply } diff --git a/tests/unit/moduleapi/subcommands.tcl b/tests/unit/moduleapi/subcommands.tcl index 11d2432435..5bc881d842 100644 --- a/tests/unit/moduleapi/subcommands.tcl +++ b/tests/unit/moduleapi/subcommands.tcl @@ -15,8 +15,8 @@ start_server {tags {"modules"}} { set docs_reply [r command docs subcommands.bitarray] set docs [dict create {*}[lindex $docs_reply 1]] set subcmds_in_cmd_docs [dict create {*}[dict get $docs subcommands]] - assert_equal [dict get $subcmds_in_cmd_docs "subcommands.bitarray|get"] {group module} - assert_equal [dict get $subcmds_in_cmd_docs "subcommands.bitarray|set"] {group module} + assert_equal [dict get $subcmds_in_cmd_docs "subcommands.bitarray|get"] {group module module subcommands} + assert_equal [dict get $subcmds_in_cmd_docs "subcommands.bitarray|set"] {group module module subcommands} } test "Module pure-container command fails on arity error" {