mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Initialize help when using redis-cli help or redis-cli ? (#10382)
The following usage will output an empty newline: ``` > redis-cli help set empty line ``` The reason is that in interactive mode, we have called `cliInitHelp`, which initializes help. When using `redis-cli help xxx` or `redis-cli help ? xxx`, we can't match the command due to empty `helpEntries`, so we output an empty newline. In this commit, we will call `cliInitHelp` to init the help. Note that in this case, we need to call `cliInitHelp` (COMMAND DOCS) every time, which i think is acceptable. So now the output will look like: ``` [redis]# src/redis-cli help get GET key summary: Get the value of a key since: 1.0.0 group: string [redis]# ``` Fixes #10378 This PR also fix a redis-cli crash when using `--ldb --eval`: ``` [root]# src/redis-cli --ldb --eval test.lua test 1 Lua debugging session started, please use: quit -- End the session. restart -- Restart the script in debug mode again. help -- Show Lua script debugging commands. * Stopped at 1, stop reason = step over -> 1 local num = redis.call('GET', KEYS[1]); redis-cli: redis-cli.c:718: cliCountCommands: Assertion `commandTable->element[i]->type == 1' failed. Aborted ``` Because in ldb mode, `COMMAND DOCS` or `COMMAND` will return an array, only with one element, and the type is `REDIS_REPLY_STATUS`, the result is `<error> Unknown Redis Lua debugger command or wrong number of arguments`. So if we are in the ldb mode, and init the Redis HELP, we will get the wrong response and crash the redis-cli. In ldb mode we don't initialize HELP, help is only initialized after the lua debugging session ends. It was broken in #10043
This commit is contained in:
parent
11b071a22b
commit
1797330e2e
@ -282,7 +282,7 @@ static void usage(int err);
|
||||
static void slaveMode(void);
|
||||
char *redisGitSHA1(void);
|
||||
char *redisGitDirty(void);
|
||||
static int cliConnect(int force);
|
||||
static int cliConnect(int flags);
|
||||
|
||||
static char *getInfoField(char *info, char *field);
|
||||
static long getLongInfoField(char *info, char *field);
|
||||
@ -800,7 +800,12 @@ static void cliInitHelp(void) {
|
||||
redisReply *commandTable;
|
||||
dict *groups;
|
||||
|
||||
if (cliConnect(CC_QUIET) == REDIS_ERR) return;
|
||||
if (cliConnect(CC_QUIET) == REDIS_ERR) {
|
||||
/* Can not connect to the server, but we still want to provide
|
||||
* help, generate it only from the old help.h data instead. */
|
||||
cliOldInitHelp();
|
||||
return;
|
||||
}
|
||||
commandTable = redisCommand(context, "COMMAND DOCS");
|
||||
if (commandTable == NULL || commandTable->type == REDIS_REPLY_ERROR) {
|
||||
/* New COMMAND DOCS subcommand not supported - generate help from old help.h data instead. */
|
||||
@ -810,7 +815,7 @@ static void cliInitHelp(void) {
|
||||
return;
|
||||
};
|
||||
if (commandTable->type != REDIS_REPLY_MAP && commandTable->type != REDIS_REPLY_ARRAY) return;
|
||||
|
||||
|
||||
/* Scan the array reported by COMMAND DOCS and fill in the entries */
|
||||
helpEntriesLen = cliCountCommands(commandTable);
|
||||
helpEntries = zmalloc(sizeof(helpEntry)*helpEntriesLen);
|
||||
@ -870,6 +875,12 @@ static void cliOutputHelp(int argc, char **argv) {
|
||||
group = argv[0]+1;
|
||||
}
|
||||
|
||||
if (helpEntries == NULL) {
|
||||
/* Initialize the help using the results of the COMMAND command.
|
||||
* In case we are using redis-cli help XXX, we need to init it. */
|
||||
cliInitHelp();
|
||||
}
|
||||
|
||||
assert(argc > 0);
|
||||
for (i = 0; i < helpEntriesLen; i++) {
|
||||
entry = &helpEntries[i];
|
||||
@ -1713,12 +1724,6 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
|
||||
size_t *argvlen;
|
||||
int j, output_raw;
|
||||
|
||||
if (!config.eval_ldb && /* In debugging mode, let's pass "help" to Redis. */
|
||||
(!strcasecmp(command,"help") || !strcasecmp(command,"?"))) {
|
||||
cliOutputHelp(--argc, ++argv);
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
if (context == NULL) return REDIS_ERR;
|
||||
|
||||
output_raw = 0;
|
||||
@ -2420,6 +2425,17 @@ static int confirmWithYes(char *msg, int ignore_force) {
|
||||
}
|
||||
|
||||
static int issueCommandRepeat(int argc, char **argv, long repeat) {
|
||||
/* In Lua debugging mode, we want to pass the "help" to Redis to get
|
||||
* it's own HELP message, rather than handle it by the CLI, see ldbRepl.
|
||||
*
|
||||
* For the normal Redis HELP, we can process it without a connection. */
|
||||
if (!config.eval_ldb &&
|
||||
(!strcasecmp(argv[0],"help") || !strcasecmp(argv[0],"?")))
|
||||
{
|
||||
cliOutputHelp(--argc, ++argv);
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (config.cluster_reissue_command || context == NULL ||
|
||||
context->err == REDIS_ERR_IO || context->err == REDIS_ERR_EOF)
|
||||
@ -2439,6 +2455,8 @@ static int issueCommandRepeat(int argc, char **argv, long repeat) {
|
||||
}
|
||||
if (cliSendCommand(argc,argv,repeat) != REDIS_OK) {
|
||||
cliPrintContextError();
|
||||
redisFree(context);
|
||||
context = NULL;
|
||||
return REDIS_ERR;
|
||||
}
|
||||
|
||||
@ -2576,8 +2594,13 @@ static void repl(void) {
|
||||
int argc;
|
||||
sds *argv;
|
||||
|
||||
/* Initialize the help using the results of the COMMAND command. */
|
||||
cliInitHelp();
|
||||
/* There is no need to initialize redis HELP when we are in lua debugger mode.
|
||||
* It has its own HELP and commands (COMMAND or COMMAND DOCS will fail and got nothing).
|
||||
* We will initialize the redis HELP after the Lua debugging session ended.*/
|
||||
if (!config.eval_ldb) {
|
||||
/* Initialize the help using the results of the COMMAND command. */
|
||||
cliInitHelp();
|
||||
}
|
||||
|
||||
config.interactive = 1;
|
||||
linenoiseSetMultiLine(1);
|
||||
@ -2679,6 +2702,7 @@ static void repl(void) {
|
||||
printf("\n(Lua debugging session ended%s)\n\n",
|
||||
config.eval_ldb_sync ? "" :
|
||||
" -- dataset changes rolled back");
|
||||
cliInitHelp();
|
||||
}
|
||||
|
||||
elapsed = mstime()-start_time;
|
||||
@ -9005,10 +9029,11 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
/* Otherwise, we have some arguments to execute */
|
||||
if (cliConnect(0) != REDIS_OK) exit(1);
|
||||
if (config.eval) {
|
||||
if (cliConnect(0) != REDIS_OK) exit(1);
|
||||
return evalMode(argc,argv);
|
||||
} else {
|
||||
cliConnect(CC_QUIET);
|
||||
return noninteractive(argc,argv);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user