mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-09 09:49:10 +02:00
commit
ec28d48bea
5 changed files with 119 additions and 30 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -11,6 +11,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.3.2 (git+https://github.com/dbrgn/tar-rs?branch=pax_header)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -292,6 +293,15 @@ dependencies = [
|
|||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.5"
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ env_logger = { version = "^0.3", optional = true }
|
|||
rustc-serialize = "^0.3"
|
||||
docopt = "^0.6"
|
||||
time = "^0.1"
|
||||
walkdir = "^0.1"
|
||||
|
|
|
|||
76
src/cache.rs
76
src/cache.rs
|
|
@ -8,6 +8,7 @@ use std::path::PathBuf;
|
|||
use flate2::read::GzDecoder;
|
||||
use tar::Archive;
|
||||
use curl::http;
|
||||
use walkdir::{WalkDir, WalkDirIterator, DirEntry};
|
||||
use time;
|
||||
|
||||
use error::TldrError::{self, CacheError, UpdateError};
|
||||
|
|
@ -90,24 +91,29 @@ impl Cache {
|
|||
None
|
||||
}
|
||||
|
||||
/// Return the platform directory.
|
||||
fn get_platform_dir(&self) -> Option<&'static str> {
|
||||
match self.os {
|
||||
OsType::Linux => Some("linux"),
|
||||
OsType::OsX => Some("osx"),
|
||||
OsType::SunOs => None, // TODO: Does Rust support SunOS?
|
||||
OsType::Other => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Search for a page and return the path to it.
|
||||
pub fn find_page(&self, name: &str) -> Option<PathBuf> {
|
||||
// Build page file name
|
||||
let page_filename = format!("{}.md", name);
|
||||
|
||||
// Get platform dir
|
||||
let cache_dir = match self.get_cache_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(_) => return None,
|
||||
let platforms_dir = match self.get_cache_dir() {
|
||||
Ok(cache_dir) => cache_dir.join("tldr-master").join("pages"),
|
||||
_ => return None,
|
||||
};
|
||||
let platforms_dir = cache_dir.join("tldr-master").join("pages");
|
||||
|
||||
// Determine platform
|
||||
let platform = match self.os {
|
||||
OsType::Linux => Some("linux"),
|
||||
OsType::OsX => Some("osx"),
|
||||
OsType::SunOs => None, // TODO: Does Rust support SunOS?
|
||||
OsType::Other => None,
|
||||
};
|
||||
let platform = self.get_platform_dir();
|
||||
|
||||
// Search for the page in the platform specific directory
|
||||
if let Some(pf) = platform {
|
||||
|
|
@ -129,6 +135,56 @@ impl Cache {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the available pages.
|
||||
pub fn list_pages(&self) -> Result<Vec<String>, TldrError> {
|
||||
|
||||
// Determine platforms directory and platform
|
||||
let cache_dir = try!(self.get_cache_dir());
|
||||
let platforms_dir = cache_dir.join("tldr-master").join("pages");
|
||||
let platform_dir = self.get_platform_dir();
|
||||
|
||||
// Closure that allows the WalkDir instance to traverse platform
|
||||
// specific and common page directories, but not others.
|
||||
let should_walk = |entry: &DirEntry| -> bool {
|
||||
let file_type = entry.file_type();
|
||||
let file_name = match entry.file_name().to_str() {
|
||||
Some(name) => name,
|
||||
None => return false,
|
||||
};
|
||||
if file_type.is_dir() {
|
||||
if file_name == "common" {
|
||||
return true;
|
||||
}
|
||||
if let Some(platform) = platform_dir {
|
||||
return file_name == platform;
|
||||
}
|
||||
} else if file_type.is_file() {
|
||||
return true
|
||||
}
|
||||
false
|
||||
};
|
||||
|
||||
// Recursively walk through common and (if applicable) platform specific directory
|
||||
let mut pages = WalkDir::new(platforms_dir)
|
||||
.min_depth(1) // Skip root directory
|
||||
.into_iter()
|
||||
.filter_entry(|e| should_walk(e)) // Filter out pages for other architectures
|
||||
.filter_map(|e| e.ok()) // Convert results to options, filter out errors
|
||||
.filter_map(|e| {
|
||||
let path = e.path();
|
||||
let extension = &path.extension().and_then(|s| s.to_str()).unwrap_or("");
|
||||
if e.file_type().is_file() && extension == &"md" {
|
||||
path.file_stem().and_then(|stem| stem.to_str().map(|s| s.into()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
pages.sort();
|
||||
pages.dedup();
|
||||
Ok(pages)
|
||||
}
|
||||
|
||||
/// Delete the cache directory.
|
||||
pub fn clear(&self) -> Result<(), TldrError> {
|
||||
let path = try!(self.get_cache_dir());
|
||||
|
|
|
|||
60
src/main.rs
60
src/main.rs
|
|
@ -9,6 +9,7 @@ extern crate tar;
|
|||
extern crate curl;
|
||||
extern crate rustc_serialize;
|
||||
extern crate time;
|
||||
extern crate walkdir;
|
||||
|
||||
use std::io::BufReader;
|
||||
use std::fs::File;
|
||||
|
|
@ -16,6 +17,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::process;
|
||||
|
||||
use docopt::Docopt;
|
||||
use ansi_term::Colour;
|
||||
|
||||
mod types;
|
||||
mod tokenizer;
|
||||
|
|
@ -95,6 +97,27 @@ fn print_page(path: &Path) -> Result<(), String> {
|
|||
}
|
||||
|
||||
|
||||
/// Check the cache for freshness
|
||||
fn check_cache(args: &Args, cache: &Cache) {
|
||||
if !args.flag_update {
|
||||
match cache.last_update() {
|
||||
Some(ago) if ago > MAX_CACHE_AGE => {
|
||||
println!("{}", Colour::Red.paint(format!(
|
||||
"Cache wasn't updated in {} days.\n\
|
||||
You should probably run `tldr --update` soon.\n",
|
||||
MAX_CACHE_AGE / 24 / 3600
|
||||
)));
|
||||
},
|
||||
None => {
|
||||
println!("Cache not found. Please run `tldr --update`.");
|
||||
process::exit(1);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "logging")]
|
||||
fn init_log() {
|
||||
env_logger::init().unwrap();
|
||||
|
|
@ -162,7 +185,7 @@ fn main() {
|
|||
}
|
||||
|
||||
// Render local file and exit
|
||||
if let Some(file) = args.flag_render {
|
||||
if let Some(ref file) = args.flag_render {
|
||||
let path = PathBuf::from(file);
|
||||
if let Err(msg) = print_page(&path) {
|
||||
println!("{}", msg);
|
||||
|
|
@ -174,27 +197,26 @@ fn main() {
|
|||
|
||||
// List cached commands and exit
|
||||
if args.flag_list {
|
||||
println!("Flag --list not yet implemented.");
|
||||
process::exit(1);
|
||||
// Check cache for freshness
|
||||
check_cache(&args, &cache);
|
||||
|
||||
// Get list of pages
|
||||
let pages = cache.list_pages().unwrap_or_else(|e| {
|
||||
match e {
|
||||
UpdateError(msg) | CacheError(msg) => println!("Could not get list of pages: {}", msg),
|
||||
}
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
// Print pages
|
||||
println!("{}", pages.join(", "));
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
// Show command from cache
|
||||
if let Some(command) = args.arg_command {
|
||||
|
||||
// Check cache
|
||||
if !args.flag_update {
|
||||
match cache.last_update() {
|
||||
Some(ago) if ago > MAX_CACHE_AGE => {
|
||||
println!("Cache wasn't updated in {} days.", MAX_CACHE_AGE / 24 / 3600);
|
||||
println!("You should probably run `tldr --update` soon.");
|
||||
},
|
||||
None => {
|
||||
println!("Cache not found. Please run `tldr --update`.");
|
||||
process::exit(1);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
if let Some(ref command) = args.arg_command {
|
||||
// Check cache for freshness
|
||||
check_cache(&args, &cache);
|
||||
|
||||
// Search for command in cache
|
||||
if let Some(path) = cache.find_page(&command) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use rustc_serialize::{Decodable, Decoder};
|
||||
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub enum OsType {
|
||||
Linux,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue