-
Notifications
You must be signed in to change notification settings - Fork 341
DOC-6823 make dependent data-type examples runnable in the interactive CLI #3604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
andy-stark-redis
wants to merge
28
commits into
main
Choose a base branch
from
DOC-6823-update-tce-examples-to-work-with-interactive-cli
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
2c14ef8
DOC-6823 make sorted-set zrank/zadd_lex examples runnable in the inte…
andy-stark-redis 2f99455
DOC-6823 make string setnx_xx example runnable in the interactive CLI
andy-stark-redis 329abae
DOC-6823 add reusable multi-client example test harness
andy-stark-redis c858733
DOC-6823 make hash hmget/hincrby examples runnable in the interactive…
andy-stark-redis 6d7f19d
DOC-6823 make timeseries dependent examples runnable in the interacti…
andy-stark-redis 0898fad
DOC-6823 add timeseries recreates to the go-redis client
andy-stark-redis 2423230
DOC-6823 add timeseries recreates to jedis, node, and C# clients
andy-stark-redis 12302f9
DOC-6823 make sets smismember example runnable in the interactive CLI
andy-stark-redis 9bf49b2
DOC-6823 add smismember recreates across the sets client tabs
andy-stark-redis 4f3925e
DOC-6823 make geosearch runnable in the interactive CLI via needs_prereq
andy-stark-redis 6735cf9
DOC-6823 run reactive StringExample steps sequentially, not under Mon…
andy-stark-redis 4c2284f
DOC-6823 use Double.NEGATIVE_INFINITY, not Double.MIN_VALUE, for -inf…
andy-stark-redis 17b158d
DOC-6823 make document-database term queries runnable via a merged cr…
andy-stark-redis b2fcf89
DOC-6823 make geoindex GEO/GEOSHAPE examples self-contained and runnable
andy-stark-redis 38e3594
DOC-6823 disable Try-it on document-database (payload over redis.io/c…
andy-stark-redis 8f8402f
DOC-6823 add build/check_tryit_payloads.py — audit Try-it button payl…
andy-stark-redis c58916e
DOC-6823 trim document-database descriptions under the Try-it limit; …
andy-stark-redis f37804f
DOC-6823 correct Try-it limit to 4094 request-line; re-disable docume…
andy-stark-redis 3b59414
DOC-6823 fix pre-existing upstream defects Bugbot flagged in the new …
andy-stark-redis 41cf3fd
DOC-6823 make check_tryit_payloads serialize like JSON.stringify (com…
andy-stark-redis 1e0445c
DOC-6823 fix stale 8192 references in check_tryit_payloads docstring/…
andy-stark-redis f79c791
DOC-6823 drop the lingering 8192 reference from the checker docstring
andy-stark-redis 983f1d3
DOC-6823 fix swapped brand/model for bicycle:9 in the jedis search ov…
andy-stark-redis bdc4452
DOC-6823 lowercase C# search paths, fix geoindex py import, dispose h…
andy-stark-redis c75fe58
DOC-6823 bump harness jedis to 7.5.3 so RedisClient examples compile
andy-stark-redis b6cb882
DOC-6823 fail the harness loudly on unreachable Redis / failed flush
andy-stark-redis 903c0d0
DOC-6823 complete the go search_quickstart index schema (price, condi…
andy-stark-redis e815e44
DOC-6823 order-independent node wildcard assert + harness exits non-z…
andy-stark-redis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| Check interactive "Try it" payload sizes across the docs. | ||
|
|
||
| The external "Try it" button on a `clients-example` block opens | ||
| `redis.io/cli?commands=<base64>&autorun=true`, where <base64> is the URL-safe | ||
| base64 of a JSON array of the block's CLI commands. The server rejects the | ||
| request with "Request Line is too large (N > 4094)" once the **HTTP request | ||
| line** exceeds ~4094 bytes. The request line is `GET /cli?commands=<base64>& | ||
| autorun=true HTTP/1.1`, i.e. the base64 payload plus ~40 bytes of scaffolding, | ||
| so the base64 must be ≲ 4054 bytes. Two subtleties this checker accounts for: | ||
|
|
||
| * The cap is on the request line / URL, not the raw typed command text. | ||
| Sizes are computed to match the browser exactly: base64 of | ||
| JSON.stringify(cmds) (compact separators, real UTF-8) — see _payload_b64_len. | ||
| * A block with `needs_prereq="true"` has its set's `prereq="true"` block | ||
| prepended by the button, so it inherits the prereq's payload size. | ||
|
|
||
| A block is only subject to the limit if its external button is actually shown: | ||
| `try_it != "false"` and `runnable != "false"`. Blocks over the limit should get | ||
| `try_it="false"` (the on-page terminal still runs them — it does not go through | ||
| the URL). See the DOC-6823 work on content/develop/get-started/document-database.md. | ||
|
|
||
| Usage: | ||
| python build/check_tryit_payloads.py [--content-dir content] [--limit 4094] | ||
| [--overhead 40] [--warn-frac 0.85] [--quiet] | ||
|
|
||
| Exit status: 1 if any interactive block's request line exceeds the limit, else 0 | ||
| (so it can gate CI). Stdlib only; run from the repo root. | ||
| """ | ||
|
|
||
| import argparse | ||
| import base64 | ||
| import glob | ||
| import json | ||
| import os | ||
| import re | ||
| import sys | ||
|
|
||
| # Match a shortcode attribute value. The negative lookbehind on a word char | ||
| # stops `prereq="..."` from also matching inside `needs_prereq="..."`. | ||
| def _attr(tag, name): | ||
| m = re.search(r'(?<![\w])' + re.escape(name) + r'="([^"]*)"', tag) | ||
| return m.group(1) if m else None | ||
|
|
||
|
|
||
| _OPEN_TAG = re.compile(r'\{\{<\s*clients-example\s+.*?>\}\}', re.S) | ||
| _CLOSE = '{{< /clients-example' | ||
|
|
||
|
|
||
| def _parse_blocks(text): | ||
| """Yield (open_tag, body_between_tags) for each clients-example block.""" | ||
| parts = re.split(r'(' + _OPEN_TAG.pattern + r')', text, flags=re.S) | ||
| i = 1 | ||
| while i < len(parts): | ||
| tag = parts[i] | ||
| body = parts[i + 1] if i + 1 < len(parts) else "" | ||
| end = body.find(_CLOSE) | ||
| if end >= 0: | ||
| body = body[:end] | ||
| yield tag, body | ||
| i += 2 | ||
|
|
||
|
|
||
| def _cli_cmds(body): | ||
| """Extract the redis-cli command lines (the `> ` / `redis> ` prefixed lines).""" | ||
| cmds = [] | ||
| for line in body.split("\n"): | ||
| s = line.strip() | ||
| if s.startswith("redis> "): | ||
| cmds.append(s[len("redis> "):]) | ||
| elif s.startswith("> "): | ||
| cmds.append(s[2:]) | ||
| return cmds | ||
|
|
||
|
|
||
| def _payload_b64_len(cmds): | ||
| """Bytes of the URL-safe base64 payload the button would send (no padding). | ||
|
|
||
| Mirrors the browser's btoa(unescape(encodeURIComponent(JSON.stringify(cmds)))): | ||
| JSON.stringify emits compact JSON (no spaces after ',' / ':') and keeps real | ||
| Unicode, so use compact separators and ensure_ascii=False + UTF-8 bytes. | ||
| Default json.dumps (spaces, \\uXXXX escapes) would overstate the size. | ||
| """ | ||
| js = json.dumps(cmds, separators=(",", ":"), ensure_ascii=False) | ||
| b64 = base64.b64encode(js.encode("utf-8")).decode().rstrip("=") | ||
| return len(b64) | ||
|
|
||
|
|
||
| def scan(content_dir): | ||
| """Return (blocks, set_prereq) for all clients-example blocks under content_dir.""" | ||
| blocks = [] | ||
| set_prereq = {} # (file, set) -> prereq command list | ||
| for f in sorted(glob.glob(os.path.join(content_dir, "**", "*.md"), recursive=True)): | ||
| try: | ||
| text = open(f, encoding="utf-8").read() | ||
| except (OSError, UnicodeDecodeError): | ||
| continue | ||
| if "clients-example" not in text: | ||
| continue | ||
| for tag, body in _parse_blocks(text): | ||
| b = { | ||
| "file": f, | ||
| "set": _attr(tag, "set"), | ||
| "step": _attr(tag, "step"), | ||
| "prereq": _attr(tag, "prereq") == "true", | ||
| "needs_prereq": _attr(tag, "needs_prereq") == "true", | ||
| "runnable": _attr(tag, "runnable"), | ||
| "try_it": _attr(tag, "try_it"), | ||
| "cmds": _cli_cmds(body), | ||
| } | ||
| blocks.append(b) | ||
| if b["prereq"]: | ||
| set_prereq[(b["file"], b["set"])] = b["cmds"] | ||
| return blocks, set_prereq | ||
|
|
||
|
|
||
| def payload_for(b, set_prereq): | ||
| """The full command list the button would send for block b.""" | ||
| cmds = [] | ||
| if b["needs_prereq"]: | ||
| cmds += set_prereq.get((b["file"], b["set"]), []) | ||
| cmds += b["cmds"] | ||
| return cmds | ||
|
|
||
|
|
||
| def main(): | ||
| ap = argparse.ArgumentParser(description=__doc__, | ||
| formatter_class=argparse.RawDescriptionHelpFormatter) | ||
| ap.add_argument("--content-dir", default="content") | ||
| ap.add_argument("--limit", type=int, default=4094, | ||
| help="max HTTP request-line bytes for redis.io/cli " | ||
| "(observed server cap: 4094)") | ||
| ap.add_argument("--overhead", type=int, default=40, | ||
| help="bytes added to the base64 payload to form the request " | ||
| "line: 'GET /cli?commands=' + '&autorun=true HTTP/1.1' " | ||
| "(~40; observed ~24, so 40 is conservative)") | ||
| ap.add_argument("--warn-frac", type=float, default=0.85, | ||
| help="warn when payload exceeds this fraction of the limit") | ||
| ap.add_argument("--quiet", action="store_true", | ||
| help="only print offenders, not the summary") | ||
| args = ap.parse_args() | ||
|
|
||
| blocks, set_prereq = scan(args.content_dir) | ||
|
|
||
| over, near = [], [] | ||
| for b in blocks: | ||
| # Only blocks whose external button is actually shown are subject to the limit. | ||
| if b["try_it"] == "false" or b["runnable"] == "false" or not b["cmds"]: | ||
| continue | ||
| b64 = _payload_b64_len(payload_for(b, set_prereq)) | ||
| size = b64 + args.overhead # estimated HTTP request-line length | ||
| if size > args.limit: | ||
| over.append((size, b64, b)) | ||
| elif size > args.limit * args.warn_frac: | ||
| near.append((size, b64, b)) | ||
|
|
||
| for size, b64, b in sorted(near, key=lambda x: x[0], reverse=True): | ||
| print(f"WARN req-line ~{size} B ({100*size/args.limit:.0f}% of " | ||
| f"{args.limit}, b64={b64}) {b['set']}/{b['step']} ({b['file']})") | ||
| for size, b64, b in sorted(over, key=lambda x: x[0], reverse=True): | ||
| print(f"OVER req-line ~{size} B (> {args.limit}, b64={b64}) " | ||
| f"{b['set']}/{b['step']} ({b['file']}) -- set try_it=\"false\" " | ||
| f"or trim to b64 <= {args.limit - args.overhead}") | ||
|
|
||
| if not args.quiet: | ||
| interactive = sum(1 for b in blocks | ||
| if b["try_it"] != "false" and b["runnable"] != "false" | ||
| and b["cmds"]) | ||
| print(f"\nScanned {len(blocks)} blocks ({interactive} interactive) under " | ||
| f"{args.content_dir}/. Request-line limit={args.limit} B " | ||
| f"(base64 payload + {args.overhead} B scaffolding). " | ||
| f"{len(over)} over, {len(near)} near.") | ||
|
|
||
| return 1 if over else 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # transient: cached per-language projects/deps and run logs | ||
| work/ | ||
| results/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # TCE example test harness | ||
|
|
||
| Runs a docs example set's per-client source files (from `local_examples/`) against a | ||
| **live throwaway Redis on `localhost:6379`**, using each library's real in-file | ||
| assertions. Built for the DOC-6823 work (making `try_it="false"` examples self-contained), | ||
| but reusable for any example set. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| ./run.sh <example_set> [client ...] | ||
| # all clients: | ||
| ./run.sh ss_tutorial | ||
| # one/some: | ||
| ./run.sh set_tutorial rust-sync dotnet | ||
| ``` | ||
|
|
||
| `example_set` ∈ { `ss_tutorial`, `set_tutorial` } today. Results print as a matrix; | ||
| per-run logs land in `results/<set>_<client>.log`. | ||
|
|
||
| ⚠️ Several examples call `FLUSHALL`/`FLUSHDB`, and the harness flushes before each run. | ||
| Point it only at a scratch Redis. | ||
|
|
||
| ## Clients & how each is run | ||
|
|
||
| | Client | Toolchain | Notes | | ||
| |---|---|---| | ||
| | python | venv + `redis` | run script directly (`assert`) | | ||
| | node | `npm i redis`, ESM | run as `.mjs` | | ||
| | go | module + `go-redis` | `go test`; needs a sibling `package example_commands` stub | | ||
| | jedis | Maven + `jedis:5.2.0` | surefire include `**/*Example.java` (classes aren't `*Test`) | | ||
| | lettuce-async / -reactive | Maven + `lettuce-core:6.5.5.RELEASE` | same surefire include | | ||
| | ruby | `redis` gem | run script (`raise`/local `assert_equal`) | | ||
| | rust-sync | Cargo + `redis = "1.3"` | file is `#[cfg(test)]` → dropped in `src/lib.rs`, `cargo test` | | ||
| | rust-async | Cargo + `redis` (tokio-comp) + `tokio` | `#[tokio::test]` | | ||
| | php | Composer + `predis/predis` | `bootstrap.php` stubs `PredisTestCase` asserts; reflection finds the `test*` method | | ||
| | dotnet | `dotnet test` + xunit + `StackExchange.Redis` | `dotnet/stubs.cs` stands in for NRedisStack's `AbstractNRedisStackTest`/`EndpointsFixture`/`[SkippableFact]`/`DocsTests` collection | | ||
|
|
||
| ## Gotchas learned | ||
|
|
||
| - **Version pins matter.** `redis-rs` is now **1.x** (`1.3`), not `0.27` — the old pin failed | ||
| to compile `flushall` in a REMOVE block. Jedis 5.2, Lettuce 6.5.5, StackExchange.Redis 2.8.x. | ||
| - **Surefire only runs `*Test`/`*Tests` by default** — these classes are `*Example`, so the | ||
| POMs add an explicit `<include>`. First run looked green with **zero tests** without it. | ||
| - The test scaffolding lives in `REMOVE_START` blocks; for py/ruby/node/go/rust/jedis/lettuce | ||
| it's self-contained (stdlib asserts / JUnit), but **C# and PHP reference their repo's own | ||
| test base classes**, which is why they need the stubs above. | ||
|
|
||
| ## Adding a new example set | ||
|
|
||
| Add one block of `case "$set:$client"` → source-path lines in `src_path()` in `run.sh`. | ||
| Nothing else changes; deps are cached under `work/`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| global using Xunit; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <LangVersion>latest</LangVersion> | ||
| <Nullable>disable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <IsPackable>false</IsPackable> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <PackageReference Include="StackExchange.Redis" Version="3.0.0" /> | ||
| <PackageReference Include="NRedisStack" Version="1.6.0" /> | ||
| <PackageReference Include="xunit" Version="2.9.2" /> | ||
| <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" /> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> | ||
| </ItemGroup> | ||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // Minimal stand-ins for NRedisStack's own test fixtures, so a docs example | ||
| // file (which extends AbstractNRedisStackTest and uses [SkippableFact]) runs | ||
| // under plain xunit + StackExchange.Redis. The example creates its own | ||
| // ConnectionMultiplexer, so the fixture helpers can be no-ops. | ||
| using StackExchange.Redis; | ||
|
|
||
| namespace NRedisStack.Tests | ||
| { | ||
| public class EndpointsFixture | ||
| { | ||
| public enum Env { Standalone } | ||
| } | ||
|
|
||
| public class AbstractNRedisStackTest : IDisposable | ||
| { | ||
| private ConnectionMultiplexer? _muxer; | ||
| protected AbstractNRedisStackTest(EndpointsFixture fixture) { } | ||
| protected void SkipIfTargetConnectionDoesNotExist(EndpointsFixture.Env env) { } | ||
| protected IDatabase GetCleanDatabase(EndpointsFixture.Env env) | ||
| { | ||
| _muxer ??= ConnectionMultiplexer.Connect("localhost:6379"); | ||
| return _muxer.GetDatabase(); | ||
| } | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| public void Dispose() { _muxer?.Dispose(); } | ||
| } | ||
|
|
||
| // The examples annotate the test method [SkippableFact]; make it a plain Fact. | ||
| public class SkippableFactAttribute : FactAttribute { } | ||
| } | ||
|
|
||
| // Satisfy [Collection("DocsTests")] + constructor injection of EndpointsFixture. | ||
| [CollectionDefinition("DocsTests")] | ||
| public class DocsTestsCollection : ICollectionFixture<NRedisStack.Tests.EndpointsFixture> { } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <groupId>io.redis</groupId><artifactId>jedis</artifactId><version>1.0</version> | ||
| <properties><maven.compiler.release>17</maven.compiler.release><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties> | ||
| <dependencies> | ||
| <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>7.5.3</version></dependency> | ||
| <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.10.2</version><scope>test</scope></dependency> | ||
| <dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.25.3</version><scope>test</scope></dependency> | ||
| </dependencies> | ||
| <build><plugins> | ||
| <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.2.5</version> | ||
| <configuration><includes><include>**/*Example.java</include></includes></configuration></plugin> | ||
| </plugins></build> | ||
| </project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <groupId>io.redis</groupId><artifactId>lettuce-async</artifactId><version>1.0</version> | ||
| <properties><maven.compiler.release>17</maven.compiler.release><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties> | ||
| <dependencies> | ||
| <dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.5.5.RELEASE</version></dependency> | ||
| <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.10.2</version><scope>test</scope></dependency> | ||
| <dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.25.3</version><scope>test</scope></dependency> | ||
| </dependencies> | ||
| <build><plugins> | ||
| <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.2.5</version> | ||
| <configuration><includes><include>**/*Example.java</include></includes></configuration></plugin> | ||
| </plugins></build> | ||
| </project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <groupId>io.redis</groupId><artifactId>lettuce-reactive</artifactId><version>1.0</version> | ||
| <properties><maven.compiler.release>17</maven.compiler.release><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties> | ||
| <dependencies> | ||
| <dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.5.5.RELEASE</version></dependency> | ||
| <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.10.2</version><scope>test</scope></dependency> | ||
| <dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.25.3</version><scope>test</scope></dependency> | ||
| </dependencies> | ||
| <build><plugins> | ||
| <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.2.5</version> | ||
| <configuration><includes><include>**/*Example.java</include></includes></configuration></plugin> | ||
| </plugins></build> | ||
| </project> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.