Add 5 opposing CLI options

Those are:
  - `--no-hidden`, which overrides `--hidden`
  - `--ignore`, which overrides `--no-ignore`
  - `--ignore-vcs`, which overrides `--no-ignore-vcs`
  - `--no-follow`, which overrides `--follow`
  - `--relative-path`, which overrides `--absolute-path`
This commit is contained in:
Vukašin Stepanović 2021-08-09 15:49:48 +02:00
parent c37592b0b7
commit 37852aa388
6 changed files with 148 additions and 18 deletions

View file

@ -2,6 +2,8 @@
## Features
- Add opposing command-line options, see #595 (@Asha20)
## Bugfixes
- Set default path separator to `/` in MSYS, see #537 and #730 (@aswild)

49
Cargo.lock generated
View file

@ -173,6 +173,7 @@ dependencies = [
"regex",
"regex-syntax",
"tempdir",
"test-case",
"users",
"version_check",
]
@ -352,6 +353,24 @@ dependencies = [
"libc",
]
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.4.6"
@ -455,6 +474,17 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tempdir"
version = "0.3.7"
@ -475,6 +505,19 @@ dependencies = [
"winapi",
]
[[package]]
name = "test-case"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b114ece25254e97bf48dd4bfc2a12bad0647adacfe4cae1247a9ca6ad302cec"
dependencies = [
"cfg-if 1.0.0",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "textwrap"
version = "0.11.0"
@ -500,6 +543,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "users"
version = "0.11.0"

View file

@ -69,6 +69,7 @@ jemallocator = "0.3.0"
diff = "0.1"
tempdir = "0.3"
filetime = "0.2.14"
test-case = "1.2.0"
[profile.release]
lto = true

View file

@ -25,7 +25,17 @@ pub fn build_app() -> App<'static, 'static> {
.long_help(
"Include hidden directories and files in the search results (default: \
hidden files and directories are skipped). Files and directories are \
considered to be hidden if their name starts with a `.` sign (dot).",
considered to be hidden if their name starts with a `.` sign (dot). \
Flag can be overridden with --no-hidden.",
),
)
.arg(
Arg::with_name("no-hidden")
.long("no-hidden")
.overrides_with("no-hidden")
.hidden(true)
.long_help(
"Overrides --hidden.",
),
)
.arg(
@ -36,7 +46,17 @@ pub fn build_app() -> App<'static, 'static> {
.help("Do not respect .(git|fd)ignore files")
.long_help(
"Show search results from files and directories that would otherwise be \
ignored by '.gitignore', '.ignore', '.fdignore', or the global ignore file.",
ignored by '.gitignore', '.ignore', '.fdignore', or the global ignore file. \
Flag can be overridden with --ignore.",
),
)
.arg(
Arg::with_name("ignore")
.long("ignore")
.overrides_with("ignore")
.hidden(true)
.long_help(
"Overrides --no-ignore.",
),
)
.arg(
@ -46,7 +66,16 @@ pub fn build_app() -> App<'static, 'static> {
.hidden_short_help(true)
.long_help(
"Show search results from files and directories that would otherwise be \
ignored by '.gitignore' files.",
ignored by '.gitignore' files. Flag can be overridden with --ignore-vcs.",
),
)
.arg(
Arg::with_name("ignore-vcs")
.long("ignore-vcs")
.overrides_with("ignore-vcs")
.hidden(true)
.long_help(
"Overrides --no-ignore-vcs.",
),
)
.arg(
@ -129,7 +158,17 @@ pub fn build_app() -> App<'static, 'static> {
.overrides_with("absolute-path")
.help("Show absolute instead of relative paths")
.long_help(
"Shows the full path starting from the root as opposed to relative paths.",
"Shows the full path starting from the root as opposed to relative paths. \
Flag can be overridden with --relative-path.",
),
)
.arg(
Arg::with_name("relative-path")
.long("relative-path")
.overrides_with("relative-path")
.hidden(true)
.long_help(
"Overrides --absolute-path.",
),
)
.arg(
@ -154,7 +193,17 @@ pub fn build_app() -> App<'static, 'static> {
.help("Follow symbolic links")
.long_help(
"By default, fd does not descend into symlinked directories. Using this \
flag, symbolic links are also traversed.",
flag, symbolic links are also traversed. \
Flag can be overriden with --no-follow.",
),
)
.arg(
Arg::with_name("no-follow")
.long("no-follow")
.overrides_with("no-follow")
.hidden(true)
.long_help(
"Overrides --follow.",
),
)
.arg(

View file

@ -20,8 +20,8 @@ use anyhow::{anyhow, Context, Result};
use atty::Stream;
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};
use normpath::PathExt;
use regex::bytes::{RegexBuilder, RegexSetBuilder};
use crate::error::print_error;
use crate::exec::CommandTemplate;
@ -116,7 +116,7 @@ fn run() -> Result<ExitCode> {
return Err(anyhow!("No valid search paths given."));
}
if matches.is_present("absolute-path") {
if matches.is_present("absolute-path") && !matches.is_present("relative-path") {
search_paths = search_paths
.iter()
.map(|path_buffer| {
@ -331,17 +331,21 @@ fn run() -> Result<ExitCode> {
let config = Options {
case_sensitive,
search_full_path: matches.is_present("full-path"),
ignore_hidden: !(matches.is_present("hidden")
|| matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
read_fdignore: !(matches.is_present("no-ignore")
|| matches.is_present("rg-alias-hidden-ignore")),
read_vcsignore: !(matches.is_present("no-ignore")
|| matches.is_present("rg-alias-hidden-ignore")
|| matches.is_present("no-ignore-vcs")),
read_global_ignore: !(matches.is_present("no-ignore")
|| matches.is_present("rg-alias-hidden-ignore")
|| matches.is_present("no-global-ignore-file")),
follow_links: matches.is_present("follow"),
ignore_hidden: matches.is_present("no-hidden")
|| !(matches.is_present("hidden")
|| matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
read_fdignore: matches.is_present("ignore")
|| !(matches.is_present("no-ignore") || matches.is_present("rg-alias-hidden-ignore")),
read_vcsignore: matches.is_present("ignore") || matches.is_present("ignore-vcs") || {
!(matches.is_present("no-ignore")
|| matches.is_present("rg-alias-hidden-ignore")
|| matches.is_present("no-ignore-vcs"))
},
read_global_ignore: matches.is_present("ignore")
|| !(matches.is_present("no-ignore")
|| matches.is_present("rg-alias-hidden-ignore")
|| matches.is_present("no-global-ignore-file")),
follow_links: matches.is_present("follow") && !matches.is_present("no-follow"),
one_file_system: matches.is_present("one-file-system"),
null_separator: matches.is_present("null_separator"),
max_depth: matches

View file

@ -4,6 +4,7 @@ use std::fs;
use std::io::Write;
use std::path::Path;
use std::time::{Duration, SystemTime};
use test_case::test_case;
use normpath::PathExt;
use regex::escape;
@ -1788,6 +1789,30 @@ fn test_number_parsing_errors() {
te.assert_failure(&["--max-results=a"]);
}
#[test_case("--hidden", &["--no-hidden"] ; "hidden")]
#[test_case("--no-ignore", &["--ignore"] ; "no-ignore")]
#[test_case("--no-ignore-vcs", &["--ignore-vcs"] ; "no-ignore-vcs")]
#[test_case("--follow", &["--no-follow"] ; "follow")]
#[test_case("--absolute-path", &["--relative-path"] ; "absolute-path")]
#[test_case("-u", &["--ignore"] ; "u")]
#[test_case("-uu", &["--ignore", "--no-hidden"] ; "uu")]
fn test_opposing(flag: &str, opposing_flags: &[&str]) {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
let mut flags = vec![flag];
flags.extend_from_slice(opposing_flags);
let out_no_flags = te.assert_success_and_get_output(".", &[]);
let out_opposing_flags = te.assert_success_and_get_output(".", &flags);
assert_eq!(
out_no_flags,
out_opposing_flags,
"{} should override {}",
opposing_flags.join(" "),
flag
);
}
/// Print error if search pattern starts with a dot and --hidden is not set
/// (Unix only, hidden files on Windows work differently)
#[test]