Ignore directories with \r and \n in path

This commit is contained in:
Ajeet D'Souza 2021-05-27 11:39:57 +05:30
parent d39c9a1fc6
commit 9ef2ef5a6d
9 changed files with 47 additions and 44 deletions

View File

@ -5,29 +5,35 @@ use crate::util;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use std::path::Path;
impl Run for Add { impl Run for Add {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let path = if config::zo_resolve_symlinks() { let path = if config::resolve_symlinks() {
util::canonicalize(&self.path) util::canonicalize(&self.path)
} else { } else {
util::resolve_path(&self.path) util::resolve_path(&self.path)
}?; }?;
if config::zo_exclude_dirs()?.iter().any(|pattern| pattern.matches_path(&path)) {
return Ok(());
}
if !path.is_dir() {
bail!("not a directory: {}", path.display());
}
let path = util::path_to_str(&path)?; let path = util::path_to_str(&path)?;
let now = util::current_time()?; let now = util::current_time()?;
let data_dir = config::zo_data_dir()?; // These characters can't be printed cleanly to a single line, so they
let max_age = config::zo_maxage()?; // can cause confusion when writing to fzf / stdout.
const EXCLUDE_CHARS: &[char] = &['\n', '\r'];
let mut exclude_dirs = config::exclude_dirs()?.into_iter();
if exclude_dirs.any(|pattern| pattern.matches(path)) || path.contains(EXCLUDE_CHARS) {
return Ok(());
}
if !Path::new(path).is_dir() {
bail!("not a directory: {}", path);
}
let data_dir = config::data_dir()?;
let max_age = config::maxage()?;
let mut db = DatabaseFile::new(data_dir); let mut db = DatabaseFile::new(data_dir);
let mut db = db.open()?; let mut db = db.open()?;
db.add(path, now); db.add(path, now);
db.age(max_age); db.age(max_age);

View File

@ -10,7 +10,7 @@ use std::path::Path;
impl Run for Import { impl Run for Import {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let data_dir = config::zo_data_dir()?; let data_dir = config::data_dir()?;
let mut db = DatabaseFile::new(data_dir); let mut db = DatabaseFile::new(data_dir);
let db = &mut db.open()?; let db = &mut db.open()?;

View File

@ -12,8 +12,8 @@ impl Run for Init {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let cmd = if self.no_aliases { None } else { Some(self.cmd.as_str()) }; let cmd = if self.no_aliases { None } else { Some(self.cmd.as_str()) };
let echo = config::zo_echo(); let echo = config::echo();
let resolve_symlinks = config::zo_resolve_symlinks(); let resolve_symlinks = config::resolve_symlinks();
let opts = &Opts { cmd, hook: self.hook, echo, resolve_symlinks }; let opts = &Opts { cmd, hook: self.hook, echo, resolve_symlinks };

View File

@ -11,14 +11,14 @@ use std::io::{self, Write};
impl Run for Query { impl Run for Query {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let data_dir = config::zo_data_dir()?; let data_dir = config::data_dir()?;
let mut db = DatabaseFile::new(data_dir); let mut db = DatabaseFile::new(data_dir);
let mut db = db.open()?; let mut db = db.open()?;
let now = util::current_time()?; let now = util::current_time()?;
let mut stream = db.stream(now).with_keywords(&self.keywords); let mut stream = db.stream(now).with_keywords(&self.keywords);
if !self.all { if !self.all {
let resolve_symlinks = config::zo_resolve_symlinks(); let resolve_symlinks = config::resolve_symlinks();
stream = stream.with_exists(resolve_symlinks); stream = stream.with_exists(resolve_symlinks);
} }
if let Some(path) = &self.exclude { if let Some(path) = &self.exclude {

View File

@ -11,7 +11,7 @@ use std::io::Write;
impl Run for Remove { impl Run for Remove {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let data_dir = config::zo_data_dir()?; let data_dir = config::data_dir()?;
let mut db = DatabaseFile::new(data_dir); let mut db = DatabaseFile::new(data_dir);
let mut db = db.open()?; let mut db = db.open()?;

View File

@ -8,68 +8,67 @@ use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::path::PathBuf; use std::path::PathBuf;
pub fn zo_data_dir() -> Result<PathBuf> { pub fn data_dir() -> Result<PathBuf> {
let data_dir = match env::var_os("_ZO_DATA_DIR") { let path = match env::var_os("_ZO_DATA_DIR") {
Some(data_osstr) => PathBuf::from(data_osstr), Some(path) => PathBuf::from(path),
None => match dirs::data_local_dir() { None => match dirs::data_local_dir() {
Some(mut data_dir) => { Some(mut path) => {
data_dir.push("zoxide"); path.push("zoxide");
data_dir path
} }
None => bail!("could not find data directory, please set _ZO_DATA_DIR manually"), None => bail!("could not find data directory, please set _ZO_DATA_DIR manually"),
}, },
}; };
Ok(data_dir) Ok(path)
} }
pub fn zo_echo() -> bool { pub fn echo() -> bool {
match env::var_os("_ZO_ECHO") { match env::var_os("_ZO_ECHO") {
Some(var) => var == "1", Some(var) => var == "1",
None => false, None => false,
} }
} }
pub fn zo_exclude_dirs() -> Result<Vec<Pattern>> { pub fn exclude_dirs() -> Result<Vec<Pattern>> {
match env::var_os("_ZO_EXCLUDE_DIRS") { match env::var_os("_ZO_EXCLUDE_DIRS") {
Some(dirs_osstr) => env::split_paths(&dirs_osstr) Some(paths) => env::split_paths(&paths)
.map(|path| { .map(|path| {
let pattern = path.to_str().context("invalid unicode in _ZO_EXCLUDE_DIRS")?; let pattern = path.to_str().context("invalid unicode in _ZO_EXCLUDE_DIRS")?;
Pattern::new(&pattern) Pattern::new(pattern)
.with_context(|| format!("invalid glob in _ZO_EXCLUDE_DIRS: {}", pattern)) .with_context(|| format!("invalid glob in _ZO_EXCLUDE_DIRS: {}", pattern))
}) })
.collect(), .collect(),
None => { None => {
let pattern = (|| { let pattern = (|| {
let home = dirs::home_dir()?; let home = dirs::home_dir()?;
let home_str = home.to_str()?; let home = home.to_str()?;
let home_esc = Pattern::escape(home_str); let home = Pattern::escape(home);
Pattern::new(&home_esc).ok() Pattern::new(&home).ok()
})(); })();
Ok(pattern.into_iter().collect()) Ok(pattern.into_iter().collect())
} }
} }
} }
pub fn zo_fzf_opts() -> Option<OsString> { pub fn fzf_opts() -> Option<OsString> {
env::var_os("_ZO_FZF_OPTS") env::var_os("_ZO_FZF_OPTS")
} }
pub fn zo_maxage() -> Result<Rank> { pub fn maxage() -> Result<Rank> {
match env::var_os("_ZO_MAXAGE") { match env::var_os("_ZO_MAXAGE") {
Some(maxage_osstr) => { Some(maxage) => {
let maxage_str = maxage_osstr.to_str().context("invalid unicode in _ZO_MAXAGE")?; let maxage = maxage.to_str().context("invalid unicode in _ZO_MAXAGE")?;
let maxage = maxage_str.parse::<u64>().with_context(|| { let maxage = maxage
format!("unable to parse _ZO_MAXAGE as integer: {}", maxage_str) .parse::<u64>()
})?; .with_context(|| format!("unable to parse _ZO_MAXAGE as integer: {}", maxage))?;
Ok(maxage as Rank) Ok(maxage as Rank)
} }
None => Ok(10000.0), None => Ok(10000.0),
} }
} }
pub fn zo_resolve_symlinks() -> bool { pub fn resolve_symlinks() -> bool {
match env::var_os("_ZO_RESOLVE_SYMLINKS") { match env::var_os("_ZO_RESOLVE_SYMLINKS") {
Some(var) => var == "1", Some(var) => var == "1",
None => false, None => false,

View File

@ -7,7 +7,6 @@ pub use stream::Stream;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use tempfile::{NamedTempFile, PersistError}; use tempfile::{NamedTempFile, PersistError};
use std::borrow::Cow;
use std::fs; use std::fs;
use std::io::{self, Write}; use std::io::{self, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -51,7 +50,7 @@ impl<'file> Database<'file> {
match self.dirs.iter_mut().find(|dir| dir.path == path) { match self.dirs.iter_mut().find(|dir| dir.path == path) {
None => { None => {
self.dirs.push(Dir { path: Cow::Owned(path.into()), last_accessed: now, rank: 1.0 }) self.dirs.push(Dir { path: path.to_string().into(), last_accessed: now, rank: 1.0 })
} }
Some(dir) => { Some(dir) => {
dir.last_accessed = now; dir.last_accessed = now;

View File

@ -89,7 +89,6 @@ impl<'db, 'file> Stream<'db, 'file> {
if !self.check_exists { if !self.check_exists {
return true; return true;
} }
let resolver = if self.resolve_symlinks { fs::symlink_metadata } else { fs::metadata }; let resolver = if self.resolve_symlinks { fs::symlink_metadata } else { fs::metadata };
resolver(path.as_ref()).map(|m| m.is_dir()).unwrap_or_default() resolver(path.as_ref()).map(|m| m.is_dir()).unwrap_or_default()
} }

View File

@ -17,7 +17,7 @@ impl Fzf {
command.arg("-m"); command.arg("-m");
} }
command.arg("-n2..").stdin(Stdio::piped()).stdout(Stdio::piped()); command.arg("-n2..").stdin(Stdio::piped()).stdout(Stdio::piped());
if let Some(fzf_opts) = config::zo_fzf_opts() { if let Some(fzf_opts) = config::fzf_opts() {
command.env("FZF_DEFAULT_OPTS", fzf_opts); command.env("FZF_DEFAULT_OPTS", fzf_opts);
} }