Revise command line value names
Make command line value names make sense in context. For example, `--announce URL` instead of `--announce ANNOUNCE`. type: documentation
This commit is contained in:
parent
cba238470d
commit
fa6d4e6ad0
|
@ -41,7 +41,7 @@ pub(crate) use url::{Host, Url};
|
|||
pub(crate) use walkdir::WalkDir;
|
||||
|
||||
// modules
|
||||
pub(crate) use crate::{consts, error, use_color};
|
||||
pub(crate) use crate::{consts, error};
|
||||
|
||||
// traits
|
||||
pub(crate) use crate::{
|
||||
|
|
16
src/lint.rs
16
src/lint.rs
|
@ -6,14 +6,16 @@ pub(crate) enum Lint {
|
|||
SmallPieceLength,
|
||||
}
|
||||
|
||||
const UNEVEN_PIECE_LENGTH: &str = "uneven-piece-length";
|
||||
const SMALL_PIECE_LENGTH: &str = "small-piece-length";
|
||||
|
||||
impl Lint {
|
||||
const SMALL_PIECE_LENGTH: &'static str = "small-piece-length";
|
||||
const UNEVEN_PIECE_LENGTH: &'static str = "uneven-piece-length";
|
||||
pub(crate) const VALUES: &'static [&'static str] =
|
||||
&[Self::SMALL_PIECE_LENGTH, Self::UNEVEN_PIECE_LENGTH];
|
||||
|
||||
pub(crate) fn name(self) -> &'static str {
|
||||
match self {
|
||||
Self::UnevenPieceLength => UNEVEN_PIECE_LENGTH,
|
||||
Self::SmallPieceLength => SMALL_PIECE_LENGTH,
|
||||
Self::SmallPieceLength => Self::SMALL_PIECE_LENGTH,
|
||||
Self::UnevenPieceLength => Self::UNEVEN_PIECE_LENGTH,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +25,8 @@ impl FromStr for Lint {
|
|||
|
||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
||||
match text.replace('_', "-").to_lowercase().as_str() {
|
||||
UNEVEN_PIECE_LENGTH => Ok(Self::UnevenPieceLength),
|
||||
SMALL_PIECE_LENGTH => Ok(Self::SmallPieceLength),
|
||||
Self::SMALL_PIECE_LENGTH => Ok(Self::SmallPieceLength),
|
||||
Self::UNEVEN_PIECE_LENGTH => Ok(Self::UnevenPieceLength),
|
||||
_ => Err(Error::LintUnknown {
|
||||
text: text.to_string(),
|
||||
}),
|
||||
|
|
|
@ -13,13 +13,14 @@ pub(crate) struct Options {
|
|||
unstable: bool,
|
||||
#[structopt(
|
||||
long = "color",
|
||||
default_value = use_color::AUTO,
|
||||
value_name = "WHEN",
|
||||
default_value = UseColor::AUTO,
|
||||
set = ArgSettings::CaseInsensitive,
|
||||
possible_values = use_color::VALUES,
|
||||
help = "Print colorful output. When `auto`, the default, colored output is only enabled \
|
||||
if imdl detects that it is connected to a terminal, the `NO_COLOR` environment \
|
||||
variable is not set, and the `TERM` environment variable is not set with a \
|
||||
value of `dumb`.",
|
||||
possible_values = UseColor::VALUES,
|
||||
help = "Print colorful output according to `WHEN`. When `auto`, the default, colored output \
|
||||
is only enabled if imdl detects that it is connected to a terminal, the `NO_COLOR` \
|
||||
environment variable is not set, and the `TERM` environment variable is not set to \
|
||||
`dumb`.",
|
||||
)]
|
||||
pub(crate) use_color: UseColor,
|
||||
}
|
||||
|
|
|
@ -8,24 +8,27 @@ use crate::common::*;
|
|||
)]
|
||||
pub(crate) struct Create {
|
||||
#[structopt(
|
||||
name = "ANNOUNCE",
|
||||
long = "announce",
|
||||
value_name = "URL",
|
||||
required(true),
|
||||
help = "Use `ANNOUNCE` as the primary tracker announce URL. To supply multiple announce URLs, \
|
||||
also use `--announce-tier`."
|
||||
help = "Use `URL` as the primary tracker announce URL. To supply multiple announce URLs, also \
|
||||
use `--announce-tier`."
|
||||
)]
|
||||
announce: Url,
|
||||
#[structopt(
|
||||
name = "ALLOW",
|
||||
long = "allow",
|
||||
help = "Use `ANNOUNCE` as the primary tracker announce URL. To supply multiple announce URLs, \
|
||||
also use `--announce-tier`."
|
||||
value_name = "LINT",
|
||||
possible_values = Lint::VALUES,
|
||||
help = "Allow `LINT`. Lints check for conditions which, although permitted, are not usually \
|
||||
desirable. For example, piece length can be any non-zero value, but probably \
|
||||
shouldn't be below 16 KiB. The lint `small-piece-size` checks for this, and \
|
||||
`--allow small-piece-size` can be used to disable this check.",
|
||||
)]
|
||||
allowed_lints: Vec<Lint>,
|
||||
#[structopt(
|
||||
long = "announce-tier",
|
||||
name = "ANNOUNCE-TIER",
|
||||
help = "Add `ANNOUNCE-TIER` to list of tracker announce tiers. Each instance adds a new \
|
||||
value_name = "URL-LIST",
|
||||
help = "Use `URL-LIST` as a tracker announce tier. Each instance adds a new \
|
||||
tier. To add multiple trackers to a given tier, separate their announce URLs \
|
||||
with commas:\n\
|
||||
\n\
|
||||
|
@ -41,15 +44,15 @@ pub(crate) struct Create {
|
|||
)]
|
||||
announce_tiers: Vec<String>,
|
||||
#[structopt(
|
||||
name = "COMMENT",
|
||||
long = "comment",
|
||||
help = "Include `COMMENT` in generated `.torrent` file. Stored under `comment` key of \
|
||||
top-level metainfo dictionary."
|
||||
value_name = "TEXT",
|
||||
help = "Include `TEXT` as the comment for generated `.torrent` file. Stored under `comment` \
|
||||
key of top-level metainfo dictionary."
|
||||
)]
|
||||
comment: Option<String>,
|
||||
#[structopt(
|
||||
name = "NODE",
|
||||
long = "dht-node",
|
||||
value_name = "NODE",
|
||||
help = "Add DHT bootstrap node `NODE` to torrent. `NODE` should be in the form `HOST:PORT`, \
|
||||
where `HOST` is a domain name, an IPv4 address, or an IPv6 address surrounded by \
|
||||
brackets. May be given more than once to add multiple bootstrap nodes. Examples:
|
||||
|
@ -59,95 +62,85 @@ pub(crate) struct Create {
|
|||
)]
|
||||
dht_nodes: Vec<Node>,
|
||||
#[structopt(
|
||||
name = "FOLLOW-SYMLINKS",
|
||||
long = "follow-symlinks",
|
||||
help = "Follow symlinks in torrent input. By default, symlinks to files and directories are \
|
||||
not included in torrent contents."
|
||||
)]
|
||||
follow_symlinks: bool,
|
||||
#[structopt(
|
||||
name = "FORCE",
|
||||
long = "force",
|
||||
help = "Overwrite the destination `.torrent` file, if it exists."
|
||||
)]
|
||||
force: bool,
|
||||
#[structopt(
|
||||
name = "GLOB",
|
||||
long = "glob",
|
||||
value_name = "GLOB",
|
||||
help = "Include or exclude files that match `GLOB`. Multiple glob may be provided, with the \
|
||||
last one taking precedence. Precede a glob with a ! to exclude it."
|
||||
last one taking precedence. Precede a glob with `!` to exclude it."
|
||||
)]
|
||||
globs: Vec<String>,
|
||||
#[structopt(
|
||||
name = "INCLUDE-HIDDEN",
|
||||
long = "include-hidden",
|
||||
help = "Include hidden files that would otherwise be skipped, such as files that start with a \
|
||||
`.`, and files hidden by file attributes on macOS and Windows."
|
||||
)]
|
||||
include_hidden: bool,
|
||||
#[structopt(
|
||||
name = "INCLUDE-JUNK",
|
||||
long = "include-junk",
|
||||
help = "Include junk files that would otherwise be skipped."
|
||||
)]
|
||||
include_junk: bool,
|
||||
#[structopt(
|
||||
name = "INPUT",
|
||||
long = "input",
|
||||
help = "Read torrent contents from `INPUT`. If `INPUT` is a file, torrent will be a \
|
||||
single-file torrent, otherwise if `INPUT` is a directory, torrent will be a \
|
||||
multi-file torrent.",
|
||||
value_name = "PATH",
|
||||
help = "Read torrent contents from `PATH`. If `PATH` is a file, torrent will be a single-file \
|
||||
torrent, if `PATH` is a directory, torrent will be a multi-file torrent.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
input: PathBuf,
|
||||
#[structopt(
|
||||
name = "MD5SUM",
|
||||
long = "md5sum",
|
||||
help = "Include MD5 checksum of each file in the torrent. N.B. MD5 is cryptographically \
|
||||
broken and only suitable for checking for accidental corruption."
|
||||
)]
|
||||
md5sum: bool,
|
||||
#[structopt(
|
||||
name = "NAME",
|
||||
long = "name",
|
||||
help = "Set name of torrent to `NAME`. Defaults to the filename of `--input`."
|
||||
value_name = "TEXT",
|
||||
help = "Set name of torrent to `TEXT`. Defaults to the filename of the argument to `--input`."
|
||||
)]
|
||||
name: Option<String>,
|
||||
#[structopt(
|
||||
name = "NO-CREATED-BY",
|
||||
long = "no-created-by",
|
||||
help = "Do not populate `created by` key of generated torrent with imdl version information."
|
||||
)]
|
||||
no_created_by: bool,
|
||||
#[structopt(
|
||||
name = "NO-CREATION-DATE",
|
||||
long = "no-creation-date",
|
||||
help = "Do not populate `creation date` key of generated torrent with current time."
|
||||
)]
|
||||
no_creation_date: bool,
|
||||
#[structopt(
|
||||
name = "OPEN",
|
||||
long = "open",
|
||||
help = "Open `.torrent` file after creation. Uses `xdg-open`, `gnome-open`, or `kde-open` on \
|
||||
Linux; `open` on macOS; and `cmd /C start on Windows"
|
||||
)]
|
||||
open: bool,
|
||||
#[structopt(
|
||||
name = "OUTPUT",
|
||||
long = "output",
|
||||
help = "Save `.torrent` file to `OUTPUT`, or `-` for standard output. Defaults to \
|
||||
`$INPUT.torrent`.",
|
||||
value_name = "TARGET",
|
||||
help = "Save `.torrent` file to `TARGET`, or print to standard output if `TARGET` is `-`. \
|
||||
Defaults to `$INPUT.torrent`.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
output: Option<Target>,
|
||||
#[structopt(
|
||||
name = "PIECE-LENGTH",
|
||||
long = "piece-length",
|
||||
help = "Set piece length to `PIECE-LENGTH` bytes. Accepts SI units, e.g. kib, mib, and gib."
|
||||
value_name = "BYTES",
|
||||
help = "Set piece length to `BYTES`. Accepts SI units, e.g. kib, mib, and gib."
|
||||
)]
|
||||
piece_length: Option<Bytes>,
|
||||
#[structopt(
|
||||
name = "PRIVATE",
|
||||
long = "private",
|
||||
help = "Set the `private` flag. Torrent clients that understand the flag and participate in \
|
||||
the swarm of a torrent with the flag set will only announce themselves to the \
|
||||
|
@ -157,10 +150,14 @@ pub(crate) struct Create {
|
|||
)]
|
||||
private: bool,
|
||||
#[structopt(
|
||||
name = "SOURCE",
|
||||
long = "source",
|
||||
help = "Include `SOURCE` in generated `.torrent` file. Stored under `info.source` key of \
|
||||
metainfo dictionary."
|
||||
value_name = "TEXT",
|
||||
help = "Set torrent source to `TEXT`. Stored under `source` key of info dictionary. This is \
|
||||
useful for keeping statistics from being mis-reported when participating in swarms \
|
||||
with the same contents, but with different trackers. When source is set to a unique \
|
||||
value for torrents with the same contents, torrent clients will treat them as \
|
||||
distinct torrents, and not share peers between them, and will correctly report \
|
||||
download and upload statistics to multiple trackers."
|
||||
)]
|
||||
source: Option<String>,
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ use crate::common::*;
|
|||
)]
|
||||
pub(crate) struct Show {
|
||||
#[structopt(
|
||||
name = "TORRENT",
|
||||
long = "input",
|
||||
help = "Show information about `TORRENT`.",
|
||||
value_name = "PATH",
|
||||
help = "Show information about torrent at `PATH`.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
input: PathBuf,
|
||||
|
|
|
@ -8,17 +8,17 @@ use crate::common::*;
|
|||
)]
|
||||
pub(crate) struct Stats {
|
||||
#[structopt(
|
||||
name = "COUNT",
|
||||
long = "limit",
|
||||
short = "l",
|
||||
help = "Stop after processing the first `COUNT` torrents. Useful when processing large \
|
||||
collections of `.torrent` files."
|
||||
value_name = "N",
|
||||
help = "Stop after processing `N` torrents. Useful when processing large collections of \
|
||||
`.torrent` files."
|
||||
)]
|
||||
limit: Option<u64>,
|
||||
#[structopt(
|
||||
name = "REGEX",
|
||||
long = "extract-pattern",
|
||||
short = "e",
|
||||
value_name = "REGEX",
|
||||
help = "Extract and display values under key paths that match `REGEX`. Subkeys of a \
|
||||
bencodeded dictionary are delimited by `/`, and values of a bencoded list are \
|
||||
delmited by `*`. For example, given the following bencoded dictionary `{\"foo\": \
|
||||
|
@ -28,10 +28,10 @@ pub(crate) struct Stats {
|
|||
)]
|
||||
extract_patterns: Vec<Regex>,
|
||||
#[structopt(
|
||||
name = "INPUT",
|
||||
long = "input",
|
||||
short = "i",
|
||||
help = "Search `INPUT` for torrents. May be a directory to search or a single torrent file.",
|
||||
value_name = "PATH",
|
||||
help = "Search `PATH` for torrents. May be a directory or a single torrent file.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
input: PathBuf,
|
||||
|
|
|
@ -8,16 +8,17 @@ use crate::common::*;
|
|||
)]
|
||||
pub(crate) struct Verify {
|
||||
#[structopt(
|
||||
name = "TORRENT",
|
||||
long = "metainfo",
|
||||
help = "Verify input data against torrent metainfo in `TORRENT`.",
|
||||
value_name = "FILE",
|
||||
help = "Verify torrent contents against torrent metainfo in `FILE`.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
metainfo: PathBuf,
|
||||
#[structopt(
|
||||
name = "INPUT",
|
||||
long = "input",
|
||||
help = "Verify `INPUT`. Defaults to `info.name` field of torrent metainfo.",
|
||||
value_name = "PATH",
|
||||
help = "Verify torrent contents at `PATH` against torrent metainfo. Defaults to `name` field \
|
||||
of torrent info dictionary.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
input: Option<PathBuf>,
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
use crate::common::*;
|
||||
|
||||
pub(crate) const AUTO: &str = "auto";
|
||||
pub(crate) const ALWAYS: &str = "always";
|
||||
pub(crate) const NEVER: &str = "never";
|
||||
|
||||
pub(crate) const VALUES: &[&str] = &[AUTO, ALWAYS, NEVER];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub(crate) enum UseColor {
|
||||
Auto,
|
||||
|
@ -13,14 +7,21 @@ pub(crate) enum UseColor {
|
|||
Never,
|
||||
}
|
||||
|
||||
impl UseColor {
|
||||
pub(crate) const ALWAYS: &'static str = "always";
|
||||
pub(crate) const AUTO: &'static str = "auto";
|
||||
pub(crate) const NEVER: &'static str = "never";
|
||||
pub(crate) const VALUES: &'static [&'static str] = &[Self::AUTO, Self::ALWAYS, Self::NEVER];
|
||||
}
|
||||
|
||||
impl FromStr for UseColor {
|
||||
type Err = Infallible;
|
||||
|
||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
||||
match text.to_lowercase().as_str() {
|
||||
AUTO => Ok(Self::Auto),
|
||||
ALWAYS => Ok(Self::Always),
|
||||
NEVER => Ok(Self::Never),
|
||||
Self::AUTO => Ok(Self::Auto),
|
||||
Self::ALWAYS => Ok(Self::Always),
|
||||
Self::NEVER => Ok(Self::Never),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -32,11 +33,20 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(UseColor::Auto, AUTO.parse().unwrap());
|
||||
assert_eq!(UseColor::Always, ALWAYS.parse().unwrap());
|
||||
assert_eq!(UseColor::Never, NEVER.parse().unwrap());
|
||||
assert_eq!(UseColor::Auto, AUTO.to_uppercase().parse().unwrap());
|
||||
assert_eq!(UseColor::Always, ALWAYS.to_uppercase().parse().unwrap());
|
||||
assert_eq!(UseColor::Never, NEVER.to_uppercase().parse().unwrap());
|
||||
assert_eq!(UseColor::Auto, UseColor::AUTO.parse().unwrap());
|
||||
assert_eq!(UseColor::Always, UseColor::ALWAYS.parse().unwrap());
|
||||
assert_eq!(UseColor::Never, UseColor::NEVER.parse().unwrap());
|
||||
assert_eq!(
|
||||
UseColor::Auto,
|
||||
UseColor::AUTO.to_uppercase().parse().unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
UseColor::Always,
|
||||
UseColor::ALWAYS.to_uppercase().parse().unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
UseColor::Never,
|
||||
UseColor::NEVER.to_uppercase().parse().unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user