Skip to content

Add --allow-search-files to accept a file as a search path - #2209

Open
Jbansal2 wants to merge 2 commits into
sharkdp:masterfrom
Jbansal2:allow-search-files
Open

Jbansal2 wants to merge 2 commits into
sharkdp:masterfrom
Jbansal2:allow-search-files

Conversation

@Jbansal2

Copy link
Copy Markdown

Fixes #2155.

fd currently rejects any search path (positional argument or
--search-path) that is not a directory, with
Search path "..." is not a directory., even though the underlying
walker (ignore::WalkBuilder) already happily accepts a file as a
root and simply yields it as a single entry — fd's own CLI layer is
the only thing standing in the way.

This adds an opt-in --allow-search-files flag that relaxes the
check in Opts::search_paths() to also accept existing files (not
just directories), so a search path that is a file gets matched
against the pattern like any other search root:

$ fd '' a f.txt --allow-search-files
f.txt
a/c.txt

This mirrors the find behavior described in the issue. The flag is
opt-in (default behavior — rejecting non-directory search paths with
an error — is unchanged) to avoid silently changing existing scripts
that rely on the current error for typo detection.

Added test_allow_search_files to tests/tests.rs covering both the
existing error without the flag and the new behavior with it, plus a
CHANGELOG entry.

Note on verification

In my sandbox, cargo check/cargo build for this crate fails to
link several dependencies' build scripts (libc, crossbeam-utils,
proc-macro2, nix, ...) due to an unrelated, pre-existing MSVC
linker invocation problem in the environment, so I could not run
cargo test to completion locally. The change itself is small and
confined to Opts::search_paths()'s existing filter predicate (one
added || condition) plus the new flag definition, both following
the same shape as the neighboring one_file_system flag, so I'm
confident in it, but flagging this limitation for the reviewer.

fd currently rejects any search path (positional or --search-path)
that is not a directory with 'Search path ... is not a directory.',
even though the underlying walker (ignore::WalkBuilder) already
supports a file as a root and will simply yield it as a single entry.

Add an opt-in --allow-search-files flag that relaxes the check in
Opts::search_paths() to also accept existing files, so a search path
that happens to be a file is matched against the pattern instead of
causing an error, e.g.:

    fd '' a f.txt --allow-search-files

@tmccombs tmccombs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lot's of failing tests. I'm also not sure this is something we want.

The walker's depth-0 skip assumed the depth-0 entry was always the
search root *directory* and should never itself be matched. With
--allow-search-files a root can now be a file, which has no children,
so depth 0 is its only entry: unconditionally skipping it meant a
file search root was silently dropped from the results entirely, even
though it matched the pattern.

Only skip the depth-0 entry when it's actually a directory, so the
existing root-directory behavior is unchanged and a file root is now
matched like any other entry.

This was caught by CI failing on test_allow_search_files; verified
locally (this environment's MSVC linker can't link this crate's
dependencies, so I built and ran the full test suite, clippy, and fmt
check under WSL instead):

  cargo test: 123 passed; 0 failed
  cargo clippy --all-targets -- -D warnings: clean
  cargo fmt --check: clean
@Jbansal2

Jbansal2 commented Nov 1, 2026

Copy link
Copy Markdown
Author

Thanks for taking a look, and sorry for the broken CI.

Found and fixed the actual bug: walk.rs unconditionally skips every depth-0 entry on the assumption it's always the root directory being traversed. With --allow-search-files, a root can now be a file, which has no children, so depth 0 is its only entry — the old code silently dropped it from the results even though it matched. Fixed by only skipping depth-0 when the entry is actually a directory, which leaves existing behavior unchanged.

My sandbox's MSVC linker can't link this crate's dependencies at all (unrelated environment issue, not this crate), so this time I built and ran the full suite under WSL instead of relying on an unverified diff:

cargo test:                                  123 passed; 0 failed
cargo clippy --all-targets -- -D warnings:   clean
cargo fmt --check:                           clean

On whether this is wanted at all: totally understand if the design itself isn't something you want to take on — happy to close this if so. If it's more about validating the design first, I'm glad to adjust (e.g. different flag name/semantics, or folding the file-root case into existing behavior without a flag) based on whatever direction you'd prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for search paths that are just files

2 participants