mirror of
https://github.com/denisidoro/navi
synced 2024-11-22 11:33:10 +00:00
Make cheat finding recursive (#403)
This commit is contained in:
parent
0e902d3230
commit
52b5271217
4 changed files with 29 additions and 67 deletions
|
@ -6,7 +6,6 @@ use anyhow::Context;
|
|||
use anyhow::Error;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub fn browse(finder: &FinderChoice) -> Result<(), Error> {
|
||||
let repo_path_str = format!("{}/featured", filesystem::tmp_path_str()?);
|
||||
|
@ -39,9 +38,8 @@ pub fn browse(finder: &FinderChoice) -> Result<(), Error> {
|
|||
pub fn add(uri: String, finder: &FinderChoice) -> Result<(), Error> {
|
||||
let (actual_uri, user, repo) = git::meta(uri.as_str());
|
||||
|
||||
let cheat_path_str = filesystem::pathbuf_to_string(filesystem::cheat_pathbuf()?)?;
|
||||
let cheat_path_str = filesystem::pathbuf_to_string(filesystem::default_cheat_pathbuf()?)?;
|
||||
let tmp_path_str = filesystem::tmp_path_str()?;
|
||||
let tmp_path_str_with_trailing_slash = format!("{}/", &tmp_path_str);
|
||||
|
||||
let _ = filesystem::remove_dir(&tmp_path_str);
|
||||
filesystem::create_dir(&tmp_path_str)?;
|
||||
|
@ -50,14 +48,7 @@ pub fn add(uri: String, finder: &FinderChoice) -> Result<(), Error> {
|
|||
|
||||
git::shallow_clone(actual_uri.as_str(), &tmp_path_str).with_context(|| format!("Failed to clone `{}`", actual_uri))?;
|
||||
|
||||
let all_files = WalkDir::new(&tmp_path_str)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.map(|e| e.path().to_str().unwrap_or("").to_string())
|
||||
.filter(|e| e.ends_with(".cheat"))
|
||||
.map(|e| e.replace(&tmp_path_str_with_trailing_slash, ""))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
let all_files = filesystem::all_cheat_files(&tmp_path_str).join("\n");
|
||||
|
||||
let opts = FinderOpts {
|
||||
suggestion_type: SuggestionType::MultipleSelections,
|
||||
|
|
|
@ -18,19 +18,6 @@ pub struct UnreadableDir {
|
|||
source: anyhow::Error,
|
||||
}
|
||||
|
||||
impl UnreadableDir {
|
||||
pub fn new<DirT, SourceError>(dir: DirT, source: SourceError) -> Self
|
||||
where
|
||||
DirT: Into<PathBuf>,
|
||||
SourceError: std::error::Error + Sync + Send + 'static,
|
||||
{
|
||||
UnreadableDir {
|
||||
dir: dir.into(),
|
||||
source: source.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_lines<P>(filename: P) -> Result<impl Iterator<Item = Result<String, Error>>, Error>
|
||||
where
|
||||
P: AsRef<Path> + Display + Copy,
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
use crate::common::filesystem::{pathbuf_to_string, read_lines, InvalidPath, UnreadableDir};
|
||||
use crate::common::filesystem::{pathbuf_to_string, read_lines};
|
||||
use crate::display::Writer;
|
||||
use crate::parser;
|
||||
use crate::structures::cheat::VariableMap;
|
||||
use anyhow::{Context, Error};
|
||||
use anyhow::Error;
|
||||
use directories_next::BaseDirs;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub fn all_cheat_files(path_str: &str) -> Vec<String> {
|
||||
let path_str_with_trailing_slash = format!("{}/", &path_str);
|
||||
|
||||
WalkDir::new(&path_str)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.map(|e| e.path().to_str().unwrap_or("").to_string())
|
||||
.filter(|e| e.ends_with(".cheat"))
|
||||
.map(|e| e.replace(&path_str_with_trailing_slash, ""))
|
||||
.collect::<Vec<String>>()
|
||||
}
|
||||
|
||||
fn paths_from_path_param<'a>(env_var: &'a str) -> impl Iterator<Item = &'a str> + 'a {
|
||||
env_var.split(':').filter(|folder| folder != &"")
|
||||
|
@ -24,7 +36,7 @@ fn read_file(
|
|||
parser::read_lines(lines, path, variables, visited_lines, writer, stdin)
|
||||
}
|
||||
|
||||
pub fn cheat_pathbuf() -> Result<PathBuf, Error> {
|
||||
pub fn default_cheat_pathbuf() -> Result<PathBuf, Error> {
|
||||
let base_dirs = BaseDirs::new().ok_or_else(|| anyhow!("Unable to get base dirs"))?;
|
||||
|
||||
let mut pathbuf = PathBuf::from(base_dirs.data_dir());
|
||||
|
@ -33,28 +45,12 @@ pub fn cheat_pathbuf() -> Result<PathBuf, Error> {
|
|||
Ok(pathbuf)
|
||||
}
|
||||
|
||||
fn cheat_paths_from_config_dir() -> Result<String, Error> {
|
||||
cheat_pathbuf()
|
||||
.and_then(pathbuf_to_string)
|
||||
.and_then(|path| {
|
||||
fs::read_dir(path.clone())
|
||||
.map_err(|e| UnreadableDir::new(path.clone(), e).into())
|
||||
.map(|entries| (path, entries))
|
||||
})
|
||||
.and_then(|(path, dir_entries)| {
|
||||
let mut paths_str = String::from("");
|
||||
for entry in dir_entries {
|
||||
let path = entry.map_err(|e| UnreadableDir::new(path.clone(), e))?;
|
||||
paths_str.push_str(path.path().into_os_string().to_str().ok_or_else(|| InvalidPath(path.path()))?);
|
||||
paths_str.push_str(":");
|
||||
}
|
||||
Ok(paths_str)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cheat_paths(path: Option<String>) -> Result<String, Error> {
|
||||
path.ok_or_else(|| anyhow!("No cheat paths"))
|
||||
.or_else(|_| cheat_paths_from_config_dir().context("No directory for cheats in user data directory"))
|
||||
if let Some(p) = path {
|
||||
Ok(p)
|
||||
} else {
|
||||
pathbuf_to_string(default_cheat_pathbuf()?)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_all(path: Option<String>, stdin: &mut std::process::ChildStdin, writer: &mut dyn Writer) -> Result<Option<VariableMap>, Error> {
|
||||
|
@ -63,10 +59,6 @@ pub fn read_all(path: Option<String>, stdin: &mut std::process::ChildStdin, writ
|
|||
let mut visited_lines = HashSet::new();
|
||||
let paths = cheat_paths(path);
|
||||
|
||||
// TODO: remove
|
||||
// read_lines(tldr::markdown_lines(), "markdown", &mut variables, &mut visited_lines, writer, stdin)?;
|
||||
// return Ok(variables);
|
||||
|
||||
if paths.is_err() {
|
||||
return Ok(None);
|
||||
};
|
||||
|
@ -75,18 +67,10 @@ pub fn read_all(path: Option<String>, stdin: &mut std::process::ChildStdin, writ
|
|||
let folders = paths_from_path_param(&paths);
|
||||
|
||||
for folder in folders {
|
||||
if let Ok(dir_entries) = fs::read_dir(folder) {
|
||||
for entry in dir_entries {
|
||||
if entry.is_ok() {
|
||||
let path = entry.expect("Impossible to read an invalid entry").path();
|
||||
let path_str = path.to_str().ok_or_else(|| InvalidPath(path.to_path_buf()))?;
|
||||
if path_str.ends_with(".cheat")
|
||||
&& read_file(path_str, &mut variables, &mut visited_lines, writer, stdin).is_ok()
|
||||
&& !found_something
|
||||
{
|
||||
found_something = true;
|
||||
}
|
||||
}
|
||||
for file in all_cheat_files(folder) {
|
||||
let full_filename = format!("{}/{}", &folder, &file);
|
||||
if read_file(&full_filename, &mut variables, &mut visited_lines, writer, stdin).is_ok() && !found_something {
|
||||
found_something = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
pub use crate::common::filesystem::{create_dir, exe_string, pathbuf_to_string, remove_dir, InvalidPath, UnreadableDir};
|
||||
use crate::display::Writer;
|
||||
use crate::fetcher;
|
||||
pub use crate::fetcher::filesystem::{cheat_pathbuf, read_all};
|
||||
pub use crate::fetcher::filesystem::{all_cheat_files, default_cheat_pathbuf, read_all};
|
||||
use crate::structures::cheat::VariableMap;
|
||||
use anyhow::Error;
|
||||
|
||||
pub fn tmp_path_str() -> Result<String, Error> {
|
||||
let cheat_path_str = pathbuf_to_string(cheat_pathbuf()?)?;
|
||||
let cheat_path_str = pathbuf_to_string(default_cheat_pathbuf()?)?;
|
||||
Ok(format!("{}/tmp", cheat_path_str))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue