mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 23:02:38 +00:00
Merge pull request #6174 from BenWiederhake/dev-all-partial-stringly-options
all: Accept shortcuts for stringly-enum options
This commit is contained in:
commit
652c65f71a
27 changed files with 565 additions and 177 deletions
|
@ -75,6 +75,9 @@ number of spaces representing a tab when determining the line length.
|
|||
GNU `ls` provides two ways to use a long listing format: `-l` and `--format=long`. We support a
|
||||
third way: `--long`.
|
||||
|
||||
GNU `ls --sort=VALUE` only supports special non-default sort orders.
|
||||
We support `--sort=name`, which makes it possible to override an earlier value.
|
||||
|
||||
## `du`
|
||||
|
||||
`du` allows `birth` and `creation` as values for the `--time` argument to show the creation time. It
|
||||
|
|
|
@ -37,8 +37,8 @@ use uucore::{backup_control, update_control};
|
|||
// requires these enum.
|
||||
pub use uucore::{backup_control::BackupMode, update_control::UpdateMode};
|
||||
use uucore::{
|
||||
format_usage, help_about, help_section, help_usage, prompt_yes, show_error, show_warning,
|
||||
util_name,
|
||||
format_usage, help_about, help_section, help_usage, prompt_yes,
|
||||
shortcut_value_parser::ShortcutValueParser, show_error, show_warning, util_name,
|
||||
};
|
||||
|
||||
use crate::copydir::copy_directory;
|
||||
|
@ -396,22 +396,14 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[
|
|||
"ownership",
|
||||
"timestamps",
|
||||
"context",
|
||||
"link",
|
||||
"links",
|
||||
"xattr",
|
||||
"all",
|
||||
];
|
||||
|
||||
#[cfg(not(unix))]
|
||||
static PRESERVABLE_ATTRIBUTES: &[&str] = &[
|
||||
"mode",
|
||||
"timestamps",
|
||||
"context",
|
||||
"link",
|
||||
"links",
|
||||
"xattr",
|
||||
"all",
|
||||
];
|
||||
static PRESERVABLE_ATTRIBUTES: &[&str] =
|
||||
&["mode", "timestamps", "context", "links", "xattr", "all"];
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
const MODE_ARGS: &[&str] = &[
|
||||
|
@ -543,7 +535,7 @@ pub fn uu_app() -> Command {
|
|||
.overrides_with_all(MODE_ARGS)
|
||||
.require_equals(true)
|
||||
.default_missing_value("always")
|
||||
.value_parser(["auto", "always", "never"])
|
||||
.value_parser(ShortcutValueParser::new(["auto", "always", "never"]))
|
||||
.num_args(0..=1)
|
||||
.help("control clone/CoW copies. See below"),
|
||||
)
|
||||
|
@ -559,9 +551,7 @@ pub fn uu_app() -> Command {
|
|||
.long(options::PRESERVE)
|
||||
.action(ArgAction::Append)
|
||||
.use_value_delimiter(true)
|
||||
.value_parser(clap::builder::PossibleValuesParser::new(
|
||||
PRESERVABLE_ATTRIBUTES,
|
||||
))
|
||||
.value_parser(ShortcutValueParser::new(PRESERVABLE_ATTRIBUTES))
|
||||
.num_args(0..)
|
||||
.require_equals(true)
|
||||
.value_name("ATTR_LIST")
|
||||
|
@ -655,7 +645,7 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::SPARSE)
|
||||
.long(options::SPARSE)
|
||||
.value_name("WHEN")
|
||||
.value_parser(["never", "auto", "always"])
|
||||
.value_parser(ShortcutValueParser::new(["never", "auto", "always"]))
|
||||
.help("control creation of sparse files. See below"),
|
||||
)
|
||||
// TODO: implement the following args
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// file that was distributed with this source code.
|
||||
|
||||
use chrono::{DateTime, Local};
|
||||
use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||
use clap::{builder::PossibleValue, crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||
use glob::Pattern;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
|
@ -30,6 +30,7 @@ use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError};
|
|||
use uucore::line_ending::LineEnding;
|
||||
use uucore::parse_glob;
|
||||
use uucore::parse_size::{parse_size_u64, ParseSizeError};
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage, show, show_error, show_warning};
|
||||
#[cfg(windows)]
|
||||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
|
@ -1040,7 +1041,11 @@ pub fn uu_app() -> Command {
|
|||
.value_name("WORD")
|
||||
.require_equals(true)
|
||||
.num_args(0..)
|
||||
.value_parser(["atime", "access", "use", "ctime", "status", "birth", "creation"])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("atime").alias("access").alias("use"),
|
||||
PossibleValue::new("ctime").alias("status"),
|
||||
PossibleValue::new("creation").alias("birth"),
|
||||
]))
|
||||
.help(
|
||||
"show time of the last modification of any file in the \
|
||||
directory, or any of its subdirectories. If WORD is given, show time as WORD instead \
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm stringly
|
||||
|
||||
use clap::{
|
||||
builder::{NonEmptyStringValueParser, ValueParser},
|
||||
builder::{NonEmptyStringValueParser, PossibleValue, ValueParser},
|
||||
crate_version, Arg, ArgAction, Command,
|
||||
};
|
||||
use glob::{MatchOptions, Pattern};
|
||||
|
@ -62,6 +62,7 @@ use uucore::{
|
|||
format_usage,
|
||||
fs::display_permissions,
|
||||
parse_size::parse_size_u64,
|
||||
shortcut_value_parser::ShortcutValueParser,
|
||||
version_cmp::version_cmp,
|
||||
};
|
||||
use uucore::{help_about, help_section, help_usage, parse_glob, show, show_error, show_warning};
|
||||
|
@ -1203,7 +1204,7 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::FORMAT)
|
||||
.long(options::FORMAT)
|
||||
.help("Set the display format.")
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"long",
|
||||
"verbose",
|
||||
"single-column",
|
||||
|
@ -1212,7 +1213,7 @@ pub fn uu_app() -> Command {
|
|||
"across",
|
||||
"horizontal",
|
||||
"commas",
|
||||
])
|
||||
]))
|
||||
.hide_possible_values(true)
|
||||
.require_equals(true)
|
||||
.overrides_with_all([
|
||||
|
@ -1303,9 +1304,11 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::HYPERLINK)
|
||||
.long(options::HYPERLINK)
|
||||
.help("hyperlink file names WHEN")
|
||||
.value_parser([
|
||||
"always", "yes", "force", "auto", "tty", "if-tty", "never", "no", "none",
|
||||
])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("always").alias("yes").alias("force"),
|
||||
PossibleValue::new("auto").alias("tty").alias("if-tty"),
|
||||
PossibleValue::new("never").alias("no").alias("none"),
|
||||
]))
|
||||
.require_equals(true)
|
||||
.num_args(0..=1)
|
||||
.default_missing_value("always")
|
||||
|
@ -1351,15 +1354,15 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::QUOTING_STYLE)
|
||||
.long(options::QUOTING_STYLE)
|
||||
.help("Set quoting style.")
|
||||
.value_parser([
|
||||
"literal",
|
||||
"shell",
|
||||
"shell-always",
|
||||
"shell-escape",
|
||||
"shell-escape-always",
|
||||
"c",
|
||||
"escape",
|
||||
])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("literal"),
|
||||
PossibleValue::new("shell"),
|
||||
PossibleValue::new("shell-escape"),
|
||||
PossibleValue::new("shell-always"),
|
||||
PossibleValue::new("shell-escape-always"),
|
||||
PossibleValue::new("c").alias("c-maybe"),
|
||||
PossibleValue::new("escape"),
|
||||
]))
|
||||
.overrides_with_all([
|
||||
options::QUOTING_STYLE,
|
||||
options::quoting::LITERAL,
|
||||
|
@ -1434,9 +1437,11 @@ pub fn uu_app() -> Command {
|
|||
\tbirth time: birth, creation;",
|
||||
)
|
||||
.value_name("field")
|
||||
.value_parser([
|
||||
"atime", "access", "use", "ctime", "status", "birth", "creation",
|
||||
])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("atime").alias("access").alias("use"),
|
||||
PossibleValue::new("ctime").alias("status"),
|
||||
PossibleValue::new("birth").alias("creation"),
|
||||
]))
|
||||
.hide_possible_values(true)
|
||||
.require_equals(true)
|
||||
.overrides_with_all([options::TIME, options::time::ACCESS, options::time::CHANGE]),
|
||||
|
@ -1496,7 +1501,7 @@ pub fn uu_app() -> Command {
|
|||
.long(options::SORT)
|
||||
.help("Sort by <field>: name, none (-U), time (-t), size (-S), extension (-X) or width")
|
||||
.value_name("field")
|
||||
.value_parser(["name", "none", "time", "size", "version", "extension", "width"])
|
||||
.value_parser(ShortcutValueParser::new(["name", "none", "time", "size", "version", "extension", "width"]))
|
||||
.require_equals(true)
|
||||
.overrides_with_all([
|
||||
options::SORT,
|
||||
|
@ -1744,9 +1749,11 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::COLOR)
|
||||
.long(options::COLOR)
|
||||
.help("Color output based on file type.")
|
||||
.value_parser([
|
||||
"always", "yes", "force", "auto", "tty", "if-tty", "never", "no", "none",
|
||||
])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("always").alias("yes").alias("force"),
|
||||
PossibleValue::new("auto").alias("tty").alias("if-tty"),
|
||||
PossibleValue::new("never").alias("no").alias("none"),
|
||||
]))
|
||||
.require_equals(true)
|
||||
.num_args(0..=1),
|
||||
)
|
||||
|
@ -1757,7 +1764,7 @@ pub fn uu_app() -> Command {
|
|||
"Append indicator with style WORD to entry names: \
|
||||
none (default), slash (-p), file-type (--file-type), classify (-F)",
|
||||
)
|
||||
.value_parser(["none", "slash", "file-type", "classify"])
|
||||
.value_parser(ShortcutValueParser::new(["none", "slash", "file-type", "classify"]))
|
||||
.overrides_with_all([
|
||||
options::indicator_style::FILE_TYPE,
|
||||
options::indicator_style::SLASH,
|
||||
|
@ -1788,9 +1795,11 @@ pub fn uu_app() -> Command {
|
|||
--dereference-command-line-symlink-to-dir options are specified.",
|
||||
)
|
||||
.value_name("when")
|
||||
.value_parser([
|
||||
"always", "yes", "force", "auto", "tty", "if-tty", "never", "no", "none",
|
||||
])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("always").alias("yes").alias("force"),
|
||||
PossibleValue::new("auto").alias("tty").alias("if-tty"),
|
||||
PossibleValue::new("never").alias("no").alias("none"),
|
||||
]))
|
||||
.default_missing_value("always")
|
||||
.require_equals(true)
|
||||
.num_args(0..=1)
|
||||
|
|
|
@ -15,6 +15,7 @@ use units::{IEC_BASES, SI_BASES};
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::UResult;
|
||||
use uucore::ranges::Range;
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage, show, show_error};
|
||||
|
||||
pub mod errors;
|
||||
|
@ -340,7 +341,13 @@ pub fn uu_app() -> Command {
|
|||
.help("use METHOD for rounding when scaling")
|
||||
.value_name("METHOD")
|
||||
.default_value("from-zero")
|
||||
.value_parser(["up", "down", "from-zero", "towards-zero", "nearest"]),
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"up",
|
||||
"down",
|
||||
"from-zero",
|
||||
"towards-zero",
|
||||
"nearest",
|
||||
])),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::SUFFIX)
|
||||
|
|
|
@ -43,6 +43,7 @@ use clap::{crate_version, parser::ValueSource, Arg, ArgMatches, Command};
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::{UResult, USimpleError};
|
||||
use uucore::parse_size::ParseSizeError;
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_warning};
|
||||
|
||||
const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes
|
||||
|
@ -287,7 +288,7 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::ENDIAN)
|
||||
.long(options::ENDIAN)
|
||||
.help("byte order to use for multi-byte formats")
|
||||
.value_parser(["big", "little"])
|
||||
.value_parser(ShortcutValueParser::new(["big", "little"]))
|
||||
.value_name("big|little"),
|
||||
)
|
||||
.arg(
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::path::{Path, PathBuf};
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
|
||||
use uucore::parse_size::parse_size_u64;
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_if_err};
|
||||
|
||||
const ABOUT: &str = help_about!("shred.md");
|
||||
|
@ -315,11 +316,11 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::REMOVE)
|
||||
.long(options::REMOVE)
|
||||
.value_name("HOW")
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
options::remove::UNLINK,
|
||||
options::remove::WIPE,
|
||||
options::remove::WIPESYNC,
|
||||
])
|
||||
]))
|
||||
.num_args(0..=1)
|
||||
.require_equals(true)
|
||||
.default_missing_value(options::remove::WIPESYNC)
|
||||
|
|
|
@ -43,6 +43,7 @@ use uucore::display::Quotable;
|
|||
use uucore::error::{set_exit_code, strip_errno, UError, UResult, USimpleError, UUsageError};
|
||||
use uucore::line_ending::LineEnding;
|
||||
use uucore::parse_size::{ParseSizeError, Parser};
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::version_cmp::version_cmp;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage};
|
||||
|
||||
|
@ -1297,14 +1298,14 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(options::modes::SORT)
|
||||
.long(options::modes::SORT)
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"general-numeric",
|
||||
"human-numeric",
|
||||
"month",
|
||||
"numeric",
|
||||
"version",
|
||||
"random",
|
||||
])
|
||||
]))
|
||||
.conflicts_with_all(options::modes::ALL_SORT_MODES),
|
||||
)
|
||||
.arg(make_sort_mode_arg(
|
||||
|
@ -1363,11 +1364,11 @@ pub fn uu_app() -> Command {
|
|||
.long(options::check::CHECK)
|
||||
.require_equals(true)
|
||||
.num_args(0..)
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
options::check::SILENT,
|
||||
options::check::QUIET,
|
||||
options::check::DIAGNOSE_FIRST,
|
||||
])
|
||||
]))
|
||||
.conflicts_with(options::OUTPUT)
|
||||
.help("check for sorted input; do not sort"),
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ use std::io::IsTerminal;
|
|||
use std::time::Duration;
|
||||
use uucore::error::{UResult, USimpleError, UUsageError};
|
||||
use uucore::parse_size::{parse_size_u64, ParseSizeError};
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_usage, show_warning};
|
||||
|
||||
const ABOUT: &str = help_about!("tail.md");
|
||||
|
@ -494,7 +495,7 @@ pub fn uu_app() -> Command {
|
|||
.default_missing_value("descriptor")
|
||||
.num_args(0..=1)
|
||||
.require_equals(true)
|
||||
.value_parser(["descriptor", "name"])
|
||||
.value_parser(ShortcutValueParser::new(["descriptor", "name"]))
|
||||
.overrides_with(options::FOLLOW)
|
||||
.help("Print the file as it grows"),
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::io::{copy, stdin, stdout, Error, ErrorKind, Read, Result, Write};
|
|||
use std::path::PathBuf;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::UResult;
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage, show_error};
|
||||
|
||||
// spell-checker:ignore nopipe
|
||||
|
@ -119,7 +120,7 @@ pub fn uu_app() -> Command {
|
|||
.long(options::OUTPUT_ERROR)
|
||||
.require_equals(true)
|
||||
.num_args(0..=1)
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("warn")
|
||||
.help("produce warnings for errors writing to any output"),
|
||||
PossibleValue::new("warn-nopipe")
|
||||
|
@ -127,7 +128,7 @@ pub fn uu_app() -> Command {
|
|||
PossibleValue::new("exit").help("exit on write errors to any output"),
|
||||
PossibleValue::new("exit-nopipe")
|
||||
.help("exit on write errors to any output that are not pipe errors (equivalent to exit on non-unix platforms)"),
|
||||
])
|
||||
]))
|
||||
.help("set write error behavior")
|
||||
.conflicts_with(options::IGNORE_PIPE_ERRORS),
|
||||
)
|
||||
|
|
|
@ -10,7 +10,7 @@ use chrono::{
|
|||
DateTime, Datelike, Duration, Local, LocalResult, NaiveDate, NaiveDateTime, NaiveTime,
|
||||
TimeZone, Timelike,
|
||||
};
|
||||
use clap::builder::ValueParser;
|
||||
use clap::builder::{PossibleValue, ValueParser};
|
||||
use clap::{crate_version, Arg, ArgAction, ArgGroup, ArgMatches, Command};
|
||||
use filetime::{set_file_times, set_symlink_file_times, FileTime};
|
||||
use std::ffi::OsString;
|
||||
|
@ -18,6 +18,7 @@ use std::fs::{self, File};
|
|||
use std::path::{Path, PathBuf};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError};
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_usage, show};
|
||||
|
||||
const ABOUT: &str = help_about!("touch.md");
|
||||
|
@ -216,7 +217,10 @@ pub fn uu_app() -> Command {
|
|||
equivalent to -m",
|
||||
)
|
||||
.value_name("WORD")
|
||||
.value_parser(["access", "atime", "use", "modify", "mtime"]),
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
PossibleValue::new("atime").alias("access").alias("use"),
|
||||
PossibleValue::new("mtime").alias("modify"),
|
||||
])),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(ARG_FILES)
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::num::IntErrorKind;
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
||||
use uucore::posix::{posix_version, OBSOLETE};
|
||||
use uucore::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::{format_usage, help_about, help_section, help_usage};
|
||||
|
||||
const ABOUT: &str = help_about!("uniq.md");
|
||||
|
@ -609,11 +610,11 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::ALL_REPEATED)
|
||||
.short('D')
|
||||
.long(options::ALL_REPEATED)
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"none",
|
||||
"prepend",
|
||||
"separate"
|
||||
])
|
||||
]))
|
||||
.help("print all duplicate lines. Delimiting is done with blank lines. [default: none]")
|
||||
.value_name("delimit-method")
|
||||
.num_args(0..=1)
|
||||
|
@ -623,12 +624,12 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(options::GROUP)
|
||||
.long(options::GROUP)
|
||||
.value_parser([
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"separate",
|
||||
"prepend",
|
||||
"append",
|
||||
"both",
|
||||
])
|
||||
]))
|
||||
.help("show all items, separating groups with an empty line. [default: separate]")
|
||||
.value_name("group-method")
|
||||
.num_args(0..=1)
|
||||
|
|
|
@ -29,6 +29,7 @@ use uucore::{
|
|||
error::{FromIo, UError, UResult},
|
||||
format_usage, help_about, help_usage,
|
||||
quoting_style::{escape_name, QuotingStyle},
|
||||
shortcut_value_parser::ShortcutValueParser,
|
||||
show,
|
||||
};
|
||||
|
||||
|
@ -439,7 +440,9 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(options::TOTAL)
|
||||
.long(options::TOTAL)
|
||||
.value_parser(["auto", "always", "only", "never"])
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"auto", "always", "only", "never",
|
||||
]))
|
||||
.value_name("WHEN")
|
||||
.hide_possible_values(true)
|
||||
.help(concat!(
|
||||
|
|
|
@ -61,6 +61,7 @@ pub enum UpdateMode {
|
|||
}
|
||||
|
||||
pub mod arguments {
|
||||
use crate::shortcut_value_parser::ShortcutValueParser;
|
||||
use clap::ArgAction;
|
||||
|
||||
pub static OPT_UPDATE: &str = "update";
|
||||
|
@ -71,7 +72,7 @@ pub mod arguments {
|
|||
clap::Arg::new(OPT_UPDATE)
|
||||
.long("update")
|
||||
.help("move only when the SOURCE file is newer than the destination file or when the destination file is missing")
|
||||
.value_parser(["none", "all", "older"])
|
||||
.value_parser(ShortcutValueParser::new(["none", "all", "older"]))
|
||||
.num_args(0..=1)
|
||||
.default_missing_value("older")
|
||||
.require_equals(true)
|
||||
|
|
|
@ -66,7 +66,7 @@ impl TypedValueParser for ShortcutValueParser {
|
|||
let matched_values: Vec<_> = self
|
||||
.0
|
||||
.iter()
|
||||
.filter(|x| x.get_name().starts_with(value))
|
||||
.filter(|x| x.get_name_and_aliases().any(|name| name.starts_with(value)))
|
||||
.collect();
|
||||
|
||||
match matched_values.len() {
|
||||
|
@ -101,7 +101,7 @@ where
|
|||
mod tests {
|
||||
use std::ffi::OsStr;
|
||||
|
||||
use clap::{builder::TypedValueParser, error::ErrorKind, Command};
|
||||
use clap::{builder::PossibleValue, builder::TypedValueParser, error::ErrorKind, Command};
|
||||
|
||||
use super::ShortcutValueParser;
|
||||
|
||||
|
@ -166,4 +166,30 @@ mod tests {
|
|||
let result = parser.parse_ref(&cmd, None, OsStr::from_bytes(&[0xc3, 0x28]));
|
||||
assert_eq!(ErrorKind::InvalidUtf8, result.unwrap_err().kind());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ambiguous_word_same_meaning() {
|
||||
let cmd = Command::new("cmd");
|
||||
let parser = ShortcutValueParser::new([
|
||||
PossibleValue::new("atime").alias("access"),
|
||||
"status".into(),
|
||||
]);
|
||||
// Even though "a" is ambiguous (it might mean "atime" or "access"),
|
||||
// the meaning is uniquely defined, therefore accept it.
|
||||
let atime_values = [
|
||||
// spell-checker:disable-next-line
|
||||
"atime", "atim", "at", "a", "access", "acces", "acce", "acc", "ac",
|
||||
];
|
||||
// spell-checker:disable-next-line
|
||||
let status_values = ["status", "statu", "stat", "sta", "st", "st"];
|
||||
|
||||
for value in atime_values {
|
||||
let result = parser.parse_ref(&cmd, None, OsStr::new(value));
|
||||
assert_eq!("atime", result.unwrap());
|
||||
}
|
||||
for value in status_values {
|
||||
let result = parser.parse_ref(&cmd, None, OsStr::new(value));
|
||||
assert_eq!("status", result.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE clob btrfs ROOTDIR USERDIR procfs outfile uufs xattrs
|
||||
// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE clob btrfs neve ROOTDIR USERDIR procfs outfile uufs xattrs
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(not(windows))]
|
||||
|
@ -286,16 +286,18 @@ fn test_cp_arg_update_interactive_error() {
|
|||
|
||||
#[test]
|
||||
fn test_cp_arg_update_none() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
for argument in ["--update=none", "--update=non", "--update=n"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg("--update=none")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg(argument)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1402,29 +1404,28 @@ fn test_cp_preserve_no_args_before_opts() {
|
|||
|
||||
#[test]
|
||||
fn test_cp_preserve_all() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let src_file = "a";
|
||||
let dst_file = "b";
|
||||
for argument in ["--preserve=all", "--preserve=al"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let src_file = "a";
|
||||
let dst_file = "b";
|
||||
|
||||
// Prepare the source file
|
||||
at.touch(src_file);
|
||||
#[cfg(unix)]
|
||||
at.set_mode(src_file, 0o0500);
|
||||
// Prepare the source file
|
||||
at.touch(src_file);
|
||||
#[cfg(unix)]
|
||||
at.set_mode(src_file, 0o0500);
|
||||
|
||||
// TODO: create a destination that does not allow copying of xattr and context
|
||||
// Copy
|
||||
ucmd.arg(src_file)
|
||||
.arg(dst_file)
|
||||
.arg("--preserve=all")
|
||||
.succeeds();
|
||||
// TODO: create a destination that does not allow copying of xattr and context
|
||||
// Copy
|
||||
ucmd.arg(src_file).arg(dst_file).arg(argument).succeeds();
|
||||
|
||||
#[cfg(all(unix, not(target_os = "freebsd")))]
|
||||
{
|
||||
// Assert that the mode, ownership, and timestamps are preserved
|
||||
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
|
||||
let metadata_src = at.metadata(src_file);
|
||||
let metadata_dst = at.metadata(dst_file);
|
||||
assert_metadata_eq!(metadata_src, metadata_dst);
|
||||
#[cfg(all(unix, not(target_os = "freebsd")))]
|
||||
{
|
||||
// Assert that the mode, ownership, and timestamps are preserved
|
||||
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
|
||||
let metadata_src = at.metadata(src_file);
|
||||
let metadata_dst = at.metadata(dst_file);
|
||||
assert_metadata_eq!(metadata_src, metadata_dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1472,6 +1473,35 @@ fn test_cp_preserve_all_context_fails_on_non_selinux() {
|
|||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_preserve_link_parses() {
|
||||
// TODO: Also check whether --preserve=link did the right thing!
|
||||
for argument in [
|
||||
"--preserve=links",
|
||||
"--preserve=link",
|
||||
"--preserve=li",
|
||||
"--preserve=l",
|
||||
] {
|
||||
new_ucmd!()
|
||||
.arg(argument)
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.succeeds()
|
||||
.no_output();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_preserve_invalid_rejected() {
|
||||
new_ucmd!()
|
||||
.arg("--preserve=invalid-value")
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(disabled_until_fixed)] // FIXME: the test looks to .succeed on android
|
||||
|
@ -2196,14 +2226,16 @@ fn test_cp_reflink_none() {
|
|||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))]
|
||||
fn test_cp_reflink_never() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg("--reflink=never")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.succeeds();
|
||||
for argument in ["--reflink=never", "--reflink=neve", "--reflink=n"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg(argument)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2286,19 +2318,21 @@ fn test_cp_sparse_never_empty() {
|
|||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[test]
|
||||
fn test_cp_sparse_always_empty() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
for argument in ["--sparse=always", "--sparse=alway", "--sparse=al"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
const BUFFER_SIZE: usize = 4096 * 4;
|
||||
let buf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
const BUFFER_SIZE: usize = 4096 * 4;
|
||||
let buf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
|
||||
at.make_file("src_file1");
|
||||
at.write_bytes("src_file1", &buf);
|
||||
at.make_file("src_file1");
|
||||
at.write_bytes("src_file1", &buf);
|
||||
|
||||
ucmd.args(&["--sparse=always", "src_file1", "dst_file_sparse"])
|
||||
.succeeds();
|
||||
ucmd.args(&[argument, "src_file1", "dst_file_sparse"])
|
||||
.succeeds();
|
||||
|
||||
assert_eq!(at.read_bytes("dst_file_sparse"), buf);
|
||||
assert_eq!(at.metadata("dst_file_sparse").blocks(), 0);
|
||||
assert_eq!(at.read_bytes("dst_file_sparse"), buf);
|
||||
assert_eq!(at.metadata("dst_file_sparse").blocks(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty tsublink testfile1 testfile2 filelist testdir testfile
|
||||
// spell-checker:ignore (paths) atim sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty tsublink testfile1 testfile2 filelist testdir testfile
|
||||
#[cfg(not(windows))]
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -576,13 +576,15 @@ fn test_du_time() {
|
|||
.succeeds();
|
||||
result.stdout_only("0\t2016-06-16 00:00\tdate_test\n");
|
||||
|
||||
let result = ts
|
||||
.ucmd()
|
||||
.env("TZ", "UTC")
|
||||
.arg("--time=atime")
|
||||
.arg("date_test")
|
||||
.succeeds();
|
||||
result.stdout_only("0\t2015-05-15 00:00\tdate_test\n");
|
||||
for argument in ["--time=atime", "--time=atim", "--time=a"] {
|
||||
let result = ts
|
||||
.ucmd()
|
||||
.env("TZ", "UTC")
|
||||
.arg(argument)
|
||||
.arg("date_test")
|
||||
.succeeds();
|
||||
result.stdout_only("0\t2015-05-15 00:00\tdate_test\n");
|
||||
}
|
||||
|
||||
let result = ts
|
||||
.ucmd()
|
||||
|
|
|
@ -27,6 +27,7 @@ const LONG_ARGS: &[&str] = &[
|
|||
"-l",
|
||||
"--long",
|
||||
"--format=long",
|
||||
"--format=lon",
|
||||
"--for=long",
|
||||
"--format=verbose",
|
||||
"--for=verbose",
|
||||
|
@ -35,6 +36,7 @@ const LONG_ARGS: &[&str] = &[
|
|||
const ACROSS_ARGS: &[&str] = &[
|
||||
"-x",
|
||||
"--format=across",
|
||||
"--format=acr",
|
||||
"--format=horizontal",
|
||||
"--for=across",
|
||||
"--for=horizontal",
|
||||
|
@ -999,6 +1001,8 @@ fn test_ls_zero() {
|
|||
let ignored_opts = [
|
||||
"--quoting-style=c",
|
||||
"--color=always",
|
||||
"--color=alway",
|
||||
"--color=al",
|
||||
"-m",
|
||||
"--hide-control-chars",
|
||||
];
|
||||
|
@ -1601,6 +1605,24 @@ fn test_ls_deref() {
|
|||
.succeeds();
|
||||
assert!(re.is_match(result.stdout_str().trim()));
|
||||
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-l")
|
||||
.arg("--color=neve") // spell-checker:disable-line
|
||||
.arg("test-long")
|
||||
.arg("test-long.link")
|
||||
.succeeds();
|
||||
assert!(re.is_match(result.stdout_str().trim()));
|
||||
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-l")
|
||||
.arg("--color=n")
|
||||
.arg("test-long")
|
||||
.arg("test-long.link")
|
||||
.succeeds();
|
||||
assert!(re.is_match(result.stdout_str().trim()));
|
||||
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-L")
|
||||
|
@ -1676,6 +1698,10 @@ fn test_ls_sort_none() {
|
|||
// Order is not specified so we just check that it doesn't
|
||||
// give any errors.
|
||||
scene.ucmd().arg("--sort=none").succeeds();
|
||||
scene.ucmd().arg("--sort=non").succeeds();
|
||||
scene.ucmd().arg("--sort=no").succeeds();
|
||||
// scene.ucmd().arg("--sort=n").succeeds();
|
||||
// We refuse to accept "--sort=n", since this is too confusable with "--sort=name", which is our own extension.
|
||||
scene.ucmd().arg("-U").succeeds();
|
||||
}
|
||||
|
||||
|
@ -1693,6 +1719,16 @@ fn test_ls_sort_name() {
|
|||
.arg("--sort=name")
|
||||
.succeeds()
|
||||
.stdout_is("test-1\ntest-2\ntest-3\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--sort=nam")
|
||||
.succeeds()
|
||||
.stdout_is("test-1\ntest-2\ntest-3\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--sort=na")
|
||||
.succeeds()
|
||||
.stdout_is("test-1\ntest-2\ntest-3\n");
|
||||
|
||||
let scene_dot = TestScenario::new(util_name!());
|
||||
let at = &scene_dot.fixtures;
|
||||
|
@ -1729,6 +1765,16 @@ fn test_ls_sort_width() {
|
|||
.arg("--sort=width")
|
||||
.succeeds()
|
||||
.stdout_is("d\nzz\nabc\nbbb\neee\ncccc\naaaaa\nbcdef\nfffff\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--sort=widt") // spell-checker:disable-line
|
||||
.succeeds()
|
||||
.stdout_is("d\nzz\nabc\nbbb\neee\ncccc\naaaaa\nbcdef\nfffff\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--sort=w")
|
||||
.succeeds()
|
||||
.stdout_is("d\nzz\nabc\nbbb\neee\ncccc\naaaaa\nbcdef\nfffff\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1757,6 +1803,12 @@ fn test_ls_order_size() {
|
|||
let result = scene.ucmd().arg("--sort=size").succeeds();
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=siz").succeeds();
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=s").succeeds();
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=size").arg("-r").succeeds();
|
||||
result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n");
|
||||
}
|
||||
|
@ -1961,7 +2013,14 @@ fn test_ls_order_time() {
|
|||
|
||||
// 3 was accessed last in the read
|
||||
// So the order should be 2 3 4 1
|
||||
for arg in ["-u", "--time=atime", "--time=access", "--time=use"] {
|
||||
for arg in [
|
||||
"-u",
|
||||
"--time=atime",
|
||||
"--time=atim", // spell-checker:disable-line
|
||||
"--time=a",
|
||||
"--time=access",
|
||||
"--time=use",
|
||||
] {
|
||||
let result = scene.ucmd().arg("-t").arg(arg).succeeds();
|
||||
at.open("test-3").metadata().unwrap().accessed().unwrap();
|
||||
at.open("test-4").metadata().unwrap().accessed().unwrap();
|
||||
|
@ -2216,12 +2275,16 @@ fn test_ls_indicator_style() {
|
|||
for opt in [
|
||||
"--indicator-style=classify",
|
||||
"--ind=classify",
|
||||
"--indicator-style=clas", // spell-checker:disable-line
|
||||
"--indicator-style=c",
|
||||
"--indicator-style=file-type",
|
||||
"--ind=file-type",
|
||||
"--indicator-style=slash",
|
||||
"--ind=slash",
|
||||
"--classify",
|
||||
"--classify=always",
|
||||
"--classify=alway", // spell-checker:disable-line
|
||||
"--classify=al",
|
||||
"--classify=yes",
|
||||
"--classify=force",
|
||||
"--class",
|
||||
|
@ -2236,10 +2299,13 @@ fn test_ls_indicator_style() {
|
|||
// Classify, Indicator options should not contain any indicators when value is none.
|
||||
for opt in [
|
||||
"--indicator-style=none",
|
||||
"--indicator-style=n",
|
||||
"--ind=none",
|
||||
"--classify=none",
|
||||
"--classify=never",
|
||||
"--classify=non",
|
||||
"--classify=no",
|
||||
"--classify=n",
|
||||
] {
|
||||
// Verify that there are no indicators for any of the file types.
|
||||
scene
|
||||
|
@ -2553,6 +2619,12 @@ fn test_ls_version_sort() {
|
|||
expected
|
||||
);
|
||||
|
||||
let result = scene.ucmd().arg("-1").arg("--sort=v").succeeds();
|
||||
assert_eq!(
|
||||
result.stdout_str().split('\n').collect::<Vec<_>>(),
|
||||
expected
|
||||
);
|
||||
|
||||
let result = scene.ucmd().arg("-a1v").succeeds();
|
||||
expected.insert(expected.len() - 1, "..");
|
||||
expected.insert(0, ".");
|
||||
|
@ -2589,19 +2661,27 @@ fn test_ls_quoting_style() {
|
|||
|
||||
for (arg, correct) in [
|
||||
("--quoting-style=literal", "one?two"),
|
||||
("--quoting-style=litera", "one?two"), // spell-checker:disable-line
|
||||
("--quoting-style=li", "one?two"),
|
||||
("-N", "one?two"),
|
||||
("--literal", "one?two"),
|
||||
("--l", "one?two"),
|
||||
("--quoting-style=c", "\"one\\ntwo\""),
|
||||
("--quoting-style=c-", "\"one\\ntwo\""),
|
||||
("--quoting-style=c-maybe", "\"one\\ntwo\""),
|
||||
("-Q", "\"one\\ntwo\""),
|
||||
("--quote-name", "\"one\\ntwo\""),
|
||||
("--quoting-style=escape", "one\\ntwo"),
|
||||
("--quoting-style=escap", "one\\ntwo"), // spell-checker:disable-line
|
||||
("-b", "one\\ntwo"),
|
||||
("--escape", "one\\ntwo"),
|
||||
("--quoting-style=shell-escape", "'one'$'\\n''two'"),
|
||||
("--quoting-style=shell-escape-always", "'one'$'\\n''two'"),
|
||||
("--quoting-style=shell-escape-alway", "'one'$'\\n''two'"),
|
||||
("--quoting-style=shell-escape-a", "'one'$'\\n''two'"),
|
||||
("--quoting-style=shell", "one?two"),
|
||||
("--quoting-style=shell-always", "'one?two'"),
|
||||
("--quoting-style=shell-a", "'one?two'"),
|
||||
] {
|
||||
scene
|
||||
.ucmd()
|
||||
|
@ -4244,11 +4324,18 @@ fn test_ls_hyperlink() {
|
|||
.stdout_str()
|
||||
.contains(&format!("{path}{separator}{file}\x07{file}\x1b]8;;\x07")));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--hyperlink=never")
|
||||
.succeeds()
|
||||
.stdout_is(format!("{file}\n"));
|
||||
for argument in [
|
||||
"--hyperlink=never",
|
||||
"--hyperlink=neve", // spell-checker:disable-line
|
||||
"--hyperlink=ne", // spell-checker:disable-line
|
||||
"--hyperlink=n",
|
||||
] {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(argument)
|
||||
.succeeds()
|
||||
.stdout_is(format!("{file}\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// spell-checker: disable
|
||||
|
|
|
@ -550,10 +550,14 @@ fn test_delimiter_with_padding_and_fields() {
|
|||
fn test_round() {
|
||||
for (method, exp) in [
|
||||
("from-zero", ["9.1K", "-9.1K", "9.1K", "-9.1K"]),
|
||||
("from-zer", ["9.1K", "-9.1K", "9.1K", "-9.1K"]), // spell-checker:disable-line
|
||||
("f", ["9.1K", "-9.1K", "9.1K", "-9.1K"]),
|
||||
("towards-zero", ["9.0K", "-9.0K", "9.0K", "-9.0K"]),
|
||||
("up", ["9.1K", "-9.0K", "9.1K", "-9.0K"]),
|
||||
("down", ["9.0K", "-9.1K", "9.0K", "-9.1K"]),
|
||||
("nearest", ["9.0K", "-9.0K", "9.1K", "-9.1K"]),
|
||||
("near", ["9.0K", "-9.0K", "9.1K", "-9.1K"]),
|
||||
("n", ["9.0K", "-9.0K", "9.1K", "-9.1K"]),
|
||||
] {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
|
|
|
@ -53,6 +53,20 @@ fn test_file() {
|
|||
.no_stderr()
|
||||
.stdout_is(unindent(ALPHA_OUT));
|
||||
|
||||
new_ucmd!()
|
||||
.arg("--endian=littl") // spell-checker:disable-line
|
||||
.arg(file.as_os_str())
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is(unindent(ALPHA_OUT));
|
||||
|
||||
new_ucmd!()
|
||||
.arg("--endian=l")
|
||||
.arg(file.as_os_str())
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is(unindent(ALPHA_OUT));
|
||||
|
||||
// Ensure that default format matches `-t o2`, and that `-t` does not absorb file argument
|
||||
new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
|
@ -463,6 +477,16 @@ fn test_big_endian() {
|
|||
.run_piped_stdin(&input[..])
|
||||
.no_stderr()
|
||||
.success()
|
||||
.stdout_is(&expected_output);
|
||||
new_ucmd!()
|
||||
.arg("--endian=b")
|
||||
.arg("-F")
|
||||
.arg("-f")
|
||||
.arg("-X")
|
||||
.arg("-x")
|
||||
.run_piped_stdin(&input[..])
|
||||
.no_stderr()
|
||||
.success()
|
||||
.stdout_is(expected_output);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@ fn test_invalid_remove_arg() {
|
|||
new_ucmd!().arg("--remove=unknown").fails().code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ambiguous_remove_arg() {
|
||||
new_ucmd!().arg("--remove=wip").fails().code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shred() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
@ -49,15 +54,15 @@ fn test_shred_remove() {
|
|||
|
||||
#[test]
|
||||
fn test_shred_remove_unlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let file = "test_shred_remove_unlink";
|
||||
at.touch(file);
|
||||
|
||||
ucmd.arg("--remove=unlink").arg(file).succeeds();
|
||||
|
||||
// File was deleted
|
||||
assert!(!at.file_exists(file));
|
||||
// spell-checker:disable-next-line
|
||||
for argument in ["--remove=unlink", "--remove=unlin", "--remove=u"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_shred_remove_unlink";
|
||||
at.touch(file);
|
||||
ucmd.arg(argument).arg(file).succeeds();
|
||||
// File was deleted
|
||||
assert!(!at.file_exists(file));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -75,15 +80,15 @@ fn test_shred_remove_wipe() {
|
|||
|
||||
#[test]
|
||||
fn test_shred_remove_wipesync() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let file = "test_shred_remove_wipesync";
|
||||
at.touch(file);
|
||||
|
||||
ucmd.arg("--remove=wipesync").arg(file).succeeds();
|
||||
|
||||
// File was deleted
|
||||
assert!(!at.file_exists(file));
|
||||
// spell-checker:disable-next-line
|
||||
for argument in ["--remove=wipesync", "--remove=wipesyn", "--remove=wipes"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_shred_remove_wipesync";
|
||||
at.touch(file);
|
||||
ucmd.arg(argument).arg(file).succeeds();
|
||||
// File was deleted
|
||||
assert!(!at.file_exists(file));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -126,7 +126,16 @@ fn test_ext_sort_zero_terminated() {
|
|||
|
||||
#[test]
|
||||
fn test_months_whitespace() {
|
||||
test_helper("months-whitespace", &["-M", "--month-sort", "--sort=month"]);
|
||||
test_helper(
|
||||
"months-whitespace",
|
||||
&[
|
||||
"-M",
|
||||
"--month-sort",
|
||||
"--sort=month",
|
||||
"--sort=mont", // spell-checker:disable-line
|
||||
"--sort=m",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -141,6 +150,16 @@ fn test_version_sort_unstable() {
|
|||
.pipe_in("0.1\n0.02\n0.2\n0.002\n0.3\n")
|
||||
.succeeds()
|
||||
.stdout_is("0.1\n0.002\n0.02\n0.2\n0.3\n");
|
||||
new_ucmd!()
|
||||
.arg("--sort=versio") // spell-checker:disable-line
|
||||
.pipe_in("0.1\n0.02\n0.2\n0.002\n0.3\n")
|
||||
.succeeds()
|
||||
.stdout_is("0.1\n0.002\n0.02\n0.2\n0.3\n");
|
||||
new_ucmd!()
|
||||
.arg("--sort=v")
|
||||
.pipe_in("0.1\n0.02\n0.2\n0.002\n0.3\n")
|
||||
.succeeds()
|
||||
.stdout_is("0.1\n0.002\n0.02\n0.2\n0.3\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -157,7 +176,14 @@ fn test_version_sort_stable() {
|
|||
fn test_human_numeric_whitespace() {
|
||||
test_helper(
|
||||
"human-numeric-whitespace",
|
||||
&["-h", "--human-numeric-sort", "--sort=human-numeric"],
|
||||
&[
|
||||
"-h",
|
||||
"--human-numeric-sort",
|
||||
"--sort=human-numeric",
|
||||
"--sort=human-numeri", // spell-checker:disable-line
|
||||
"--sort=human",
|
||||
"--sort=h",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -177,7 +203,14 @@ fn test_ext_sort_as64_bailout() {
|
|||
fn test_multiple_decimals_general() {
|
||||
test_helper(
|
||||
"multiple_decimals_general",
|
||||
&["-g", "--general-numeric-sort", "--sort=general-numeric"],
|
||||
&[
|
||||
"-g",
|
||||
"--general-numeric-sort",
|
||||
"--sort=general-numeric",
|
||||
"--sort=general-numeri", // spell-checker:disable-line
|
||||
"--sort=general",
|
||||
"--sort=g",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -185,7 +218,7 @@ fn test_multiple_decimals_general() {
|
|||
fn test_multiple_decimals_numeric() {
|
||||
test_helper(
|
||||
"multiple_decimals_numeric",
|
||||
&["-n", "--numeric-sort", "--sort=numeric"],
|
||||
&["-n", "--numeric-sort", "--sort=numeric", "--sort=n"],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -784,7 +817,13 @@ fn test_pipe() {
|
|||
|
||||
#[test]
|
||||
fn test_check() {
|
||||
for diagnose_arg in ["-c", "--check", "--check=diagnose-first"] {
|
||||
for diagnose_arg in [
|
||||
"-c",
|
||||
"--check",
|
||||
"--check=diagnose-first",
|
||||
"--check=diagnose",
|
||||
"--check=d",
|
||||
] {
|
||||
new_ucmd!()
|
||||
.arg(diagnose_arg)
|
||||
.arg("check_fail.txt")
|
||||
|
@ -802,12 +841,25 @@ fn test_check() {
|
|||
|
||||
#[test]
|
||||
fn test_check_silent() {
|
||||
for silent_arg in ["-C", "--check=silent", "--check=quiet"] {
|
||||
for silent_arg in [
|
||||
"-C",
|
||||
"--check=silent",
|
||||
"--check=quiet",
|
||||
"--check=silen", // spell-checker:disable-line
|
||||
"--check=quie", // spell-checker:disable-line
|
||||
"--check=s",
|
||||
"--check=q",
|
||||
] {
|
||||
new_ucmd!()
|
||||
.arg(silent_arg)
|
||||
.arg("check_fail.txt")
|
||||
.fails()
|
||||
.stdout_is("");
|
||||
new_ucmd!()
|
||||
.arg(silent_arg)
|
||||
.arg("empty.txt")
|
||||
.succeeds()
|
||||
.no_output();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -533,37 +533,40 @@ fn test_follow_multiple() {
|
|||
#[test]
|
||||
#[cfg(not(target_os = "windows"))] // FIXME: test times out
|
||||
fn test_follow_name_multiple() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let mut child = ucmd
|
||||
.arg("--follow=name")
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.run_no_wait();
|
||||
// spell-checker:disable-next-line
|
||||
for argument in ["--follow=name", "--follo=nam", "--f=n"] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let mut child = ucmd
|
||||
.arg(argument)
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.run_no_wait();
|
||||
|
||||
child
|
||||
.make_assertion_with_delay(500)
|
||||
.is_alive()
|
||||
.with_current_output()
|
||||
.stdout_only_fixture("foobar_follow_multiple.expected");
|
||||
child
|
||||
.make_assertion_with_delay(500)
|
||||
.is_alive()
|
||||
.with_current_output()
|
||||
.stdout_only_fixture("foobar_follow_multiple.expected");
|
||||
|
||||
let first_append = "trois\n";
|
||||
at.append(FOOBAR_2_TXT, first_append);
|
||||
let first_append = "trois\n";
|
||||
at.append(FOOBAR_2_TXT, first_append);
|
||||
|
||||
child
|
||||
.make_assertion_with_delay(DEFAULT_SLEEP_INTERVAL_MILLIS)
|
||||
.with_current_output()
|
||||
.stdout_only(first_append);
|
||||
child
|
||||
.make_assertion_with_delay(DEFAULT_SLEEP_INTERVAL_MILLIS)
|
||||
.with_current_output()
|
||||
.stdout_only(first_append);
|
||||
|
||||
let second_append = "twenty\nthirty\n";
|
||||
at.append(FOOBAR_TXT, second_append);
|
||||
let second_append = "twenty\nthirty\n";
|
||||
at.append(FOOBAR_TXT, second_append);
|
||||
|
||||
child
|
||||
.make_assertion_with_delay(DEFAULT_SLEEP_INTERVAL_MILLIS)
|
||||
.with_current_output()
|
||||
.stdout_only_fixture("foobar_follow_multiple_appended.expected");
|
||||
child
|
||||
.make_assertion_with_delay(DEFAULT_SLEEP_INTERVAL_MILLIS)
|
||||
.with_current_output()
|
||||
.stdout_only_fixture("foobar_follow_multiple_appended.expected");
|
||||
|
||||
child.make_assertion().is_alive();
|
||||
child.kill();
|
||||
child.make_assertion().is_alive();
|
||||
child.kill();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -844,7 +847,7 @@ fn test_follow_missing() {
|
|||
// Ensure that --follow=name does not imply --retry.
|
||||
// Ensure that --follow={descriptor,name} (without --retry) does *not wait* for the
|
||||
// file to appear.
|
||||
for follow_mode in &["--follow=descriptor", "--follow=name"] {
|
||||
for follow_mode in &["--follow=descriptor", "--follow=name", "--fo=d", "--fo=n"] {
|
||||
new_ucmd!()
|
||||
.arg(follow_mode)
|
||||
.arg("missing")
|
||||
|
|
|
@ -311,6 +311,23 @@ mod linux_only {
|
|||
expect_correct(file_out_a, &at, content.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pipe_error_warn_nopipe_3_shortcut() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let file_out_a = "tee_file_out_a";
|
||||
|
||||
let proc = ucmd
|
||||
.arg("--output-error=warn-")
|
||||
.arg(file_out_a)
|
||||
.set_stdout(make_broken_pipe());
|
||||
|
||||
let (content, output) = run_tee(proc);
|
||||
|
||||
expect_success(&output);
|
||||
expect_correct(file_out_a, &at, content.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pipe_error_warn() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
@ -362,6 +379,23 @@ mod linux_only {
|
|||
expect_correct(file_out_a, &at, content.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pipe_error_exit_nopipe_shortcut() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let file_out_a = "tee_file_out_a";
|
||||
|
||||
let proc = ucmd
|
||||
.arg("--output-error=exit-nop")
|
||||
.arg(file_out_a)
|
||||
.set_stdout(make_broken_pipe());
|
||||
|
||||
let (content, output) = run_tee(proc);
|
||||
|
||||
expect_success(&output);
|
||||
expect_correct(file_out_a, &at, content.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_space_error_default() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
|
|
@ -192,7 +192,14 @@ fn test_touch_set_cymdhms_time() {
|
|||
|
||||
#[test]
|
||||
fn test_touch_set_only_atime() {
|
||||
let atime_args = ["-a", "--time=access", "--time=atime", "--time=use"];
|
||||
let atime_args = [
|
||||
"-a",
|
||||
"--time=access",
|
||||
"--time=atime",
|
||||
"--time=atim", // spell-checker:disable-line
|
||||
"--time=a",
|
||||
"--time=use",
|
||||
];
|
||||
let file = "test_touch_set_only_atime";
|
||||
|
||||
for atime_arg in atime_args {
|
||||
|
@ -293,7 +300,7 @@ fn test_touch_set_both_time_and_date() {
|
|||
|
||||
#[test]
|
||||
fn test_touch_set_only_mtime() {
|
||||
let mtime_args = ["-m", "--time=modify", "--time=mtime"];
|
||||
let mtime_args = ["-m", "--time=modify", "--time=mtime", "--time=m"];
|
||||
let file = "test_touch_set_only_mtime";
|
||||
|
||||
for mtime_arg in mtime_args {
|
||||
|
|
|
@ -145,6 +145,21 @@ fn test_stdin_all_repeated() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=none"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=non"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=n"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -167,6 +182,16 @@ fn test_stdin_all_repeated_separate() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-separate.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=separat"]) // spell-checker:disable-line
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-separate.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=s"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-separate.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -176,6 +201,16 @@ fn test_stdin_all_repeated_prepend() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-prepend.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=prepen"]) // spell-checker:disable-line
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-prepend.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=p"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-prepend.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -253,6 +288,11 @@ fn test_group_prepend() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-prepend.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--group=p"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-prepend.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -262,6 +302,11 @@ fn test_group_append() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-append.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--group=a"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-append.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -271,6 +316,16 @@ fn test_group_both() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-both.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--group=bot"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-both.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--group=b"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group-both.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -280,6 +335,11 @@ fn test_group_separate() {
|
|||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group.expected");
|
||||
new_ucmd!()
|
||||
.args(&["--group=s"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("group.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -531,6 +531,10 @@ fn test_total_auto() {
|
|||
.args(&["lorem_ipsum.txt", "--total=auto"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n");
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--tot=au"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=auto"])
|
||||
|
@ -551,6 +555,13 @@ fn test_total_always() {
|
|||
" 13 109 772 lorem_ipsum.txt\n",
|
||||
" 13 109 772 total\n",
|
||||
));
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--total=al"])
|
||||
.run()
|
||||
.stdout_is(concat!(
|
||||
" 13 109 772 lorem_ipsum.txt\n",
|
||||
" 13 109 772 total\n",
|
||||
));
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=always"])
|
||||
|
@ -576,6 +587,13 @@ fn test_total_never() {
|
|||
" 13 109 772 lorem_ipsum.txt\n",
|
||||
" 18 204 1115 moby_dick.txt\n",
|
||||
));
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=n"])
|
||||
.run()
|
||||
.stdout_is(concat!(
|
||||
" 13 109 772 lorem_ipsum.txt\n",
|
||||
" 18 204 1115 moby_dick.txt\n",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -589,6 +607,10 @@ fn test_total_only() {
|
|||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=only"])
|
||||
.run()
|
||||
.stdout_is("31 313 1887\n");
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--t=o"])
|
||||
.run()
|
||||
.stdout_is("31 313 1887\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue