diff --git a/redis-cli/Cargo.toml b/redis-cli/Cargo.toml index 816df29..0c496c2 100644 --- a/redis-cli/Cargo.toml +++ b/redis-cli/Cargo.toml @@ -7,3 +7,4 @@ license = "Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +redis-core = { path = "../redis-core" } \ No newline at end of file diff --git a/redis-cli/src/help.rs b/redis-cli/src/help.rs new file mode 100644 index 0000000..db13968 --- /dev/null +++ b/redis-cli/src/help.rs @@ -0,0 +1,151 @@ +use std::process::exit; +use redis_core::version; + +pub(crate) fn print_usage(code: i32) { + const REDIS_CLI_AUTH_ENV: &str = "REDISCLI_AUTH"; + const REDIS_CLI_DEFAULT_PIPE_TIMEOUT: i32 = 30; + const USE_OPENSSL: bool = false; + const TLS1_3_VERSION: bool = false; + let redis_cli_version = version::redis_cli_version(); + + let mut usage = format!("{redis_cli_version} + +Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]] + -h Server hostname (default: 127.0.0.1). + -p Server port (default: 6379). + -s Server socket (overrides hostname and port). + -a Password to use when connecting to the server. + You can also use the {REDIS_CLI_AUTH_ENV} environment + variable to pass this password more safely + (if both are used, this argument takes precedence). + --user Used to send ACL style 'AUTH username pass'. Needs -a. + --pass Alias of -a for consistency with the new --user option. + --askpass Force user to input password with mask from STDIN. + If this argument is used, '-a' and {REDIS_CLI_AUTH_ENV} + environment variable will be ignored. + -u Server URI. + -r Execute specified command N times. + -i When -r is used, waits seconds per command. + It is possible to specify sub-second times like -i 0.1. + This interval is also used in --scan and --stat per cycle. + and in --bigkeys, --memkeys, and --hotkeys per 100 cycles. + -n Database number. + -2 Start session in RESP2 protocol mode. + -3 Start session in RESP3 protocol mode. + -x Read last argument from STDIN (see example below). + -X Read argument from STDIN (see example below). + -d Delimiter between response bulks for raw formatting (default: \\n). + -D Delimiter between responses for raw formatting (default: \\n). + -c Enable cluster mode (follow -ASK and -MOVED redirections). + -e Return exit error code when command execution fails."); + if USE_OPENSSL { + usage += " + --tls Establish a secure TLS connection. + --sni Server name indication for TLS. + --cacert CA Certificate file to verify with. + --cacertdir Directory where trusted CA certificates are stored. + If neither cacert nor cacertdir are specified, the default + system-wide trusted root certs configuration will apply. + --insecure Allow insecure TLS connection by skipping cert validation. + --cert Client certificate to authenticate with. + --key Private key file to authenticate with. + --tls-ciphers Sets the list of preferred ciphers (TLSv1.2 and below) + in order of preference from highest to lowest separated by colon (\":\"). + See the ciphers(1ssl) manpage for more information about the syntax of this string."; + + if TLS1_3_VERSION { + usage += " + --tls-ciphersuites Sets the list of preferred ciphersuites (TLSv1.3) + in order of preference from highest to lowest separated by colon (\":\"). + See the ciphers(1ssl) manpage for more information about the syntax of this string, + and specifically for TLSv1.3 ciphersuites." + } + } + + usage.push_str(format!(" + --raw Use raw formatting for replies (default when STDOUT is + not a tty). + --no-raw Force formatted output even when STDOUT is not a tty. + --quoted-input Force input to be handled as quoted strings. + --csv Output in CSV format. + --json Output in JSON format (default RESP3, use -2 if you want to use with RESP2). + --quoted-json Same as --json, but produce ASCII-safe quoted strings, not Unicode. + --show-pushes Whether to print RESP3 PUSH messages. Enabled by default when + STDOUT is a tty but can be overridden with --show-pushes no. + --stat Print rolling stats about server: mem, clients, ... + --latency Enter a special mode continuously sampling latency. + If you use this mode in an interactive session it runs + forever displaying real-time stats. Otherwise if --raw or + --csv is specified, or if you redirect the output to a non + TTY, it samples the latency for 1 second (you can use + -i to change the interval), then produces a single output + and exits. + --latency-history Like --latency but tracking latency changes over time. + Default time interval is 15 sec. Change it using -i. + --latency-dist Shows latency as a spectrum, requires xterm 256 colors. + Default time interval is 1 sec. Change it using -i. + --lru-test Simulate a cache workload with an 80-20 distribution. + --replica Simulate a replica showing commands received from the master. + --rdb Transfer an RDB dump from remote server to local file. + Use filename of \"-\" to write to stdout. + --functions-rdb Like --rdb but only get the functions (not the keys) + when getting the RDB dump file. + --pipe Transfer raw Redis protocol from stdin to server. + --pipe-timeout In --pipe mode, abort with error if after sending all data. + no reply is received within seconds. + Default timeout: {REDIS_CLI_DEFAULT_PIPE_TIMEOUT}. Use 0 to wait forever. + --bigkeys Sample Redis keys looking for keys with many elements (complexity). + --memkeys Sample Redis keys looking for keys consuming a lot of memory. + --memkeys-samples Sample Redis keys looking for keys consuming a lot of memory. + And define number of key elements to sample + --hotkeys Sample Redis keys looking for hot keys. + only works when maxmemory-policy is *lfu. + --scan List all keys using the SCAN command. + --pattern Keys pattern when using the --scan, --bigkeys or --hotkeys + options (default: *). + --quoted-pattern Same as --pattern, but the specified string can be + quoted, in order to pass an otherwise non binary-safe string. + --intrinsic-latency Run a test to measure intrinsic system latency. + The test will run for the specified amount of seconds. + --eval Send an EVAL command using the Lua script at . + --ldb Used with --eval enable the Redis Lua debugger. + --ldb-sync-mode Like --ldb but uses the synchronous Lua debugger, in + this mode the server is blocked and script changes are + not rolled back from the server memory. + --cluster [args...] [opts...] + Cluster Manager command and arguments (see below). + --verbose Verbose mode. + --no-auth-warning Don't show warning message when using password on command + line interface. + --help Output this help and exit. + --version Output version and exit. +").as_str()); + + /* Using another fprintf call to avoid -Woverlength-strings compile warning */ + usage += " +Cluster Manager Commands: + Use --cluster help to list all available cluster manager commands. + +Examples: + cat /etc/passwd | redis-cli -x set mypasswd + redis-cli -D \"\" --raw dump key > key.dump && redis-cli -X dump_tag restore key2 0 dump_tag replace < key.dump + redis-cli -r 100 lpush mylist x + redis-cli -r 100 -i 1 info | grep used_memory_human: + redis-cli --quoted-input set '\"null-\\x00-separated\"' value + redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3 + redis-cli --scan --pattern '*:12345*' + + (Note: when using --eval the comma separates KEYS[] from ARGV[] items) + +When no command is given, redis-cli starts in interactive mode. +Type \"help\" in interactive mode for information on available commands +and settings. +"; + + if code == 0 { + println!("{}", usage); + } else { + eprint!("{}", usage); + } + exit(code); +} \ No newline at end of file diff --git a/redis-cli/src/main.rs b/redis-cli/src/main.rs index bc4ace7..c78c661 100644 --- a/redis-cli/src/main.rs +++ b/redis-cli/src/main.rs @@ -1,3 +1,17 @@ +mod help; + +use std::env; +use std::process; +use redis_core::version; + fn main() { - println!("Hello, redis-cli!"); -} + let args: Vec = env::args().collect(); + if args.len() == 1 { + help::print_usage(0); + } + let arg1 = &args[1]; + if arg1 == "-v" || arg1 == "--version" { + println!("{}", version::redis_cli_version()); + process::exit(0); + } +} \ No newline at end of file diff --git a/redis-core/src/version.rs b/redis-core/src/version.rs index 88cb536..f94a6c3 100644 --- a/redis-core/src/version.rs +++ b/redis-core/src/version.rs @@ -1,9 +1,17 @@ -const REDIS_VERSION: &str = "7.0.5"; -const REDIS_GIT_SHA1: &str = ""; -const REDIS_GIT_DIRTY: u8 = 0; +const REDIS_VERSION: &str = "7.0.11"; +const REDIS_GIT_SHA1: &str = "bdb1e6cc"; +const REDIS_GIT_DIRTY: u8 = 1; pub fn check_rdb_version() -> String { - let mut version = format!("redis-check-rdb {REDIS_VERSION}"); + version("redis-check-rdb") +} + +pub fn redis_cli_version() -> String { + version("redis-cli") +} + +fn version(name: &str) -> String { + let mut version = format!("{name} {REDIS_VERSION}"); if !REDIS_GIT_SHA1.trim().is_empty() { version = format!("{version} (git:{REDIS_GIT_SHA1}"); if REDIS_GIT_DIRTY > 0 {