diff --git a/Cargo.lock b/Cargo.lock index b382b93..d5501ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,15 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.61" @@ -555,13 +546,48 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term", + "bitflags", + "textwrap 0.11.0", + "unicode-width", +] + +[[package]] +name = "clap" +version = "3.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" +dependencies = [ "atty", "bitflags", - "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", + "textwrap 0.15.0", +] + +[[package]] +name = "clap_derive" +version = "3.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[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]] @@ -671,7 +697,7 @@ checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast 0.3.0", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -830,7 +856,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn", ] @@ -963,7 +989,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro2", "quote", "syn", @@ -1326,15 +1352,6 @@ dependencies = [ "http", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" @@ -1728,6 +1745,7 @@ version = "0.10.1" dependencies = [ "anyhow", "assert_cmd", + "clap 3.2.17", "console", "const_format", "csv", @@ -1750,7 +1768,6 @@ dependencies = [ "secrecy", "serde", "serde_json", - "structopt", "supports-color", "tabled", "tempfile", @@ -2104,6 +2121,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + [[package]] name = "pad" version = "0.1.6" @@ -2917,7 +2940,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "410b26ed97440d90ced3e2488c868d56a86e2064f5d7d6f417909b286afe25e5" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro2", "quote", "syn", @@ -2974,42 +2997,12 @@ dependencies = [ "quote", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.26" -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 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "supports-color" version = "1.3.0" @@ -3048,7 +3041,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9ee618502f497abf593e1c5c9577f34775b111480009ffccd7ad70d23fcaba8" dependencies = [ - "heck 0.4.0", + "heck", "proc-macro-error", "proc-macro2", "quote", @@ -3080,6 +3073,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.1.17" @@ -3105,6 +3107,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "thiserror" version = "1.0.32" @@ -3428,12 +3436,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-width" version = "0.1.9" @@ -3496,12 +3498,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/README.md b/README.md index a449f87..d2cb3f1 100644 --- a/README.md +++ b/README.md @@ -208,65 +208,137 @@ See below for a full list. ```ignore USAGE: - lychee [FLAGS] [OPTIONS] ... - -FLAGS: - --cache Use request cache stored on disk at `.lycheecache` - --dump Don't perform any link checking. Instead, dump all the links extracted from inputs that - would be checked - -E, --exclude-all-private Exclude all private IPs from checking. - Equivalent to `--exclude-private --exclude-link-local --exclude-loopback` - --exclude-link-local Exclude link-local IP address range from checking - --exclude-loopback Exclude loopback IP address range and localhost from checking - --exclude-mail Exclude all mail addresses from checking - --exclude-private Exclude private IP address ranges from checking - --glob-ignore-case Ignore case when expanding filesystem path glob inputs - --help Prints help information - --include-verbatim Find links in verbatim sections like `pre`- and `code` blocks - -i, --insecure Proceed for server connections considered insecure (invalid TLS) - -n, --no-progress Do not show progress bar. - This is recommended for non-interactive shells (e.g. for continuous integration) - --offline Only check local files and block network requests - --require-https When HTTPS is available, treat HTTP links as errors - --skip-missing Skip missing input files (default is to error if they don't exist) - -V, --version Prints version information - -v, --verbose Verbose program output - -OPTIONS: - -a, --accept Comma-separated list of accepted status codes for valid links - -b, --base Base URL or website root directory to check relative URLs e.g. - https://example.com or `/path/to/public` - --basic-auth Basic authentication support. E.g. `username:password` - -c, --config Configuration file to use [default: ./lychee.toml] - --exclude ... Exclude URLs from checking (supports regex) - --exclude-file ... Deprecated; use `--exclude-path` instead - --exclude-path ... Exclude file path from getting checked - -f, --format Output format of final status report (compact, detailed, json, markdown) - [default: compact] - --github-token GitHub API token to use when checking github.com links, to avoid rate - limiting [env: GITHUB_TOKEN] - -h, --headers ... Custom request headers - --include ... URLs to check (supports regex). Has preference over all excludes - --max-cache-age Discard all cached requests older than this duration [default: 1d] - --max-concurrency Maximum number of concurrent network requests [default: 128] - -m, --max-redirects Maximum number of allowed redirects [default: 5] - --max-retries Maximum number of retries per request [default: 3] - -X, --method Request method [default: get] - -o, --output Output file of status report - --remap ... Remap URI matching pattern to different URI - -r, --retry-wait-time Minimum wait time in seconds between retries of failed requests [default: - 1] - -s, --scheme ... Only test links with the given schemes (e.g. http and https) - -T, --threads Number of threads to utilize. Defaults to number of cores available to - the system - -t, --timeout Website timeout in seconds from connect to response finished [default: - 20] - -u, --user-agent User agent [default: lychee/0.10.1] + lychee [OPTIONS] ... ARGS: - ... The inputs (where to get links to check from). These can be: files (e.g. `README.md`), file globs - (e.g. `"~/git/*/README.md"`), remote URLs (e.g. `https://example.com/README.md`) or standard - input (`-`). NOTE: Use `--` to separate inputs from options that allow multiple arguments + ... The inputs (where to get links to check from). These can be: files (e.g. + `README.md`), file globs (e.g. `"~/git/*/README.md"`), remote URLs (e.g. + `https://example.com/README.md`) or standard input (`-`). NOTE: Use `--` to + separate inputs from options that allow multiple arguments + +OPTIONS: + -a, --accept + Comma-separated list of accepted status codes for valid links + + -b, --base + Base URL or website root directory to check relative URLs e.g. https://example.com or + `/path/to/public` + + --basic-auth + Basic authentication support. E.g. `username:password` + + -c, --config + Configuration file to use [default: ./lychee.toml] + + --cache + Use request cache stored on disk at `.lycheecache` + + --dump + Don't perform any link checking. Instead, dump all the links extracted from inputs that + would be checked + + -E, --exclude-all-private + Exclude all private IPs from checking. + Equivalent to `--exclude-private --exclude-link-local --exclude-loopback` + + --exclude + Exclude URLs from checking (supports regex) + + --exclude-file + Deprecated; use `--exclude-path` instead + + --exclude-link-local + Exclude link-local IP address range from checking + + --exclude-loopback + Exclude loopback IP address range and localhost from checking + + --exclude-mail + Exclude all mail addresses from checking + + --exclude-path + Exclude file path from getting checked + + --exclude-private + Exclude private IP address ranges from checking + + -f, --format + Output format of final status report (compact, detailed, json, markdown) [default: + compact] + + --github-token + GitHub API token to use when checking github.com links, to avoid rate limiting [env: + GITHUB_TOKEN] + + --glob-ignore-case + Ignore case when expanding filesystem path glob inputs + + -h, --headers + Custom request headers + + --help + Print help information + + -i, --insecure + Proceed for server connections considered insecure (invalid TLS) + + --include + URLs to check (supports regex). Has preference over all excludes + + --include-verbatim + Find links in verbatim sections like `pre`- and `code` blocks + + -m, --max-redirects + Maximum number of allowed redirects [default: 5] + + --max-cache-age + Discard all cached requests older than this duration [default: 1d] + + --max-concurrency + Maximum number of concurrent network requests [default: 128] + + --max-retries + Maximum number of retries per request [default: 3] + + -n, --no-progress + Do not show progress bar. + This is recommended for non-interactive shells (e.g. for continuous integration) + + -o, --output + Output file of status report + + --offline + Only check local files and block network requests + + -r, --retry-wait-time + Minimum wait time in seconds between retries of failed requests [default: 1] + + --remap + Remap URI matching pattern to different URI + + --require-https + When HTTPS is available, treat HTTP links as errors + + -s, --scheme + Only test links with the given schemes (e.g. http and https) + + --skip-missing + Skip missing input files (default is to error if they don't exist) + + -t, --timeout + Website timeout in seconds from connect to response finished [default: 20] + + -T, --threads + Number of threads to utilize. Defaults to number of cores available to the system + + -u, --user-agent + User agent [default: lychee/0.10.1] + + -v, --verbose + Verbose program output + + -X, --method + Request method [default: get] ``` ### Exit codes diff --git a/lychee-bin/Cargo.toml b/lychee-bin/Cargo.toml index daf0ec2..142ebc8 100644 --- a/lychee-bin/Cargo.toml +++ b/lychee-bin/Cargo.toml @@ -35,7 +35,6 @@ reqwest = { version = "0.11.11", features = ["gzip"] } ring = "0.16.20" serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.83" -structopt = "0.3.26" tabled = "0.8.0" tokio = { version = "1.20.1", features = ["full"] } toml = "0.5.9" @@ -50,6 +49,10 @@ secrecy = { version = "0.8.0", features = ["serde"] } supports-color = "1.3.0" log = "0.4.17" +[dependencies.clap] +version = "3.2.17" +features = ["env", "derive"] + [dev-dependencies] assert_cmd = "2.0.4" predicates = "2.1.1" diff --git a/lychee-bin/src/main.rs b/lychee-bin/src/main.rs index 1d1908d..4bdbf73 100644 --- a/lychee-bin/src/main.rs +++ b/lychee-bin/src/main.rs @@ -63,13 +63,13 @@ use std::io::{self, BufRead, BufReader, ErrorKind, Write}; use std::sync::Arc; use anyhow::{Context, Error, Result}; +use clap::Parser; use color::YELLOW; use commands::CommandParams; use formatters::response::ResponseFormatter; use log::warn; use openssl_sys as _; // required for vendored-openssl feature use ring as _; // required for apple silicon -use structopt::StructOpt; use lychee_lib::Collector; @@ -130,7 +130,7 @@ fn read_lines(file: &File) -> Result> { /// Merge all provided config options into one This includes a potential config /// file, command-line- and environment variables fn load_config() -> Result { - let mut opts = LycheeOptions::from_args(); + let mut opts = LycheeOptions::parse(); // Load a potentially existing config file and merge it into the config from // the CLI @@ -202,6 +202,7 @@ fn run_main() -> Result { use std::process::exit; let opts = load_config()?; + let runtime = match opts.config.threads { Some(threads) => { // We define our own runtime instead of the `tokio::main` attribute diff --git a/lychee-bin/src/options.rs b/lychee-bin/src/options.rs index 661e202..3d9da32 100644 --- a/lychee-bin/src/options.rs +++ b/lychee-bin/src/options.rs @@ -1,5 +1,6 @@ use crate::parse::{parse_base, parse_statuscodes}; use anyhow::{anyhow, Context, Error, Result}; +use clap::StructOpt; use const_format::{concatcp, formatcp}; use lychee_lib::{ Base, Input, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_WAIT_TIME_SECS, @@ -8,7 +9,6 @@ use lychee_lib::{ use secrecy::{ExposeSecret, SecretString}; use serde::Deserialize; use std::{collections::HashSet, fs, io::ErrorKind, path::PathBuf, str::FromStr, time::Duration}; -use structopt::StructOpt; pub(crate) const LYCHEE_IGNORE_FILE: &str = ".lycheeignore"; pub(crate) const LYCHEE_CACHE_FILE: &str = ".lycheecache"; @@ -17,14 +17,14 @@ const DEFAULT_METHOD: &str = "get"; const DEFAULT_MAX_CACHE_AGE: &str = "1d"; const DEFAULT_MAX_CONCURRENCY: usize = 128; -// this exists because structopt requires `&str` type values for defaults +// this exists because clap requires `&str` type values for defaults // whereas serde expects owned `String` types // (we can't use e.g. `TIMEOUT` or `timeout()` which gets created for serde) const MAX_CONCURRENCY_STR: &str = concatcp!(DEFAULT_MAX_CONCURRENCY); const MAX_CACHE_AGE_STR: &str = concatcp!(DEFAULT_MAX_CACHE_AGE); const MAX_REDIRECTS_STR: &str = concatcp!(DEFAULT_MAX_REDIRECTS); const MAX_RETRIES_STR: &str = concatcp!(DEFAULT_MAX_RETRIES); -const STRUCTOPT_HELP_MSG_CACHE: &str = formatcp!( +const HELP_MSG_CACHE: &str = formatcp!( "Use request cache stored on disk at `{}`", LYCHEE_CACHE_FILE, ); @@ -96,7 +96,7 @@ macro_rules! fold_in { } #[derive(Debug, StructOpt)] -#[structopt( +#[clap( name = "lychee", about = "A glorious link checker.\n\nProject home page: https://github.com/lycheeverse/lychee" )] @@ -105,14 +105,14 @@ pub(crate) struct LycheeOptions { /// These can be: files (e.g. `README.md`), file globs (e.g. `"~/git/*/README.md"`), /// remote URLs (e.g. `https://example.com/README.md`) or standard input (`-`). /// NOTE: Use `--` to separate inputs from options that allow multiple arguments. - #[structopt(name = "inputs", required = true)] + #[clap(name = "inputs", required = true)] raw_inputs: Vec, /// Configuration file to use - #[structopt(short, long = "config", default_value = "./lychee.toml")] + #[clap(short, long = "config", default_value = "./lychee.toml")] pub(crate) config_file: String, - #[structopt(flatten)] + #[clap(flatten)] pub(crate) config: Config, } @@ -139,23 +139,23 @@ impl LycheeOptions { #[derive(Debug, Deserialize, StructOpt, Clone)] pub(crate) struct Config { /// Verbose program output - #[structopt(short, long)] + #[clap(short, long)] #[serde(default)] pub(crate) verbose: bool, /// Do not show progress bar. /// This is recommended for non-interactive shells (e.g. for continuous integration) - #[structopt(short, long, verbatim_doc_comment)] + #[clap(short, long, verbatim_doc_comment)] #[serde(default)] pub(crate) no_progress: bool, - #[structopt(help = &STRUCTOPT_HELP_MSG_CACHE)] - #[structopt(long)] + #[clap(help = HELP_MSG_CACHE)] + #[clap(long)] #[serde(default)] pub(crate) cache: bool, /// Discard all cached requests older than this duration - #[structopt( + #[clap( long, parse(try_from_str = humantime::parse_duration), default_value = &MAX_CACHE_AGE_STR @@ -166,171 +166,171 @@ pub(crate) struct Config { /// Don't perform any link checking. /// Instead, dump all the links extracted from inputs that would be checked - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) dump: bool, /// Maximum number of allowed redirects - #[structopt(short, long, default_value = &MAX_REDIRECTS_STR)] + #[clap(short, long, default_value = &MAX_REDIRECTS_STR)] #[serde(default = "max_redirects")] pub(crate) max_redirects: usize, /// Maximum number of retries per request - #[structopt(long, default_value = &MAX_RETRIES_STR)] + #[clap(long, default_value = &MAX_RETRIES_STR)] #[serde(default = "max_retries")] pub(crate) max_retries: u64, /// Maximum number of concurrent network requests - #[structopt(long, default_value = &MAX_CONCURRENCY_STR)] + #[clap(long, default_value = &MAX_CONCURRENCY_STR)] #[serde(default = "max_concurrency")] pub(crate) max_concurrency: usize, /// Number of threads to utilize. /// Defaults to number of cores available to the system - #[structopt(short = "T", long)] + #[clap(short = 'T', long)] #[serde(default)] pub(crate) threads: Option, /// User agent - #[structopt(short, long, default_value = DEFAULT_USER_AGENT)] + #[clap(short, long, default_value = DEFAULT_USER_AGENT)] #[serde(default = "user_agent")] pub(crate) user_agent: String, /// Proceed for server connections considered insecure (invalid TLS) - #[structopt(short, long)] + #[clap(short, long)] #[serde(default)] pub(crate) insecure: bool, /// Only test links with the given schemes (e.g. http and https) - #[structopt(short, long)] + #[clap(short, long)] #[serde(default)] pub(crate) scheme: Vec, /// Only check local files and block network requests. - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) offline: bool, /// URLs to check (supports regex). Has preference over all excludes. - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) include: Vec, /// Exclude URLs from checking (supports regex) - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude: Vec, /// Deprecated; use `--exclude-path` instead - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_file: Vec, /// Exclude file path from getting checked. - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_path: Vec, /// Exclude all private IPs from checking. /// Equivalent to `--exclude-private --exclude-link-local --exclude-loopback` - #[structopt(short = "E", long, verbatim_doc_comment)] + #[clap(short = 'E', long, verbatim_doc_comment)] #[serde(default)] pub(crate) exclude_all_private: bool, /// Exclude private IP address ranges from checking - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_private: bool, /// Exclude link-local IP address range from checking - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_link_local: bool, /// Exclude loopback IP address range and localhost from checking - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_loopback: bool, /// Exclude all mail addresses from checking - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) exclude_mail: bool, /// Remap URI matching pattern to different URI #[serde(default)] - #[structopt(long)] + #[clap(long)] pub(crate) remap: Vec, /// Custom request headers - #[structopt(short, long)] + #[clap(short, long)] #[serde(default)] pub(crate) headers: Vec, /// Comma-separated list of accepted status codes for valid links - #[structopt(short, long, parse(try_from_str = parse_statuscodes))] + #[clap(short, long, parse(try_from_str = parse_statuscodes))] #[serde(default)] pub(crate) accept: Option>, /// Website timeout in seconds from connect to response finished - #[structopt(short, long, default_value = &TIMEOUT_STR)] + #[clap(short, long, default_value = &TIMEOUT_STR)] #[serde(default = "timeout")] pub(crate) timeout: usize, /// Minimum wait time in seconds between retries of failed requests - #[structopt(short, long, default_value = &RETRY_WAIT_TIME_STR)] + #[clap(short, long, default_value = &RETRY_WAIT_TIME_STR)] #[serde(default = "retry_wait_time")] pub(crate) retry_wait_time: usize, /// Request method // Using `-X` as a short param similar to curl - #[structopt(short = "X", long, default_value = DEFAULT_METHOD)] + #[clap(short = 'X', long, default_value = DEFAULT_METHOD)] #[serde(default = "method")] pub(crate) method: String, /// Base URL or website root directory to check relative URLs /// e.g. https://example.com or `/path/to/public` - #[structopt(short, long, parse(try_from_str = parse_base))] + #[clap(short, long, parse(try_from_str = parse_base))] #[serde(default)] pub(crate) base: Option, /// Basic authentication support. E.g. `username:password` - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) basic_auth: Option, /// GitHub API token to use when checking github.com links, to avoid rate limiting - #[structopt(long, env = "GITHUB_TOKEN", hide_env_values = true)] + #[clap(long, env = "GITHUB_TOKEN", hide_env_values = true)] #[serde(default)] pub(crate) github_token: Option, /// Skip missing input files (default is to error if they don't exist) - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) skip_missing: bool, /// Find links in verbatim sections like `pre`- and `code` blocks - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) include_verbatim: bool, /// Ignore case when expanding filesystem path glob inputs - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) glob_ignore_case: bool, /// Output file of status report - #[structopt(short, long, parse(from_os_str))] + #[clap(short, long, parse(from_os_str))] #[serde(default)] pub(crate) output: Option, /// Output format of final status report (compact, detailed, json, markdown) - #[structopt(short, long, default_value = "compact")] + #[clap(short, long, default_value = "compact")] #[serde(default)] pub(crate) format: Format, /// When HTTPS is available, treat HTTP links as errors - #[structopt(long)] + #[clap(long)] #[serde(default)] pub(crate) require_https: bool, }