diff --git a/Cargo.lock b/Cargo.lock index 138dcff..3d9a346 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,12 +98,39 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cc" version = "1.0.70" @@ -821,6 +848,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -1232,7 +1265,6 @@ dependencies = [ "env_logger", "escargot", "filetime", - "flate2", "log", "pager", "predicates", @@ -1243,6 +1275,7 @@ dependencies = [ "tempfile", "toml", "walkdir", + "zip", ] [[package]] @@ -1288,6 +1321,16 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "tinyvec" version = "1.4.0" @@ -1617,3 +1660,17 @@ name = "xdg" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] diff --git a/Cargo.toml b/Cargo.toml index 0a603a4..31e16b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" docopt = "1" env_logger = { version = "0.9", optional = true } -flate2 = "1" log = "0.4" reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } serde = "1.0.21" @@ -29,6 +28,7 @@ serde_derive = "1.0.21" tar = "0.4.14" toml = "0.5.1" walkdir = "2.0.1" +zip = "0.5" [target.'cfg(not(windows))'.dependencies] pager = "0.16" diff --git a/src/cache.rs b/src/cache.rs index bdae9dc..7b682e2 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -2,18 +2,17 @@ use std::{ env, ffi::OsStr, fs, - io::Read, + io::{Cursor, Read, Seek}, iter, path::{Path, PathBuf}, }; use app_dirs::{get_app_root, AppDataType}; -use flate2::read::GzDecoder; use log::debug; use reqwest::{blocking::Client, Proxy}; use std::time::{Duration, SystemTime}; -use tar::Archive; use walkdir::{DirEntry, WalkDir}; +use zip::ZipArchive; use crate::{ error::TealdeerError::{self, CacheError, UpdateError}, @@ -22,6 +21,9 @@ use crate::{ static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR"; +pub static TLDR_PAGES_DIR: &str = "tldr-pages"; +static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; + #[derive(Debug)] pub struct Cache { url: String, @@ -133,8 +135,8 @@ impl Cache { } /// Decompress and open the archive - fn decompress(reader: R) -> Archive> { - Archive::new(GzDecoder::new(reader)) + fn decompress(reader: R) -> ZipArchive { + ZipArchive::new(reader).unwrap() } /// Update the pages cache. @@ -143,10 +145,11 @@ impl Cache { let bytes: Vec = self.download()?; // Decompress the response body into an `Archive` - let mut archive = Self::decompress(&bytes[..]); + let mut archive = Self::decompress(Cursor::new(bytes)); // Determine paths let (cache_dir, _) = Self::get_cache_dir()?; + let pages_dir = cache_dir.join(TLDR_PAGES_DIR); // Make sure that cache directory exists debug!("Ensure cache directory {:?} exists", &cache_dir); @@ -163,7 +166,7 @@ impl Cache { // Extract archive archive - .unpack(&cache_dir) + .extract(&pages_dir) .map_err(|e| UpdateError(format!("Could not unpack compressed data: {}", e)))?; Ok(()) @@ -172,7 +175,7 @@ impl Cache { /// Return the duration since the cache directory was last modified. pub fn last_update() -> Option { if let Ok((cache_dir, _)) = Self::get_cache_dir() { - if let Ok(metadata) = fs::metadata(cache_dir.join("tldr-master")) { + if let Ok(metadata) = fs::metadata(cache_dir.join(TLDR_PAGES_DIR)) { if let Ok(mtime) = metadata.modified() { let now = SystemTime::now(); return now.duration_since(mtime).ok(); @@ -235,7 +238,7 @@ impl Cache { // Get cache dir let cache_dir = match Self::get_cache_dir() { - Ok((cache_dir, _)) => cache_dir.join("tldr-master"), + Ok((cache_dir, _)) => cache_dir.join(TLDR_PAGES_DIR), Err(e) => { log::error!("Could not get cache directory: {}", e); return None; @@ -281,7 +284,7 @@ impl Cache { pub fn list_pages(&self) -> Result, TealdeerError> { // Determine platforms directory and platform let (cache_dir, _) = Self::get_cache_dir()?; - let platforms_dir = cache_dir.join("tldr-master").join("pages"); + let platforms_dir = cache_dir.join(TLDR_PAGES_DIR).join("pages"); let platform_dir = self.get_platform_dir(); // Closure that allows the WalkDir instance to traverse platform diff --git a/src/main.rs b/src/main.rs index 5c03a7d..e87bc5c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,7 +35,7 @@ mod output; mod types; use crate::{ - cache::{Cache, CacheFreshness, PageLookupResult}, + cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, config::{get_config_dir, get_config_path, make_default_config, Config}, error::TealdeerError::ConfigError, extensions::Dedup, @@ -50,7 +50,7 @@ const APP_INFO: AppInfo = AppInfo { }; const VERSION: &str = env!("CARGO_PKG_VERSION"); const USAGE: &str = include_str!("usage.docopt"); -const ARCHIVE_URL: &str = "https://github.com/tldr-pages/tldr/archive/master.tar.gz"; +const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; #[cfg(not(target_os = "windows"))] const PAGER_COMMAND: &str = "less -R"; @@ -196,7 +196,7 @@ fn show_paths() { let pages_dir = Cache::get_cache_dir().map_or_else( |e| format!("[Error: {}]", e), |(mut path, _)| { - path.push("tldr-master"); + path.push(TLDR_PAGES_DIR); path.push(""); // Trailing path separator path.into_os_string() .into_string() diff --git a/tests/lib.rs b/tests/lib.rs index 1a3a441..b6cdff2 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -17,6 +17,8 @@ use tempfile::{Builder, TempDir}; // TODO: Should be 'cache::CACHE_DIR_ENV_VAR'. This requires to have a library crate for the logic. static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR"; +pub static TLDR_PAGES_DIR: &str = "tldr-pages"; + struct TestEnv { pub cache_dir: TempDir, pub custom_pages_dir: TempDir, @@ -60,7 +62,7 @@ impl TestEnv { let dir = self .cache_dir .path() - .join("tldr-master") + .join(TLDR_PAGES_DIR) .join("pages") .join(os); create_dir_all(&dir).unwrap(); @@ -202,7 +204,7 @@ fn test_quiet_old_cache() { .stdout(is_empty()); filetime::set_file_mtime( - testenv.cache_dir.path().join("tldr-master"), + testenv.cache_dir.path().join(TLDR_PAGES_DIR), filetime::FileTime::from_unix_time(1, 0), ) .unwrap(); @@ -309,7 +311,7 @@ fn test_show_paths() { testenv .cache_dir .path() - .join("tldr-master") + .join(TLDR_PAGES_DIR) .to_str() .unwrap(), ))); @@ -534,7 +536,7 @@ fn test_autoupdate_cache() { .stderr(contains("Cache not found. Please run `tldr --update`.")); let config_file_path = testenv.config_dir.path().join("config.toml"); - let cache_file_path = testenv.cache_dir.path().join("tldr-master"); + let cache_file_path = testenv.cache_dir.path().join(TLDR_PAGES_DIR); // Activate automatic updates, set the auto-update interval to 24 hours let mut config_file = File::create(&config_file_path).unwrap();