Make cheat finding recursive (#403)

This commit is contained in:
Denis Isidoro 2020-09-14 09:40:20 -03:00 committed by GitHub
parent 0e902d3230
commit 52b5271217
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 67 deletions

View file

@ -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,

View file

@ -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,

View file

@ -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
}
}
}

View file

@ -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))
}