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 std::path::Path;
impl Run for Add {
fn run(&self) -> Result<()> {
let path = if config::zo_resolve_symlinks() {
let path = if config::resolve_symlinks() {
util::canonicalize(&self.path)
} else {
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 now = util::current_time()?;
let data_dir = config::zo_data_dir()?;
let max_age = config::zo_maxage()?;
// These characters can't be printed cleanly to a single line, so they
// 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 = db.open()?;
db.add(path, now);
db.age(max_age);

View File

@ -10,7 +10,7 @@ use std::path::Path;
impl Run for Import {
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 db = &mut db.open()?;

View File

@ -12,8 +12,8 @@ impl Run for Init {
fn run(&self) -> Result<()> {
let cmd = if self.no_aliases { None } else { Some(self.cmd.as_str()) };
let echo = config::zo_echo();
let resolve_symlinks = config::zo_resolve_symlinks();
let echo = config::echo();
let resolve_symlinks = config::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 {
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 = db.open()?;
let now = util::current_time()?;
let mut stream = db.stream(now).with_keywords(&self.keywords);
if !self.all {
let resolve_symlinks = config::zo_resolve_symlinks();
let resolve_symlinks = config::resolve_symlinks();
stream = stream.with_exists(resolve_symlinks);
}
if let Some(path) = &self.exclude {

View File

@ -11,7 +11,7 @@ use std::io::Write;
impl Run for Remove {
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 = db.open()?;

View File

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

View File

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

View File

@ -89,7 +89,6 @@ impl<'db, 'file> Stream<'db, 'file> {
if !self.check_exists {
return true;
}
let resolver = if self.resolve_symlinks { fs::symlink_metadata } else { fs::metadata };
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("-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);
}