Repository: redis/redis

Issue:
[NEW] Add history, since & deprecated since to command arguments



Discussion:
we already have "since" in command arguments.
can you please give an example of where "history" and "deprecated since" would have been useful?
someone from JSON raised it (JSON.GET used to have an arg `NOESCAPE` up until version 2.0.0 of the module)
Also RediSearch has deprecated args, such as `WITHPAYLOADS` in `FT.SEARCH` and `PAYLOAD_FIELD` in `FT.CREATE`
i feel like the general command history should work fine for mentioning deprecated arguments, I don't think we need a history for arguments.

TBH even "since", which already exists in the arguments object, is kinda redundant, because the same information exists in history (or maybe the history should not include sentences like "this arg was added in that version"?), but one may claim that "since" may be used by clients.
The same goes for "deprecated_since", si will add it.

Patch:
diff --git a/src/module.c b/src/module.c
index 3fc6a5499f2..fd6aa9da7d9 100644
--- a/src/module.c
+++ b/src/module.c
@@ -1924,6 +1924,7 @@ static struct redisCommandArg *moduleCopyCommandArgs(RedisModuleCommandArg *args
         if (arg->token) realargs[j].token = zstrdup(arg->token);
         if (arg->summary) realargs[j].summary = zstrdup(arg->summary);
         if (arg->since) realargs[j].since = zstrdup(arg->since);
+        if (arg->deprecated_since) realargs[j].deprecated_since = zstrdup(arg->deprecated_since);
         realargs[j].flags = moduleConvertArgFlags(arg->flags);
         if (arg->subargs) realargs[j].subargs = moduleCopyCommandArgs(arg->subargs, version);
     }
@@ -10908,6 +10909,7 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
     }
     zfree((char *)cmd->summary);
     zfree((char *)cmd->since);
+    zfree((char *)cmd->deprecated_since);
     zfree((char *)cmd->complexity);
     if (cmd->latency_histogram) {
         hdr_close(cmd->latency_histogram);
diff --git a/src/redismodule.h b/src/redismodule.h
index f27c06b0ec8..8c2bee922dc 100644
--- a/src/redismodule.h
+++ b/src/redismodule.h
@@ -322,6 +322,7 @@ typedef struct RedisModuleCommandArg {
     const char *summary;
     const char *since;
     int flags;                /* The REDISMODULE_CMD_ARG_* macros. */
+    const char *deprecated_since;
     struct RedisModuleCommandArg *subargs;
 } RedisModuleCommandArg;
 
diff --git a/src/server.c b/src/server.c
index 84f21fed3ea..b475493def1 100644
--- a/src/server.c
+++ b/src/server.c
@@ -4309,6 +4309,7 @@ void addReplyCommandArgList(client *c, struct redisCommandArg *args, int num_arg
         if (args[j].token) maplen++;
         if (args[j].summary) maplen++;
         if (args[j].since) maplen++;
+        if (args[j].deprecated_since) maplen++;
         if (args[j].flags) maplen++;
         if (args[j].type == ARG_TYPE_ONEOF || args[j].type == ARG_TYPE_BLOCK)
             maplen++;
@@ -4336,6 +4337,10 @@ void addReplyCommandArgList(client *c, struct redisCommandArg *args, int num_arg
             addReplyBulkCString(c, "since");
             addReplyBulkCString(c, args[j].since);
         }
+        if (args[j].deprecated_since) {
+            addReplyBulkCString(c, "deprecated_since");
+            addReplyBulkCString(c, args[j].deprecated_since);
+        }
         if (args[j].flags) {
             addReplyBulkCString(c, "flags");
             addReplyFlagsForArg(c, args[j].flags);
diff --git a/src/server.h b/src/server.h
index edfea2226ca..9709c3e498c 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2042,6 +2042,7 @@ typedef struct redisCommandArg {
     const char *summary;
     const char *since;
     int flags;
+    const char *deprecated_since;
     struct redisCommandArg *subargs;
     /* runtime populated data */
     int num_args;
diff --git a/utils/generate-command-code.py b/utils/generate-command-code.py
index 2a4bd5ccc48..c5c08e196c8 100755
--- a/utils/generate-command-code.py
+++ b/utils/generate-command-code.py
@@ -175,6 +175,8 @@ def _flags_code():
             get_optional_desc_string(self.desc, "since"),
             _flags_code(),
         )
+        if "deprecated_since" in self.desc:
+            s += ",.deprecated_since=\"%s\"" % self.desc["deprecated_since"]
         if self.subargs:
             s += ",.subargs=%s" % self.subarg_table_name()