mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 01:30:21 -07:00
cli: make ripgrep work in non-existent directories
It turns out that querying the CWD while in a directory that no longer exists results in an error. Since the CWD is queried every time ripgrep starts---whether it needs it or not---for dealing with glob matching, ripgrep winds up being completely useless inside a non-existent directory. We fix this in a few different ways: * Firstly, if std::env::current_dir() fails, then we fall back to trying to read the `PWD` environment variable. * If that fails, that we return a more sensible error message so that a user can at least react to the problem. Previously, the error message was inscrutable. * Finally, we try to avoid the problem altogether by building empty glob matchers if not globs were provided, thus side-stepping querying the CWD completely. Fixes #1291, Closes #1400
This commit is contained in:
parent
297b428c8c
commit
0c3b673e4c
@ -28,6 +28,8 @@ Feature enhancements:
|
|||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #1291](https://github.com/BurntSushi/ripgrep/issues/1291):
|
||||||
|
ripgrep now works in non-existent directories.
|
||||||
* [BUG #1335](https://github.com/BurntSushi/ripgrep/issues/1335):
|
* [BUG #1335](https://github.com/BurntSushi/ripgrep/issues/1335):
|
||||||
Fixes a performance bug when searching plain text files with very long lines.
|
Fixes a performance bug when searching plain text files with very long lines.
|
||||||
* [BUG #1344](https://github.com/BurntSushi/ripgrep/issues/1344):
|
* [BUG #1344](https://github.com/BurntSushi/ripgrep/issues/1344):
|
||||||
|
42
src/args.rs
42
src/args.rs
@ -1277,17 +1277,23 @@ impl ArgMatches {
|
|||||||
|
|
||||||
/// Builds the set of glob overrides from the command line flags.
|
/// Builds the set of glob overrides from the command line flags.
|
||||||
fn overrides(&self) -> Result<Override> {
|
fn overrides(&self) -> Result<Override> {
|
||||||
let mut builder = OverrideBuilder::new(env::current_dir()?);
|
let globs = self.values_of_lossy_vec("glob");
|
||||||
|
let iglobs = self.values_of_lossy_vec("iglob");
|
||||||
|
if globs.is_empty() && iglobs.is_empty() {
|
||||||
|
return Ok(Override::empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut builder = OverrideBuilder::new(current_dir()?);
|
||||||
// Make all globs case insensitive with --glob-case-insensitive.
|
// Make all globs case insensitive with --glob-case-insensitive.
|
||||||
if self.is_present("glob-case-insensitive") {
|
if self.is_present("glob-case-insensitive") {
|
||||||
builder.case_insensitive(true).unwrap();
|
builder.case_insensitive(true).unwrap();
|
||||||
}
|
}
|
||||||
for glob in self.values_of_lossy_vec("glob") {
|
for glob in globs {
|
||||||
builder.add(&glob)?;
|
builder.add(&glob)?;
|
||||||
}
|
}
|
||||||
// This only enables case insensitivity for subsequent globs.
|
// This only enables case insensitivity for subsequent globs.
|
||||||
builder.case_insensitive(true).unwrap();
|
builder.case_insensitive(true).unwrap();
|
||||||
for glob in self.values_of_lossy_vec("iglob") {
|
for glob in iglobs {
|
||||||
builder.add(&glob)?;
|
builder.add(&glob)?;
|
||||||
}
|
}
|
||||||
Ok(builder.build()?)
|
Ok(builder.build()?)
|
||||||
@ -1489,8 +1495,12 @@ impl ArgMatches {
|
|||||||
/// flag. If no --pre-globs are available, then this always returns an
|
/// flag. If no --pre-globs are available, then this always returns an
|
||||||
/// empty set of globs.
|
/// empty set of globs.
|
||||||
fn preprocessor_globs(&self) -> Result<Override> {
|
fn preprocessor_globs(&self) -> Result<Override> {
|
||||||
let mut builder = OverrideBuilder::new(env::current_dir()?);
|
let globs = self.values_of_lossy_vec("pre-glob");
|
||||||
for glob in self.values_of_lossy_vec("pre-glob") {
|
if globs.is_empty() {
|
||||||
|
return Ok(Override::empty());
|
||||||
|
}
|
||||||
|
let mut builder = OverrideBuilder::new(current_dir()?);
|
||||||
|
for glob in globs {
|
||||||
builder.add(&glob)?;
|
builder.add(&glob)?;
|
||||||
}
|
}
|
||||||
Ok(builder.build()?)
|
Ok(builder.build()?)
|
||||||
@ -1794,3 +1804,25 @@ where I: IntoIterator<Item=T>,
|
|||||||
let _ = write!(io::stdout(), "{}", err);
|
let _ = write!(io::stdout(), "{}", err);
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to discover the current working directory. This mostly just defers
|
||||||
|
/// to the standard library, however, such things will fail if ripgrep is in
|
||||||
|
/// a directory that no longer exists. We attempt some fallback mechanisms,
|
||||||
|
/// such as querying the PWD environment variable, but otherwise return an
|
||||||
|
/// error.
|
||||||
|
fn current_dir() -> Result<PathBuf> {
|
||||||
|
let err = match env::current_dir() {
|
||||||
|
Err(err) => err,
|
||||||
|
Ok(cwd) => return Ok(cwd),
|
||||||
|
};
|
||||||
|
if let Some(cwd) = env::var_os("PWD") {
|
||||||
|
if !cwd.is_empty() {
|
||||||
|
return Ok(PathBuf::from(cwd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(format!(
|
||||||
|
"failed to get current working directory: {} \
|
||||||
|
--- did your CWD get deleted?",
|
||||||
|
err,
|
||||||
|
).into())
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user