Skip to content

Commit

Permalink
Refactor fetcher packages (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
denisidoro authored Apr 5, 2021
1 parent 3870cd7 commit b2816e9
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/cheatsh.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::display::Writer;
use crate::fetcher;
use crate::parser;
use crate::structures::cheat::VariableMap;
use crate::structures::fetcher;
use anyhow::Context;
use anyhow::Error;
use std::collections::HashSet;
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/alfred.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::display;
use crate::fetcher::Fetcher;
use crate::filesystem;
use crate::shell::BashSpawnError;
use crate::structures::cheat::Suggestion;
use crate::structures::config::Config;
use crate::structures::fetcher::Fetcher;
use anyhow::Context;
use anyhow::Error;
use std::env;
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use crate::cheatsh;
use crate::display;

use crate::extractor;
use crate::fetcher::Fetcher;
use crate::filesystem;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use crate::finder::Finder;
use crate::structures::fetcher::Fetcher;

use crate::structures::cheat::VariableMap;

Expand Down
167 changes: 164 additions & 3 deletions src/filesystem.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,170 @@
use crate::display::Writer;
use crate::fetcher;
pub use crate::fetcher::filesystem::{all_cheat_files, default_cheat_pathbuf, read_all};
pub use crate::fs::{create_dir, exe_string, pathbuf_to_string, remove_dir, InvalidPath, UnreadableDir};
pub use crate::fs::{
create_dir, exe_string, pathbuf_to_string, read_lines, remove_dir, InvalidPath, UnreadableDir,
};
use crate::parser;
use crate::structures::cheat::VariableMap;
use crate::structures::fetcher;
use anyhow::Error;
use directories_next::BaseDirs;
use std::collections::HashSet;
use std::path::PathBuf;
use walkdir::WalkDir;

pub fn all_cheat_files(path_str: &str) -> Vec<String> {
let path_str_with_trailing_slash = if path_str.ends_with('/') {
path_str.to_string()
} else {
format!("{}/", &path_str)
};

WalkDir::new(&path_str)
.follow_links(true)
.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(env_var: &str) -> impl Iterator<Item = &str> {
env_var.split(':').filter(|folder| folder != &"")
}

// TODO: move
fn read_file(
path: &str,
file_index: usize,
variables: &mut VariableMap,
visited_lines: &mut HashSet<u64>,
writer: &mut dyn Writer,
stdin: &mut std::process::ChildStdin,
) -> Result<(), Error> {
let lines = read_lines(path)?;
parser::read_lines(lines, path, file_index, variables, visited_lines, writer, stdin)
}

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());
pathbuf.push("navi");
pathbuf.push("cheats");
Ok(pathbuf)
}

pub fn cheat_paths(path: Option<String>) -> Result<String, Error> {
if let Some(p) = path {
Ok(p)
} else {
pathbuf_to_string(default_cheat_pathbuf()?)
}
}

pub fn read_all(
path: Option<String>,
files: &mut Vec<String>,
stdin: &mut std::process::ChildStdin,
writer: &mut dyn Writer,
) -> Result<Option<VariableMap>, Error> {
let mut variables = VariableMap::new();
let mut found_something = false;
let mut visited_lines = HashSet::new();
let paths = cheat_paths(path);

if paths.is_err() {
return Ok(None);
};

let paths = paths.expect("Unable to get paths");
let folders = paths_from_path_param(&paths);

for folder in folders {
for file in all_cheat_files(folder) {
let full_filename = format!("{}/{}", &folder, &file);
files.push(full_filename.clone());
let index = files.len() - 1;
if read_file(
&full_filename,
index,
&mut variables,
&mut visited_lines,
writer,
stdin,
)
.is_ok()
&& !found_something
{
found_something = true
}
}
}

if !found_something {
return Ok(None);
}

Ok(Some(variables))
}

#[cfg(test)]
mod tests {
use super::*;
use crate::display;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use std::process::{Command, Stdio};

#[test]
fn test_read_file() {
let path = "tests/cheats/ssh.cheat";
let mut variables = VariableMap::new();
let mut child = Command::new("cat")
.stdin(Stdio::piped())
.stdout(Stdio::null())
.spawn()
.unwrap();
let child_stdin = child.stdin.as_mut().unwrap();
let mut visited_lines: HashSet<u64> = HashSet::new();
let mut writer: Box<dyn Writer> = Box::new(display::terminal::Writer::new());
read_file(
path,
0,
&mut variables,
&mut visited_lines,
&mut *writer,
child_stdin,
)
.unwrap();
let expected_suggestion = (
r#" echo -e "$(whoami)\nroot" "#.to_string(),
Some(FinderOpts {
header_lines: 0,
column: None,
delimiter: None,
suggestion_type: SuggestionType::SingleSelection,
..Default::default()
}),
);
let actual_suggestion = variables.get_suggestion("ssh", "user");
assert_eq!(Some(&expected_suggestion), actual_suggestion);
}

#[test]
fn splitting_of_dirs_param_may_not_contain_empty_items() {
// Trailing colon indicates potential extra path. Split returns an empty item for it. This empty item should be filtered away, which is what this test checks.
let given_path_config = "SOME_PATH:ANOTHER_PATH:";

let found_paths = paths_from_path_param(given_path_config);

let mut expected_paths = vec!["SOME_PATH", "ANOTHER_PATH"].into_iter();

for found in found_paths {
let expected = expected_paths.next().unwrap();
assert_eq!(found, expected)
}
}
}

pub fn tmp_path_str() -> Result<String, Error> {
let cheat_path_str = pathbuf_to_string(default_cheat_pathbuf()?)?;
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ mod cmds;
mod display;
mod env_vars;
mod extractor;
mod fetcher;
mod filesystem;
mod finder;
mod fs;
Expand Down
2 changes: 0 additions & 2 deletions src/fetcher/mod.rs → src/structures/fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
pub mod filesystem;

use crate::display::Writer;
use crate::structures::cheat::VariableMap;
use anyhow::Error;
Expand Down
1 change: 1 addition & 0 deletions src/structures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod cheat;
pub mod config;
pub mod fetcher;
pub mod item;
2 changes: 1 addition & 1 deletion src/tldr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::display::Writer;
use crate::fetcher;
use crate::parser;
use crate::structures::cheat::VariableMap;
use crate::structures::fetcher;
use anyhow::{Context, Error};
use regex::Regex;
use std::collections::HashSet;
Expand Down

0 comments on commit b2816e9

Please # to comment.