From 4e01de60e7521fe6fe4c9eae5fcb00cf1988d6f5 Mon Sep 17 00:00:00 2001 From: Mac Chaffee Date: Thu, 1 Jun 2023 15:45:58 -0400 Subject: [PATCH] refactor: migrate from structopt to clap v3 (#211) * Migrate from structopt to clap v3 Essentially followed this guide: https://github.com/clap-rs/clap/blob/v3.1.6/CHANGELOG.md#migrating * Depend on clap directly * Update use statements * Change "short" params to single chars * required_if -> required_if_eq * When referencing other args like in required_if_eq, use hyphens instead of dashes * Last param of default_value_if is now an Option * refactor: https-redirect* cli options --------- Signed-off-by: Mac Chaffee Co-authored-by: Jose Quintana --- Cargo.lock | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------- Cargo.toml | 2 +- src/directory_listing.rs | 2 +- src/settings/cli.rs | 64 +++++++++++++++++++++++++++++++++------------------------------- src/settings/mod.rs | 2 +- 5 files changed, 117 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da52844..1b19c2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,17 @@ dependencies = [ ] [[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -222,13 +233,41 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ + "atty", "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", "textwrap", - "unicode-width", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -434,11 +473,17 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "unicode-segmentation", + "libc", ] [[package]] @@ -714,7 +759,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -725,6 +770,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + +[[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1076,6 +1127,7 @@ dependencies = [ "bcrypt", "bytes", "chrono", + "clap", "form_urlencoded", "futures-util", "globset", @@ -1096,7 +1148,6 @@ dependencies = [ "serde_repr", "signal-hook", "signal-hook-tokio", - "structopt", "tikv-jemallocator", "tokio", "tokio-rustls", @@ -1108,28 +1159,10 @@ dependencies = [ ] [[package]] -name = "structopt" -version = "0.3.26" +name = "strsim" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" @@ -1160,15 +1193,21 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ - "unicode-width", + "winapi-util", ] [[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] name = "thread_local" version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1341,18 +1380,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1479,6 +1506,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 5a2c847..3387d6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ rustls-pemfile = { version = "1.0", optional = true } serde = { version = "1.0", default-features = false, features = ["derive"] } serde_ignored = "0.1" serde_repr = "0.1" -structopt = { version = "0.3", default-features = false } +clap = { version = "3.0", features = ["derive", "env"] } chrono = { version = "0.4", default-features = false, features = ["std", "clock"] } tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros", "fs", "io-util", "signal"] } tokio-rustls = { version = "0.24", optional = true } diff --git a/src/directory_listing.rs b/src/directory_listing.rs index 47753a1..952db87 100644 --- a/src/directory_listing.rs +++ b/src/directory_listing.rs @@ -9,6 +9,7 @@ #![allow(missing_docs)] use chrono::{DateTime, Local, NaiveDateTime, Utc}; +use clap::arg_enum; use futures_util::future::Either; use futures_util::{future, FutureExt}; use headers::{ContentLength, ContentType, HeaderMapExt}; @@ -21,7 +22,6 @@ use std::future::Future; use std::io; use std::path::Path; use std::time::{SystemTime, UNIX_EPOCH}; -use structopt::clap::arg_enum; use crate::{exts::http::MethodExt, Context, Result}; diff --git a/src/settings/cli.rs b/src/settings/cli.rs index 2c686d9..fc41286 100644 --- a/src/settings/cli.rs +++ b/src/settings/cli.rs @@ -5,8 +5,8 @@ //! The server CLI options +use clap::StructOpt; use std::path::PathBuf; -use structopt::StructOpt; use crate::directory_listing::DirListFmt; @@ -14,19 +14,19 @@ use crate::directory_listing::DirListFmt; #[derive(Debug, StructOpt)] #[structopt(about, author)] pub struct General { - #[structopt(long, short = "a", default_value = "::", env = "SERVER_HOST")] + #[structopt(long, short = 'a', default_value = "::", env = "SERVER_HOST")] /// Host address (E.g 127.0.0.1 or ::1) pub host: String, - #[structopt(long, short = "p", default_value = "80", env = "SERVER_PORT")] + #[structopt(long, short = 'p', default_value = "80", env = "SERVER_PORT")] /// Host port pub port: u16, #[structopt( long, - short = "f", + short = 'f', env = "SERVER_LISTEN_FD", - conflicts_with_all(&["host", "port", "https_redirect"]) + conflicts_with_all(&["host", "port", "https-redirect"]) )] /// Instead of binding to a TCP port, accept incoming connections to an already-bound TCP /// socket listener on the specified file descriptor number (usually zero). Requires that the @@ -41,7 +41,7 @@ pub struct General { not(wasm), structopt( long, - short = "n", + short = 'n', default_value = "1", env = "SERVER_THREADS_MULTIPLIER" ) @@ -50,7 +50,7 @@ pub struct General { wasm, structopt( long, - short = "n", + short = 'n', default_value = "2", env = "SERVER_THREADS_MULTIPLIER" ) @@ -65,7 +65,7 @@ pub struct General { not(wasm), structopt( long, - short = "b", + short = 'b', default_value = "512", env = "SERVER_MAX_BLOCKING_THREADS" ) @@ -74,7 +74,7 @@ pub struct General { wasm, structopt( long, - short = "b", + short = 'b', default_value = "20", env = "SERVER_MAX_BLOCKING_THREADS" ) @@ -82,7 +82,7 @@ pub struct General { /// Maximum number of blocking threads pub max_blocking_threads: usize, - #[structopt(long, short = "d", default_value = "./public", env = "SERVER_ROOT")] + #[structopt(long, short = 'd', default_value = "./public", env = "SERVER_ROOT")] /// Root directory path of static files. pub root: PathBuf, @@ -106,13 +106,13 @@ pub struct General { /// HTML file path that is used for GET requests when the requested path doesn't exist. The fallback page is served with a 200 status code, useful when using client routers. If the path is not specified or simply doesn't exist then this feature will not be active. pub page_fallback: Option, - #[structopt(long, short = "g", default_value = "error", env = "SERVER_LOG_LEVEL")] + #[structopt(long, short = 'g', default_value = "error", env = "SERVER_LOG_LEVEL")] /// Specify a logging level in lower case. Values: error, warn, info, debug or trace pub log_level: String, #[structopt( long, - short = "c", + short = 'c', default_value = "", env = "SERVER_CORS_ALLOW_ORIGINS" )] @@ -121,7 +121,7 @@ pub struct General { #[structopt( long, - short = "j", + short = 'j', default_value = "origin, content-type", env = "SERVER_CORS_ALLOW_HEADERS" )] @@ -138,7 +138,7 @@ pub struct General { #[structopt( long, - short = "t", + short = 't', parse(try_from_str), default_value = "false", env = "SERVER_HTTP2_TLS" @@ -148,13 +148,13 @@ pub struct General { /// Enable HTTP/2 with TLS support. pub http2: bool, - #[structopt(long, required_if("http2", "true"), env = "SERVER_HTTP2_TLS_CERT")] + #[structopt(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_CERT")] #[cfg(feature = "http2")] #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// Specify the file path to read the certificate. pub http2_tls_cert: Option, - #[structopt(long, required_if("http2", "true"), env = "SERVER_HTTP2_TLS_KEY")] + #[structopt(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_KEY")] #[cfg(feature = "http2")] #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// Specify the file path to read the private key. @@ -162,42 +162,46 @@ pub struct General { #[structopt( long, - required_if("http2", "true"), + requires_if("true", "http2"), parse(try_from_str), default_value = "false", env = "SERVER_HTTPS_REDIRECT" )] #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// Redirect all requests with scheme "http" to "https" for the current server instance. It depends on "http2" to be enabled. pub https_redirect: bool, #[structopt( long, - required_if("https_redirect", "true"), + requires_if("true", "https-redirect"), default_value = "localhost", env = "HTTPS_REDIRECT_HOST" )] #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// Canonical host name or IP of the HTTPS (HTTPS/2) server. It depends on "https_redirect" to be enabled. pub https_redirect_host: String, #[structopt( long, - required_if("https_redirect", "true"), + requires_if("true", "https-redirect"), default_value = "80", env = "HTTPS_REDIRECT_FROM_PORT" )] #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// HTTP host port where the redirect server will listen for requests to redirect them to HTTPS. It depends on "https_redirect" to be enabled. pub https_redirect_from_port: u16, #[structopt( long, - required_if("https_redirect", "true"), + requires_if("true", "https-redirect"), default_value = "localhost", env = "HTTPS_REDIRECT_FROM_HOSTS" )] #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] /// List of host names or IPs allowed to redirect from. HTTP requests must contain the HTTP 'Host' header and match against this list. It depends on "https_redirect" to be enabled. pub https_redirect_from_hosts: String, @@ -205,7 +209,7 @@ pub struct General { #[cfg_attr(docsrs, doc(cfg(feature = "compression")))] #[structopt( long, - short = "x", + short = 'x', parse(try_from_str), default_value = "true", env = "SERVER_COMPRESSION" @@ -227,7 +231,7 @@ pub struct General { #[structopt( long, - short = "z", + short = 'z', parse(try_from_str), default_value = "false", env = "SERVER_DIRECTORY_LISTING" @@ -237,7 +241,7 @@ pub struct General { #[structopt( long, - required_if("directory_listing", "true"), + required_if_eq("directory-listing", "true"), default_value = "6", env = "SERVER_DIRECTORY_LISTING_ORDER" )] @@ -246,8 +250,7 @@ pub struct General { #[structopt( long, - required_if("directory_listing", "true"), - possible_values = &DirListFmt::variants(), + required_if_eq("directory-listing", "true"), default_value = "html", env = "SERVER_DIRECTORY_LISTING_FORMAT", case_insensitive = true @@ -258,8 +261,7 @@ pub struct General { #[structopt( long, parse(try_from_str), - required_if("http2", "true"), - default_value_if("http2", Some("true"), "true"), + default_value_if("http2", Some("true"), Some("true")), default_value = "false", env = "SERVER_SECURITY_HEADERS" )] @@ -270,7 +272,7 @@ pub struct General { #[structopt( long, - short = "e", + short = 'e', parse(try_from_str), default_value = "true", env = "SERVER_CACHE_CONTROL_HEADERS" @@ -282,11 +284,11 @@ pub struct General { #[structopt(long, default_value = "", env = "SERVER_BASIC_AUTH")] pub basic_auth: String, - #[structopt(long, short = "q", default_value = "0", env = "SERVER_GRACE_PERIOD")] + #[structopt(long, short = 'q', default_value = "0", env = "SERVER_GRACE_PERIOD")] /// Defines a grace period in seconds after a `SIGTERM` signal is caught which will delay the server before to shut it down gracefully. The maximum value is 255 seconds. pub grace_period: u8, - #[structopt(long, short = "w", env = "SERVER_CONFIG_FILE")] + #[structopt(long, short = 'w', env = "SERVER_CONFIG_FILE")] /// Server TOML configuration file path. pub config_file: Option, @@ -323,7 +325,7 @@ pub struct General { #[cfg(windows)] #[structopt( long, - short = "s", + short = 's', parse(try_from_str), default_value = "false", env = "SERVER_WINDOWS_SERVICE" diff --git a/src/settings/mod.rs b/src/settings/mod.rs index 51cacaf..bf94bd8 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -6,10 +6,10 @@ //! Module that provides all settings of SWS. //! +use clap::StructOpt; use globset::{Glob, GlobMatcher}; use headers::HeaderMap; use hyper::StatusCode; -use structopt::StructOpt; use crate::{Context, Result}; -- libgit2 1.7.2