add redis 5.0.4 (#6320)

First off, thank you to @dzbarsky for adding the `redis` module to the
BCR!

This change adds a redis 5.0.4 module. @buildbuddy-io runs redis 5.0.4
in production, and we would love to test using the same redis version.

To get the build working on arm64 Mac, I had to add 2 patches.

I have built all targets on arm64 Mac and Linux (and tested using the
`redis-server` target on arm64 Mac).

Please leave any and all feedback. Thank you! 🙏
diff --git a/modules/redis/5.0.4/MODULE.bazel b/modules/redis/5.0.4/MODULE.bazel
new file mode 100644
index 0000000..bea75bf
--- /dev/null
+++ b/modules/redis/5.0.4/MODULE.bazel
@@ -0,0 +1,10 @@
+module(
+    name = "redis",
+    version = "5.0.4",
+    compatibility_level = 0,
+    bazel_compatibility = ['>=7.2.1'],
+)
+
+bazel_dep(name = "platforms", version = "1.0.0")
+bazel_dep(name = "rules_cc", version = "0.1.1")
+bazel_dep(name = "rules_shell", version = "0.5.1")
diff --git a/modules/redis/5.0.4/overlay/BUILD.bazel b/modules/redis/5.0.4/overlay/BUILD.bazel
new file mode 100644
index 0000000..9642e82
--- /dev/null
+++ b/modules/redis/5.0.4/overlay/BUILD.bazel
@@ -0,0 +1,205 @@
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
+
+cc_library(
+    name = "linenoise",
+    srcs = glob(["deps/linenoise/*.c"]),
+    hdrs = glob(["deps/linenoise/*.h"]),
+    strip_include_prefix = "deps/linenoise",
+)
+
+cc_library(
+    name = "hiredis",
+    srcs = glob(
+        ["deps/hiredis/*.c"],
+        exclude = [
+            "deps/hiredis/dict.c",
+            "deps/hiredis/test.c",
+        ],
+    ),
+    hdrs = glob(["deps/hiredis/*.h"]),
+    strip_include_prefix = "deps/hiredis",
+    textual_hdrs = ["deps/hiredis/dict.c"],
+)
+
+cc_library(
+    name = "lua",
+    srcs = glob(
+        ["deps/lua/src/*.c"],
+        exclude = [
+            "deps/lua/src/lua.c",
+            "deps/lua/src/luac.c",
+            "deps/lua/src/print.c",
+        ],
+    ) + ["src/solarisfixes.h"],
+    hdrs = glob(["deps/lua/src/*.h"]),
+    strip_include_prefix = "deps/lua/src",
+    local_defines = ["ENABLE_CJSON_GLOBAL"],
+    copts = ["-Wno-deprecated-declarations"],
+)
+
+sh_binary(
+    name = "mkreleasehdr",
+    srcs = ["src/mkreleasehdr.sh"],
+)
+
+genrule(
+    name = "generate_release_header",
+    outs = ["release.h"],
+    cmd = "$(location mkreleasehdr) && mv release.h $@",
+    tools = [":mkreleasehdr"],
+)
+
+cc_library(
+    name = "redis_lib",
+    srcs = [
+        "src/adlist.c",
+        "src/ae.c",
+        "src/anet.c",
+        "src/aof.c",
+        "src/bio.c",
+        "src/bitops.c",
+        "src/blocked.c",
+        "src/childinfo.c",
+        "src/cluster.c",
+        "src/config.c",
+        "src/crc16.c",
+        "src/crc64.c",
+        "src/db.c",
+        "src/debug.c",
+        "src/defrag.c",
+        "src/dict.c",
+        "src/endianconv.c",
+        "src/evict.c",
+        "src/expire.c",
+        "src/geo.c",
+        "src/geohash.c",
+        "src/geohash_helper.c",
+        "src/hyperloglog.c",
+        "src/intset.c",
+        "src/latency.c",
+        "src/lazyfree.c",
+        "src/listpack.c",
+        "src/localtime.c",
+        "src/lolwut.c",
+        "src/lolwut5.c",
+        "src/lzf_c.c",
+        "src/lzf_d.c",
+        "src/memtest.c",
+        "src/module.c",
+        "src/multi.c",
+        "src/networking.c",
+        "src/notify.c",
+        "src/object.c",
+        "src/pqsort.c",
+        "src/pubsub.c",
+        "src/quicklist.c",
+        "src/rand.c",
+        "src/rax.c",
+        "src/rdb.c",
+        "src/redis-check-aof.c",
+        "src/redis-check-rdb.c",
+        "src/release.c",
+        "src/replication.c",
+        "src/rio.c",
+        "src/scripting.c",
+        "src/sds.c",
+        "src/sentinel.c",
+        "src/server.c",
+        "src/setproctitle.c",
+        "src/sha1.c",
+        "src/siphash.c",
+        "src/slowlog.c",
+        "src/sort.c",
+        "src/sparkline.c",
+        "src/syncio.c",
+        "src/t_hash.c",
+        "src/t_list.c",
+        "src/t_set.c",
+        "src/t_stream.c",
+        "src/t_string.c",
+        "src/t_zset.c",
+        "src/util.c",
+        "src/ziplist.c",
+        "src/zipmap.c",
+        "src/zmalloc.c",
+    ] + glob(["src/*.h"]) + ["release.h"],
+    textual_hdrs = glob(["src/ae_*.c"]),
+    includes = ["src"],
+    copts = select({
+        "@platforms//os:linux": ["-fcommon"],
+        "//conditions:default": [],
+    }),
+    deps = [
+        ":hiredis",
+        ":lua",
+    ],
+)
+
+cc_library(
+    name = "redis_cli_lib",
+    srcs = [
+        "src/adlist.c",
+        "src/ae.c",
+        "src/anet.c",
+        "src/crc16.c",
+        "src/crc64.c",
+        "src/dict.c",
+        "src/redis-cli.c",
+        "src/release.c",
+        "src/siphash.c",
+        "src/zmalloc.c",
+    ] + glob(["src/*.h"]) + ["release.h"],
+    textual_hdrs = glob(["src/ae_*.c"]),
+    includes = ["src"],
+    copts = select({
+        "@platforms//os:linux": ["-fcommon"],
+        "//conditions:default": [],
+    }),
+    deps = [
+        ":hiredis",
+        ":linenoise",
+        ":lua",
+    ],
+)
+
+cc_binary(
+    name = "redis-server",
+    deps = [":redis_lib"],
+    visibility = ["//visibility:public"],
+    linkopts = select({
+        "@platforms//os:linux": [
+            "-ldl",
+            "-lm",
+            "-lpthread",
+        ],
+        "@platforms//os:osx": [
+            "-lm",
+        ],
+        "//conditions:default": [],
+    }),
+)
+
+cc_binary(
+    name = "redis-cli",
+    deps = [":redis_cli_lib"],
+    visibility = ["//visibility:public"],
+    linkopts = select({
+        "@platforms//os:linux": [
+            "-lm",
+        ],
+        "@platforms//os:osx": [
+            "-lm",
+        ],
+        "//conditions:default": [],
+    }),
+)
+
+filegroup(
+    name = "redis",
+    srcs = [
+        ":redis-server",
+        ":redis-cli",
+    ],
+    visibility = ["//visibility:public"],
+)
diff --git a/modules/redis/5.0.4/overlay/MODULE.bazel b/modules/redis/5.0.4/overlay/MODULE.bazel
new file mode 120000
index 0000000..9b599e3
--- /dev/null
+++ b/modules/redis/5.0.4/overlay/MODULE.bazel
@@ -0,0 +1 @@
+../MODULE.bazel
\ No newline at end of file
diff --git a/modules/redis/5.0.4/patches/macos-arm64-debug.patch b/modules/redis/5.0.4/patches/macos-arm64-debug.patch
new file mode 100644
index 0000000..6e3f800
--- /dev/null
+++ b/modules/redis/5.0.4/patches/macos-arm64-debug.patch
@@ -0,0 +1,79 @@
+--- src/debug.c
++++ src/debug.c
+@@ -45,6 +45,9 @@
+ #include <fcntl.h>
+ #include "bio.h"
+ #include <unistd.h>
++#ifdef __APPLE__
++#include <mach/mach.h>
++#endif
+ #endif /* HAVE_BACKTRACE */
+ 
+ #ifdef __CYGWIN__
+@@ -744,7 +747,9 @@
+     #endif
+ #elif defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
+     /* OSX >= 10.6 */
+-    #if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
++    #if defined(__arm64__) || defined(__aarch64__)
++    return (void*) uc->uc_mcontext->__ss.__pc;
++    #elif defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
+     return (void*) uc->uc_mcontext->__ss.__rip;
+     #else
+     return (void*) uc->uc_mcontext->__ss.__eip;
+@@ -833,6 +838,55 @@
+         (unsigned long) uc->uc_mcontext->__ss.__gs
+     );
+     logStackContent((void**)uc->uc_mcontext->__ss.__rsp);
++    #elif defined(__arm64__) || defined(__aarch64__)
++    /* OSX ARM64 */
++    serverLog(LL_WARNING,
++    "\n"
++    "x0:%016lx x1:%016lx x2:%016lx x3:%016lx\n"
++    "x4:%016lx x5:%016lx x6:%016lx x7:%016lx\n"
++    "x8:%016lx x9:%016lx x10:%016lx x11:%016lx\n"
++    "x12:%016lx x13:%016lx x14:%016lx x15:%016lx\n"
++    "x16:%016lx x17:%016lx x18:%016lx x19:%016lx\n"
++    "x20:%016lx x21:%016lx x22:%016lx x23:%016lx\n"
++    "x24:%016lx x25:%016lx x26:%016lx x27:%016lx\n"
++    "x28:%016lx fp:%016lx lr:%016lx\n"
++    "sp:%016lx pc:%016lx cpsr:%08lx\n",
++        (unsigned long) uc->uc_mcontext->__ss.__x[0],
++        (unsigned long) uc->uc_mcontext->__ss.__x[1],
++        (unsigned long) uc->uc_mcontext->__ss.__x[2],
++        (unsigned long) uc->uc_mcontext->__ss.__x[3],
++        (unsigned long) uc->uc_mcontext->__ss.__x[4],
++        (unsigned long) uc->uc_mcontext->__ss.__x[5],
++        (unsigned long) uc->uc_mcontext->__ss.__x[6],
++        (unsigned long) uc->uc_mcontext->__ss.__x[7],
++        (unsigned long) uc->uc_mcontext->__ss.__x[8],
++        (unsigned long) uc->uc_mcontext->__ss.__x[9],
++        (unsigned long) uc->uc_mcontext->__ss.__x[10],
++        (unsigned long) uc->uc_mcontext->__ss.__x[11],
++        (unsigned long) uc->uc_mcontext->__ss.__x[12],
++        (unsigned long) uc->uc_mcontext->__ss.__x[13],
++        (unsigned long) uc->uc_mcontext->__ss.__x[14],
++        (unsigned long) uc->uc_mcontext->__ss.__x[15],
++        (unsigned long) uc->uc_mcontext->__ss.__x[16],
++        (unsigned long) uc->uc_mcontext->__ss.__x[17],
++        (unsigned long) uc->uc_mcontext->__ss.__x[18],
++        (unsigned long) uc->uc_mcontext->__ss.__x[19],
++        (unsigned long) uc->uc_mcontext->__ss.__x[20],
++        (unsigned long) uc->uc_mcontext->__ss.__x[21],
++        (unsigned long) uc->uc_mcontext->__ss.__x[22],
++        (unsigned long) uc->uc_mcontext->__ss.__x[23],
++        (unsigned long) uc->uc_mcontext->__ss.__x[24],
++        (unsigned long) uc->uc_mcontext->__ss.__x[25],
++        (unsigned long) uc->uc_mcontext->__ss.__x[26],
++        (unsigned long) uc->uc_mcontext->__ss.__x[27],
++        (unsigned long) uc->uc_mcontext->__ss.__x[28],
++        (unsigned long) uc->uc_mcontext->__ss.__fp,
++        (unsigned long) uc->uc_mcontext->__ss.__lr,
++        (unsigned long) uc->uc_mcontext->__ss.__sp,
++        (unsigned long) uc->uc_mcontext->__ss.__pc,
++        (unsigned long) uc->uc_mcontext->__ss.__cpsr
++    );
++    logStackContent((void**)uc->uc_mcontext->__ss.__sp);
+     #else
+     /* OSX x86 */
+     serverLog(LL_WARNING,
diff --git a/modules/redis/5.0.4/patches/macos-stat-availability.patch b/modules/redis/5.0.4/patches/macos-stat-availability.patch
new file mode 100644
index 0000000..729e61b
--- /dev/null
+++ b/modules/redis/5.0.4/patches/macos-stat-availability.patch
@@ -0,0 +1,13 @@
+--- src/config.h
++++ src/config.h
+@@ -32,7 +32,10 @@
+ 
+ #ifdef __APPLE__
+ #include <AvailabilityMacros.h>
++#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 && !defined(MAC_OS_X_VERSION_10_6)
++#define MAC_OS_X_VERSION_10_6 __MAC_OS_X_VERSION_MAX_ALLOWED
+ #endif
++#endif
+ 
+ #ifdef __linux__
+ #include <linux/version.h>
diff --git a/modules/redis/5.0.4/presubmit.yml b/modules/redis/5.0.4/presubmit.yml
new file mode 100644
index 0000000..342b8e8
--- /dev/null
+++ b/modules/redis/5.0.4/presubmit.yml
@@ -0,0 +1,16 @@
+matrix:
+  platform:
+  - debian11
+  - ubuntu2204
+  - macos
+  - macos_arm64
+  bazel:
+  - 8.x
+  - 7.x
+tasks:
+  verify_targets:
+    name: Verify build targets
+    platform: ${{ platform }}
+    bazel: ${{ bazel }}
+    build_targets:
+    - '@redis'
diff --git a/modules/redis/5.0.4/source.json b/modules/redis/5.0.4/source.json
new file mode 100644
index 0000000..9093327
--- /dev/null
+++ b/modules/redis/5.0.4/source.json
@@ -0,0 +1,14 @@
+{
+    "url": "https://download.redis.io/releases/redis-5.0.4.tar.gz",
+    "strip_prefix": "redis-5.0.4",
+    "overlay": {
+        "BUILD.bazel": "sha256-WuMuXC+BXDPI9BppgSpByzR+xTZY0Iq6qFnSn8XvuKo=",
+        "MODULE.bazel": "sha256-RuDizanlE1mJi4FMwcB8jQZpRRYm0IZHd5/mgt/dBAs="
+    },
+    "patch_strip": 0,
+    "patches": {
+        "macos-arm64-debug.patch": "sha256-KIxzR4i0HxsDEnMKnH6Kre7EDBZif0N3EMR34Pr3Gxg=",
+        "macos-stat-availability.patch": "sha256-3GfRk3wqkp4NubkzuVxTx4p7EcZO+CG3NVqTBKjF/Bk="
+    },
+    "integrity": "sha256-POnO/1oj9gkT4Vc/bfzUqlO0LUonieKPpT7CvSjJh90="
+}
diff --git a/modules/redis/metadata.json b/modules/redis/metadata.json
index c0ff2f5..523639b 100644
--- a/modules/redis/metadata.json
+++ b/modules/redis/metadata.json
@@ -12,6 +12,7 @@
         "https://download.redis.io/releases"
     ],
     "versions": [
+        "5.0.4",
         "7.2.4"
     ],
     "yanked_versions": {}