From 1c05333de609b9272f4f8fcb84e2120d3b2d278a Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 5 Dec 2021 15:53:39 +0100 Subject: [PATCH 001/196] Allow setting platform to `all` The goal is supporting the special `all` platform that results in pages for all platforms being listed when calling `--list`. It's part of the tldr client specification. However, `All` should not be a variant of the `PlatformType` enum, because `Current` isn't a `PlatformType` either. Thus, we accept the string `all` but convert it into the current platform when parsing. For consistency, the same is done when no platform is specified, by introducing yet another possible value `current` which is used by default. This way, we get rid of the `Option`. To simplify handling of os / platform arguments, a conflict between `--platform` and `--os` was introduced. --- docs/src/usage.txt | 2 +- src/cache.rs | 8 ++++---- src/main.rs | 26 +++++++++++++++----------- src/types.rs | 44 +++++++++++++++++++++++--------------------- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 4f88bc9..66c45c3 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -14,7 +14,7 @@ OPTIONS: -l, --list List all commands in the cache -f, --render Render a specific markdown file -p, --platform Override the operating system [possible values: linux, macos, - windows, sunos, osx] + windows, sunos, all] -o, --os Deprecated alias of `platform` -L, --language Override the language -u, --update Update the local cache diff --git a/src/cache.rs b/src/cache.rs index ac6347c..724e4d2 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -197,10 +197,10 @@ impl Cache { /// Return the platform directory. fn get_platform_dir(&self) -> &'static str { match self.platform { - PlatformType::Linux => "linux", - PlatformType::OsX => "osx", - PlatformType::SunOs => "sunos", - PlatformType::Windows => "windows", + PlatformType::Linux { .. } => "linux", + PlatformType::OsX { .. } => "osx", + PlatformType::SunOs { .. } => "sunos", + PlatformType::Windows { .. } => "windows", } } diff --git a/src/main.rs b/src/main.rs index 45aa050..b8bdd29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -80,22 +80,28 @@ struct Args { )] render: Option, - /// Override the operating system + /// Override the operating system [possible values: linux, macos, windows, sunos, all] #[clap( short = 'p', long = "platform", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], + possible_values = ["linux", "macos", "windows", "sunos", "osx", "current", "all"], + default_value = "current", + hide_possible_values = true, + hide_default_value = true, )] - platform: Option, + platform: PlatformType, /// Deprecated alias of `platform` #[clap( short = 'o', long = "os", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], + conflicts_with = "platform", + possible_values = ["linux", "macos", "windows", "sunos", "osx", "current", "all"], + default_value = "current", hide_possible_values = true, + hide_default_value = true, )] - os: Option, + os: PlatformType, /// Override the language #[clap(short = 'L', long = "language")] @@ -400,13 +406,14 @@ fn main() { "The -m / --markdown flag is deprecated, use -r / --raw instead", ); } - if args.os.is_some() { + let default_platform = PlatformType::current(false); + if args.os != default_platform { print_warning( enable_styles, "The -o / --os flag is deprecated, use -p / --platform instead", ); + args.platform = args.os; } - args.platform = args.platform.or(args.os); // Show config file and path, pass through if args.config_path { @@ -442,9 +449,6 @@ fn main() { configure_pager(enable_styles); } - // Specify target OS - let platform: PlatformType = args.platform.unwrap_or_else(PlatformType::current); - // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); @@ -457,7 +461,7 @@ fn main() { } // Initialize cache - let cache = Cache::new(ARCHIVE_URL, platform); + let cache = Cache::new(ARCHIVE_URL, args.platform); // Clear cache, pass through if args.clear_cache { diff --git a/src/types.rs b/src/types.rs index 3981776..9cc5f8e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,19 +8,19 @@ use serde_derive::{Deserialize, Serialize}; #[serde(rename_all = "lowercase")] #[allow(dead_code)] pub enum PlatformType { - Linux, - OsX, - SunOs, - Windows, + Linux { all: bool }, + OsX { all: bool }, + SunOs { all: bool }, + Windows { all: bool }, } impl fmt::Display for PlatformType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Linux => write!(f, "Linux"), - Self::OsX => write!(f, "macOS / BSD"), - Self::SunOs => write!(f, "SunOS"), - Self::Windows => write!(f, "Windows"), + Self::Linux { .. } => write!(f, "Linux"), + Self::OsX { .. } => write!(f, "macOS / BSD"), + Self::SunOs { .. } => write!(f, "SunOS"), + Self::Windows { .. } => write!(f, "Windows"), } } } @@ -30,12 +30,14 @@ impl str::FromStr for PlatformType { fn from_str(s: &str) -> Result { match s { - "linux" => Ok(Self::Linux), - "osx" | "macos" => Ok(Self::OsX), - "sunos" => Ok(Self::SunOs), - "windows" => Ok(Self::Windows), + "linux" => Ok(Self::Linux { all: false }), + "osx" | "macos" => Ok(Self::OsX { all: false }), + "windows" => Ok(Self::Windows { all: false }), + "sunos" => Ok(Self::SunOs { all: false }), + "current" => Ok(PlatformType::current(false)), + "all" => Ok(PlatformType::current(true)), other => Err(format!( - "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows", + "Unknown platform: {}. Possible values: linux, macos, osx, windows, sunos, current, all", other )), } @@ -44,8 +46,8 @@ impl str::FromStr for PlatformType { impl PlatformType { #[cfg(target_os = "linux")] - pub fn current() -> Self { - Self::Linux + pub fn current(all: bool) -> Self { + Self::Linux { all } } #[cfg(any( @@ -55,13 +57,13 @@ impl PlatformType { target_os = "openbsd", target_os = "dragonfly" ))] - pub fn current() -> Self { - Self::OsX + pub fn current(all: bool) -> Self { + Self::OsX { all } } #[cfg(target_os = "windows")] - pub fn current() -> Self { - Self::Windows + pub fn current(all: bool) -> Self { + Self::Windows { all } } #[cfg(not(any( @@ -73,8 +75,8 @@ impl PlatformType { target_os = "dragonfly", target_os = "windows" )))] - pub fn current() -> Self { - Self::Other + pub fn current(all: bool) -> Self { + Self::Other { all } } } From 3b69359757cf8b38c2ac6af65db9ed092e328be9 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 5 Dec 2021 16:39:05 +0100 Subject: [PATCH 002/196] Support `all` platform when listing pages --- src/cache.rs | 2 +- src/types.rs | 13 +++++++++++++ tests/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/cache.rs b/src/cache.rs index 724e4d2..bf4af6d 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -305,7 +305,7 @@ impl Cache { 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_entry(|e| self.platform.is_all() || should_walk(e)) // Filter out pages for other architectures .filter_map(Result::ok) // Convert results to options, filter out errors .filter_map(|e| { let path = e.path(); diff --git a/src/types.rs b/src/types.rs index 9cc5f8e..d3bdebb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -78,6 +78,19 @@ impl PlatformType { pub fn current(all: bool) -> Self { Self::Other { all } } + + /// Return whether or not the `all` flag is set. + /// + /// This flag is only relevant when listing pages: When `all` is set to + /// `true`, then the pages for all platforms should be listed. + pub fn is_all(self) -> bool { + match self { + Self::Linux { all } + | Self::OsX { all } + | Self::SunOs { all } + | Self::Windows { all } => all, + } + } } #[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize)] diff --git a/tests/lib.rs b/tests/lib.rs index de6d346..e79d9aa 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -523,6 +523,40 @@ fn test_list_flag_rendering() { .stdout("bar\nbaz\nfoo\nqux\n"); } +#[test] +fn test_list_platform_filtering() { + let testenv = TestEnv::new(); + + testenv.add_os_entry("common", "a-common", ""); + testenv.add_os_entry("windows", "a-windows", ""); + testenv.add_os_entry("linux", "a-linux", ""); + testenv.add_os_entry("linux", "b-linux", ""); + + // Filter: linux + testenv + .command() + .args(["--list", "--platform", "linux"]) + .assert() + .success() + .stdout("a-common\na-linux\nb-linux\n"); + + // Filter: windows + testenv + .command() + .args(["--list", "--platform", "windows"]) + .assert() + .success() + .stdout("a-common\na-windows\n"); + + // Filter: all + testenv + .command() + .args(["--list", "--platform", "all"]) + .assert() + .success() + .stdout("a-common\na-linux\na-windows\nb-linux\n"); +} + #[test] fn test_autoupdate_cache() { let testenv = TestEnv::new(); From 4a92bed585ae15c58a348e886910fe8dd575624f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 6 Dec 2021 00:31:58 +0100 Subject: [PATCH 003/196] Improve API by introducing a PlatformType struct --- src/cache.rs | 10 ++--- src/main.rs | 10 ++--- src/types.rs | 104 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 49 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index bf4af6d..1d94d89 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -16,7 +16,7 @@ use zip::ZipArchive; use crate::{ error::TealdeerError::{self, CacheError, UpdateError}, - types::{PathSource, PlatformType}, + types::{PathSource, PlatformStrategy, PlatformType}, }; static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR"; @@ -27,7 +27,7 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; #[derive(Debug)] pub struct Cache { url: String, - platform: PlatformType, + platform: PlatformStrategy, } #[derive(Debug)] @@ -64,7 +64,7 @@ pub enum CacheFreshness { } impl Cache { - pub fn new(url: S, platform: PlatformType) -> Self + pub fn new(url: S, platform: PlatformStrategy) -> Self where S: Into, { @@ -196,7 +196,7 @@ impl Cache { /// Return the platform directory. fn get_platform_dir(&self) -> &'static str { - match self.platform { + match self.platform.platform_type { PlatformType::Linux { .. } => "linux", PlatformType::OsX { .. } => "osx", PlatformType::SunOs { .. } => "sunos", @@ -305,7 +305,7 @@ impl Cache { let mut pages = WalkDir::new(platforms_dir) .min_depth(1) // Skip root directory .into_iter() - .filter_entry(|e| self.platform.is_all() || should_walk(e)) // Filter out pages for other architectures + .filter_entry(|e| self.platform.list_all || should_walk(e)) // Filter out pages for other architectures .filter_map(Result::ok) // Convert results to options, filter out errors .filter_map(|e| { let path = e.path(); diff --git a/src/main.rs b/src/main.rs index b8bdd29..4c9e676 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,7 @@ use crate::{ error::TealdeerError::ConfigError, extensions::Dedup, output::print_page, - types::{ColorOptions, PlatformType}, + types::{ColorOptions, PlatformStrategy, PlatformType}, utils::{print_error, print_warning}, }; @@ -89,7 +89,7 @@ struct Args { hide_possible_values = true, hide_default_value = true, )] - platform: PlatformType, + platform: PlatformStrategy, /// Deprecated alias of `platform` #[clap( @@ -101,7 +101,7 @@ struct Args { hide_possible_values = true, hide_default_value = true, )] - os: PlatformType, + os: PlatformStrategy, /// Override the language #[clap(short = 'L', long = "language")] @@ -406,8 +406,8 @@ fn main() { "The -m / --markdown flag is deprecated, use -r / --raw instead", ); } - let default_platform = PlatformType::current(false); - if args.os != default_platform { + let default_platform = PlatformType::current(); + if args.os.platform_type != default_platform || args.os.list_all { print_warning( enable_styles, "The -o / --os flag is deprecated, use -p / --platform instead", diff --git a/src/types.rs b/src/types.rs index d3bdebb..72d5b92 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,40 +2,79 @@ use std::{fmt, str}; -use serde_derive::{Deserialize, Serialize}; +use serde::Deserialize; -#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] +/// The platform types supported by tldr. +#[derive(Debug, Eq, PartialEq, Copy, Clone)] #[allow(dead_code)] pub enum PlatformType { - Linux { all: bool }, - OsX { all: bool }, - SunOs { all: bool }, - Windows { all: bool }, + Linux, + OsX, + SunOs, + Windows, } impl fmt::Display for PlatformType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Linux { .. } => write!(f, "Linux"), - Self::OsX { .. } => write!(f, "macOS / BSD"), - Self::SunOs { .. } => write!(f, "SunOS"), - Self::Windows { .. } => write!(f, "Windows"), + Self::Linux => write!(f, "Linux"), + Self::OsX => write!(f, "macOS / BSD"), + Self::SunOs => write!(f, "SunOS"), + Self::Windows => write!(f, "Windows"), } } } -impl str::FromStr for PlatformType { +/// The platform lookup strategy. +/// +/// Includes both the platform type, as well as +#[derive(Debug, Copy, Clone)] +pub struct PlatformStrategy { + /// The platform type that should be looked up. + pub platform_type: PlatformType, + /// Flag indicating whether all pages should be listed or not. This is only + /// used when the special platform type `all` is specified by the user. + pub list_all: bool, +} + +impl PlatformStrategy { + pub fn new(platform_type: PlatformType) -> Self { + Self { + platform_type, + list_all: false, + } + } + + /// Return a `PlatformStrategy` containing the current platform as the + /// target platform type. + pub fn current() -> Self { + Self { + platform_type: PlatformType::current(), + list_all: false, + } + } + + /// Like `current()`, but when listing the pages, return the pages for all + /// platforms, not just for the current platform. + pub fn all() -> Self { + Self { + platform_type: PlatformType::current(), + list_all: true, + } + } +} + +impl str::FromStr for PlatformStrategy { type Err = String; fn from_str(s: &str) -> Result { match s { - "linux" => Ok(Self::Linux { all: false }), - "osx" | "macos" => Ok(Self::OsX { all: false }), - "windows" => Ok(Self::Windows { all: false }), - "sunos" => Ok(Self::SunOs { all: false }), - "current" => Ok(PlatformType::current(false)), - "all" => Ok(PlatformType::current(true)), + "linux" => Ok(PlatformStrategy::new(PlatformType::Linux)), + "osx" | "macos" => Ok(PlatformStrategy::new(PlatformType::OsX)), + "windows" => Ok(PlatformStrategy::new(PlatformType::Windows)), + "sunos" => Ok(PlatformStrategy::new(PlatformType::SunOs)), + "current" => Ok(PlatformStrategy::current()), + "all" => Ok(PlatformStrategy::all()), other => Err(format!( "Unknown platform: {}. Possible values: linux, macos, osx, windows, sunos, current, all", other @@ -46,8 +85,8 @@ impl str::FromStr for PlatformType { impl PlatformType { #[cfg(target_os = "linux")] - pub fn current(all: bool) -> Self { - Self::Linux { all } + pub fn current() -> Self { + Self::Linux } #[cfg(any( @@ -57,13 +96,13 @@ impl PlatformType { target_os = "openbsd", target_os = "dragonfly" ))] - pub fn current(all: bool) -> Self { - Self::OsX { all } + pub fn current() -> Self { + Self::OsX } #[cfg(target_os = "windows")] - pub fn current(all: bool) -> Self { - Self::Windows { all } + pub fn current() -> Self { + Self::Windows } #[cfg(not(any( @@ -75,21 +114,8 @@ impl PlatformType { target_os = "dragonfly", target_os = "windows" )))] - pub fn current(all: bool) -> Self { - Self::Other { all } - } - - /// Return whether or not the `all` flag is set. - /// - /// This flag is only relevant when listing pages: When `all` is set to - /// `true`, then the pages for all platforms should be listed. - pub fn is_all(self) -> bool { - match self { - Self::Linux { all } - | Self::OsX { all } - | Self::SunOs { all } - | Self::Windows { all } => all, - } + pub fn current() -> Self { + Self::Other } } From 25d771778a67813fb56d9d27a670bda46a59fec6 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 11 Dec 2021 17:36:28 +0100 Subject: [PATCH 004/196] Update clap to 3.0.0-rc.4 --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- src/main.rs | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3585ebf..1560972 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,9 +130,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.0-beta.5" +version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" +checksum = "967965e82fc46fee1a88147a7a977a66d615ed5f83eb95b18577b342c08f90ff" dependencies = [ "bitflags", "clap_derive", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.0.0-beta.5" +version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" +checksum = "85946d4034625800196413478a1c6d3a57c12785e1f3970e590e0137dfa07342" dependencies = [ "heck", "proc-macro-error", @@ -822,9 +822,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "os_str_bytes" -version = "4.2.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index ba56396..805e743 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ path = "src/main.rs" ansi_term = "0.12.0" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" -clap = { version = "3.0.0-beta.5", features = ["std", "derive", "suggestions" ], default-features = false } +clap = { version = "3.0.0-rc.4", features = ["std", "derive", "suggestions" ], default-features = false } env_logger = { version = "0.9", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } diff --git a/src/main.rs b/src/main.rs index 45aa050..87570b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,7 +56,6 @@ const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; #[derive(Parser, Debug)] #[clap(about = "A fast TLDR client", author, version)] #[clap(setting = AppSettings::ArgRequiredElseHelp)] -#[clap(setting = AppSettings::HelpRequired)] #[clap(setting = AppSettings::DeriveDisplayOrder)] #[clap( after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." @@ -122,7 +121,7 @@ struct Args { long = "markdown", short = 'm', requires = "command_or_file", - hidden = true + hide = true )] markdown: bool, From 69f48082147d917f9ccccacc010c1a9bfb3c4ebc Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 11 Dec 2021 17:37:11 +0100 Subject: [PATCH 005/196] Clap: Hide deprecated -o/--os argument from help --- docs/src/usage.txt | 1 - src/main.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 4f88bc9..a1df753 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -15,7 +15,6 @@ OPTIONS: -f, --render Render a specific markdown file -p, --platform Override the operating system [possible values: linux, macos, windows, sunos, osx] - -o, --os Deprecated alias of `platform` -L, --language Override the language -u, --update Update the local cache -c, --clear-cache Clear the local cache diff --git a/src/main.rs b/src/main.rs index 87570b6..6a80017 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,7 +92,7 @@ struct Args { short = 'o', long = "os", possible_values = ["linux", "macos", "windows", "sunos", "osx"], - hide_possible_values = true, + hide = true )] os: Option, From b726840246f5999f1e95b65df0d27dfe60ddb3cd Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 11 Dec 2021 17:37:21 +0100 Subject: [PATCH 006/196] Run cargo update --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1560972..cd7b9d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,9 +277,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encoding_rs" -version = "0.8.29" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" +checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ "cfg-if", ] @@ -440,9 +440,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" +checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" dependencies = [ "bytes", "fnv", @@ -523,9 +523,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.15" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ "bytes", "futures-channel", @@ -593,9 +593,9 @@ checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] @@ -938,9 +938,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" dependencies = [ "unicode-xid", ] @@ -1133,9 +1133,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" +checksum = "254df5081ce98661a883445175e52efe99d1cb2a5552891d965d2f5d0cad1c16" [[package]] name = "same-file" @@ -1191,18 +1191,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" dependencies = [ "proc-macro2", "quote", From 876f390ac6dcd19ff2839465b33244cae1c7c03a Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 11 Dec 2021 17:40:16 +0100 Subject: [PATCH 007/196] Clap: Enable colored error messages --- Cargo.lock | 2 ++ Cargo.toml | 2 +- src/main.rs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index cd7b9d4..c937fc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,12 +134,14 @@ version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "967965e82fc46fee1a88147a7a977a66d615ed5f83eb95b18577b342c08f90ff" dependencies = [ + "atty", "bitflags", "clap_derive", "indexmap", "lazy_static", "os_str_bytes", "strsim 0.10.0", + "termcolor", "textwrap", ] diff --git a/Cargo.toml b/Cargo.toml index 805e743..5caf131 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ path = "src/main.rs" ansi_term = "0.12.0" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" -clap = { version = "3.0.0-rc.4", features = ["std", "derive", "suggestions" ], default-features = false } +clap = { version = "3.0.0-rc.4", features = ["std", "derive", "suggestions", "color"], default-features = false } env_logger = { version = "0.9", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } diff --git a/src/main.rs b/src/main.rs index 6a80017..4ee6d2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,6 +57,7 @@ const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; #[clap(about = "A fast TLDR client", author, version)] #[clap(setting = AppSettings::ArgRequiredElseHelp)] #[clap(setting = AppSettings::DeriveDisplayOrder)] +#[clap(setting = AppSettings::DisableColoredHelp)] #[clap( after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." )] From 00ec281b9b0ef301b414dfc9182289ba517d1a0f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Dec 2021 00:25:48 +0100 Subject: [PATCH 008/196] Include custom pages directory in --show-paths command --- src/main.rs | 39 +++++++++++++++++++++++++-------------- tests/lib.rs | 26 ++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4ee6d2d..d23e029 100644 --- a/src/main.rs +++ b/src/main.rs @@ -257,7 +257,7 @@ fn show_config_path(enable_styles: bool) { } /// Show file paths -fn show_paths() { +fn show_paths(config: &Config) { let config_dir = get_config_dir().map_or_else( |e| format!("[Error: {}]", e), |(mut path, source)| { @@ -289,13 +289,21 @@ fn show_paths() { path.push(""); // Trailing path separator path.into_os_string() .into_string() - .unwrap_or_else(|_| String::from("[Invalid]")) + .unwrap_or_else(|_| "[Invalid]".to_string()) }, ); - println!("Config dir: {}", config_dir); - println!("Config path: {}", config_path); - println!("Cache dir: {}", cache_dir); - println!("Pages dir: {}", pages_dir); + let custom_pages_dir = config.directories.custom_pages_dir.as_deref().map_or_else( + || "[None]".to_string(), + |path| { + path.to_str() + .map_or_else(|| "[Invalid]".to_string(), ToString::to_string) + }, + ); + println!("Config dir: {}", config_dir); + println!("Config path: {}", config_path); + println!("Cache dir: {}", cache_dir); + println!("Pages dir: {}", pages_dir); + println!("Custom pages dir: {}", custom_pages_dir); } /// Create seed config file and exit @@ -416,14 +424,6 @@ fn main() { ); show_config_path(enable_styles); } - if args.show_paths { - show_paths(); - } - - // Create a basic config and exit - if args.seed_config { - create_config_and_exit(enable_styles); - } // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { @@ -438,10 +438,21 @@ fn main() { } }; + // Set up pager if args.pager || config.display.use_pager { configure_pager(enable_styles); } + // Show various paths + if args.show_paths { + show_paths(&config); + } + + // Create a basic config and exit + if args.seed_config { + create_config_and_exit(enable_styles); + } + // Specify target OS let platform: PlatformType = args.platform.unwrap_or_else(PlatformType::current); diff --git a/tests/lib.rs b/tests/lib.rs index de6d346..dd03135 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -284,17 +284,18 @@ fn test_setup_seed_config() { fn test_show_paths() { let testenv = TestEnv::new(); + // Show general commands testenv .command() .args(["--show-paths"]) .assert() .success() .stdout(contains(format!( - "Config dir: {}", + "Config dir: {}", testenv.config_dir.path().to_str().unwrap(), ))) .stdout(contains(format!( - "Config path: {}", + "Config path: {}", testenv .config_dir .path() @@ -303,11 +304,11 @@ fn test_show_paths() { .unwrap(), ))) .stdout(contains(format!( - "Cache dir: {}", + "Cache dir: {}", testenv.cache_dir.path().to_str().unwrap(), ))) .stdout(contains(format!( - "Pages dir: {}", + "Pages dir: {}", testenv .cache_dir .path() @@ -315,6 +316,23 @@ fn test_show_paths() { .to_str() .unwrap(), ))); + + // Set custom pages directory + testenv.write_config(format!( + "[directories]\ncustom_pages_dir = '{}'", + testenv.custom_pages_dir.path().to_str().unwrap() + )); + + // Now ensure that this path is contained in the output + testenv + .command() + .args(["--show-paths"]) + .assert() + .success() + .stdout(contains(format!( + "Custom pages dir: {}", + testenv.custom_pages_dir.path().to_str().unwrap(), + ))); } #[test] From 6508ec6ac662af2009ec45ffe467728a594ec2ad Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Dec 2021 00:26:16 +0100 Subject: [PATCH 009/196] Ensure that default custom_pages_dir ends with trailing slash --- src/config.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index d1b040b..32e902e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -173,7 +173,10 @@ impl Default for RawDirectoriesConfig { fn default() -> Self { Self { custom_pages_dir: get_app_root(AppDataType::UserData, &crate::APP_INFO) - .map(|path| path.join("pages")) + .map(|path| { + // Note: The `join("")` call ensures that there's a trailing slash + path.join("pages").join("") + }) .ok(), } } From 66255219fa65f3466bd7db275afa7db0dd494009 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Dec 2021 00:43:40 +0100 Subject: [PATCH 010/196] Docs: Improve structure of config docs --- docs/src/SUMMARY.md | 6 ++--- docs/src/config.md | 49 +++++++++++++++++++++++--------------- docs/src/config_display.md | 2 +- docs/src/config_style.md | 2 +- docs/src/config_updates.md | 2 +- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 6201678..e2455c4 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -5,6 +5,6 @@ - [Installing](./installing.md) - [Usage](./usage.md) - [Configuration](./config.md) - - [display](./config_display.md) - - [style](./config_style.md) - - [updates](./config_updates.md) + - [Section: \[display\]](./config_display.md) + - [Section: \[style\]](./config_style.md) + - [Section: \[updates\]](./config_updates.md) diff --git a/docs/src/config.md b/docs/src/config.md index 79afcdf..9052210 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -1,33 +1,30 @@ # Configuration -Tealdeer can be customized with a config file called `config.toml`. Creating -the config file can be done manually or with the help of `tldr`: +Tealdeer can be customized with a config file in [TOML +format](https://toml.io/) called `config.toml`. - $ tldr --seed-config +## Configfile Path -The configuration file path follows OS conventions. It can be queried with the -following command: +The configuration file path follows OS conventions (e.g. +`$XDG_CONFIG_HOME/tealdeer/config.toml` on Linux). The paths can be queried +with the following command: $ tldr --show-paths +Creating the config file can be done manually or with the help of `tldr`: + + $ tldr --seed-config + On Linux, this will usually be `~/.config/tealdeer/config.toml`. -## Override Config Directory - -The directory where the configuration file resides may be overwritten by the -environment variable `TEALDEER_CONFIG_DIR`. Remember to use an absolute path. -Variable expansion will not be performed on the path. - -## Override Cache Directory - -Similarly, the cache directory where the pages are downloaded to, also follows -OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`. The path -can be overwritten using the environment variable `TEALDEER_CACHE_DIR`. -Remember to use an absolute path. Variable expansion will not be performed on -the path. - ## Config Example +Here's an example configuration file. Note that this example does not contain +all possible config options. For details on the things that can be configured, +please refer to the subsections of this documentation page +([display](config_display.html), [style](config_style.html) or +[updates](config_updates.html)). + ```toml [display] compact = false @@ -49,3 +46,17 @@ underline = true [updates] auto_update = true ``` + +## Override Config Directory + +The directory where the configuration file resides may be overwritten by the +environment variable `TEALDEER_CONFIG_DIR`. Remember to use an absolute path. +Variable expansion will not be performed on the path. + +## Override Cache Directory + +Similarly, the cache directory where the pages are downloaded to, also follows +OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`. The path +can be overwritten using the environment variable `TEALDEER_CACHE_DIR`. +Remember to use an absolute path. Variable expansion will not be performed on +the path. diff --git a/docs/src/config_display.md b/docs/src/config_display.md index 6d16805..36d5f23 100644 --- a/docs/src/config_display.md +++ b/docs/src/config_display.md @@ -1,4 +1,4 @@ -# display +# Section: \[display\] In the `display` section you can configure the output format. diff --git a/docs/src/config_style.md b/docs/src/config_style.md index 38709ee..be2a4cc 100644 --- a/docs/src/config_style.md +++ b/docs/src/config_style.md @@ -1,4 +1,4 @@ -# style +# Section: \[style\] Using the config file, the style (e.g. colors or underlines) can be customized. diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index ac9a59b..5eb8f95 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -1,4 +1,4 @@ -# updates +# Section: \[updates\] ## Automatic updates From abeb5c37576d6f47b19fdd321411a24a40c12110 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Dec 2021 00:48:39 +0100 Subject: [PATCH 011/196] Docs: Add directories config section --- docs/src/SUMMARY.md | 1 + docs/src/config.md | 4 ++-- docs/src/config_directories.md | 11 +++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 docs/src/config_directories.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index e2455c4..eb628c2 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -8,3 +8,4 @@ - [Section: \[display\]](./config_display.md) - [Section: \[style\]](./config_style.md) - [Section: \[updates\]](./config_updates.md) + - [Section: \[directories\]](./config_directories.md) diff --git a/docs/src/config.md b/docs/src/config.md index 9052210..020687e 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -22,8 +22,8 @@ On Linux, this will usually be `~/.config/tealdeer/config.toml`. Here's an example configuration file. Note that this example does not contain all possible config options. For details on the things that can be configured, please refer to the subsections of this documentation page -([display](config_display.html), [style](config_style.html) or -[updates](config_updates.html)). +([display](config_display.html), [style](config_style.html), +[updates](config_updates.html) or [directories](config_directories.html)). ```toml [display] diff --git a/docs/src/config_directories.md b/docs/src/config_directories.md new file mode 100644 index 0000000..8340ad9 --- /dev/null +++ b/docs/src/config_directories.md @@ -0,0 +1,11 @@ +# Section: \[directories\] + +This section allows overriding some directory paths. + +## `custom_pages_dir` + +Set the directory to be used to look up custom pages. Remember to use an +absolute path. Variable expansion will not be performed on the path. + + [directories] + custom_pages_dir = "/home/myuser/custom-tldr-pages/" From ca844b35e93bb32d43ce433f650b1dbf9378891a Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 20 Dec 2021 01:04:57 +0100 Subject: [PATCH 012/196] Docs: Document custom pages and patches --- docs/src/SUMMARY.md | 1 + docs/src/config_directories.md | 5 ++-- docs/src/usage_custom_pages.md | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 docs/src/usage_custom_pages.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index eb628c2..8aaac31 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -4,6 +4,7 @@ - [Installing](./installing.md) - [Usage](./usage.md) + - [Custom Pages](./usage_custom_pages.md) - [Configuration](./config.md) - [Section: \[display\]](./config_display.md) - [Section: \[style\]](./config_style.md) diff --git a/docs/src/config_directories.md b/docs/src/config_directories.md index 8340ad9..d894e90 100644 --- a/docs/src/config_directories.md +++ b/docs/src/config_directories.md @@ -4,8 +4,9 @@ This section allows overriding some directory paths. ## `custom_pages_dir` -Set the directory to be used to look up custom pages. Remember to use an -absolute path. Variable expansion will not be performed on the path. +Set the directory to be used to look up [custom +pages](usage_custom_pages.html). Remember to use an absolute path. Variable +expansion will not be performed on the path. [directories] custom_pages_dir = "/home/myuser/custom-tldr-pages/" diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md new file mode 100644 index 0000000..589479f --- /dev/null +++ b/docs/src/usage_custom_pages.md @@ -0,0 +1,42 @@ +# Custom Pages and Patches + +Tealdeer allows creating new custom pages, overriding existing pages as well as +extending existing pages. + +The directory, where these custom pages and patches can be placed, follows OS +conventions. On Linux, for example, the default location is +`~/.local/share/tealdeer/pages/`. To print the path used on your system, simply +run `tldr --show-paths`. + +The custom pages directory can be [overridden by the config +file](config_directories.html). + +## Custom Pages + +To document internal command line tools, or if you want to replace an existing +tldr page with one that's better suited for you, place a file with the name +`.page` in the custom pages directory. When calling `tldr `, +your custom page will be shown instead of the upstream version in the cache. + +Path: + + $CUSTOM_PAGES_DIR/.page + +Example: + + ~/.local/share/tealdeer/pages/ufw.page + +## Custom Patches + +Sometimes you don't want to fully replace an existing upstream page, but just +want to extend it with your own examples that you frequently need. In this +case, use a file called `.patch`, it will be appended to existing +pages. + +Path: + + $CUSTOM_PAGES_DIR/.patch + +Example: + + ~/.local/share/tealdeer/pages/ufw.patch From 0ef31d1f17727a4ec2550e78faf0024b9ff8df8d Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 29 Dec 2021 23:52:25 +0100 Subject: [PATCH 013/196] Concatenate page and patch bytes before processing This way a patch file does not need a well-formed header anymore. Fixes #181. --- src/cache.rs | 60 +++++++++++++++++++++++------------------ src/main.rs | 5 ++-- src/output.rs | 60 ++++++++++++++++++++--------------------- tests/inkscape-v2.patch | 3 +-- 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index ac6347c..1a3a31d 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,9 +1,8 @@ use std::{ env, ffi::OsStr, - fs, - io::{Cursor, Read, Seek}, - iter, + fs::{self, File}, + io::{BufReader, Cursor, Read, Seek}, path::{Path, PathBuf}, }; @@ -32,8 +31,8 @@ pub struct Cache { #[derive(Debug)] pub struct PageLookupResult { - page_path: PathBuf, - patch_path: Option, + pub page_path: PathBuf, + pub patch_path: Option, } impl PageLookupResult { @@ -49,8 +48,36 @@ impl PageLookupResult { self } - pub fn paths(&self) -> impl Iterator { - iter::once(self.page_path.as_path()).chain(self.patch_path.as_deref()) + /// Create a buffered reader that sequentially reads from the page and the + /// patch, as if they were concatenated. + /// + /// This will return an error if either the page file or the patch file + /// cannot be opened. + pub fn reader(&self) -> Result>, String> { + // Open page file + let page_file = File::open(&self.page_path) + .map_err(|msg| format!("Could not open page file at {:?}: {}", self.page_path, msg))?; + + // Open patch file + let patch_file_opt = match &self.patch_path { + Some(path) => Some( + File::open(path) + .map_err(|msg| format!("Could not open patch file at {:?}: {}", path, msg))?, + ), + None => None, + }; + + // Create chained reader from file(s) + // + // Note: It might be worthwhile to create our own struct that accepts + // the page and patch files and that will read them sequentially, + // because it avoids the boxing below. However, the performance impact + // would first need to be shown to be significant using a benchmark. + Ok(BufReader::new(if let Some(patch_file) = patch_file_opt { + Box::new(page_file.chain(patch_file)) as Box + } else { + Box::new(page_file) as Box + })) } } @@ -360,23 +387,4 @@ impl Cache { /// Unit Tests for cache module #[cfg(test)] mod tests { - use super::*; - - #[test] - fn test_page_lookup_result_iter_with_patch() { - let lookup = PageLookupResult::with_page(PathBuf::from("test.page")) - .with_optional_patch(Some(PathBuf::from("test.patch"))); - let mut iter = lookup.paths(); - assert_eq!(iter.next(), Some(Path::new("test.page"))); - assert_eq!(iter.next(), Some(Path::new("test.patch"))); - assert_eq!(iter.next(), None); - } - - #[test] - fn test_page_lookup_result_iter_no_patch() { - let lookup = PageLookupResult::with_page(PathBuf::from("test.page")); - let mut iter = lookup.paths(); - assert_eq!(iter.next(), Some(Path::new("test.page"))); - assert_eq!(iter.next(), None); - } } diff --git a/src/main.rs b/src/main.rs index d23e029..7b2e45c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -514,17 +514,18 @@ fn main() { // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#page-names let command = args.command.join("-").to_lowercase(); + // Collect languages let languages = args .language .map_or_else(get_languages_from_env, |lang| vec![lang]); // Search for command in cache - if let Some(page) = cache.find_page( + if let Some(lookup_result) = cache.find_page( &command, &languages, config.directories.custom_pages_dir.as_deref(), ) { - if let Err(msg) = print_page(&page, args.raw, &config) { + if let Err(msg) = print_page(&lookup_result, args.raw, &config) { print_error(enable_styles, &msg); process::exit(1); } diff --git a/src/output.rs b/src/output.rs index 70cd138..cad0690 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,9 +1,6 @@ //! Functions for printing pages to the terminal -use std::{ - fs::File, - io::{self, BufRead, BufReader, Write}, -}; +use std::io::{self, BufRead, Write}; use crate::{ cache::PageLookupResult, @@ -15,41 +12,44 @@ use crate::{ /// Print page by path pub fn print_page( - page: &PageLookupResult, + lookup_result: &PageLookupResult, enable_markdown: bool, config: &Config, ) -> Result<(), String> { + // Create reader from file(s) + let reader = lookup_result.reader()?; + + // Lock stdout only once, this improves performance considerably let stdout = io::stdout(); let mut handle = stdout.lock(); - for path in page.paths() { - let file = File::open(path).map_err(|msg| format!("Could not open file: {}", msg))?; - let reader = BufReader::new(file); - - if enable_markdown { - // Print the raw markdown of the file. - for line in reader.lines() { - writeln!(handle, "{}", line.unwrap()) - .map_err(|_| "Could not write to stdout".to_string())?; + if enable_markdown { + // Print the raw markdown of the file. + for line in reader.lines() { + writeln!(handle, "{}", line.unwrap()) + .map_err(|_| "Could not write to stdout".to_string())?; + } + } else { + // Closure that processes a page snippet and writes it to stdout + let mut process_snippet = |snip: PageSnippet<'_>| { + if snip.is_empty() { + Ok(()) + } else { + print_snippet(&mut handle, snip, &config.style) + .map_err(|e| WriteError(e.to_string())) } - } else { - let mut process_snippet = |snip: PageSnippet<'_>| { - if snip.is_empty() { - Ok(()) - } else { - print_snippet(&mut handle, snip, &config.style) - .map_err(|e| WriteError(e.to_string())) - } - }; - highlight_lines( - LineIterator::new(reader), - &mut process_snippet, - !config.display.compact, - ) - .map_err(|e| format!("Could not write to stdout: {}", e.message()))?; }; - } + // Print highlighted lines + highlight_lines( + LineIterator::new(reader), + &mut process_snippet, + !config.display.compact, + ) + .map_err(|e| format!("Could not write to stdout: {}", e.message()))?; + }; + + // We're done outputting data, flush stdout now! handle .flush() .map_err(|_| "Could not flush stdout".to_string())?; diff --git a/tests/inkscape-v2.patch b/tests/inkscape-v2.patch index ffca34c..762cf15 100644 --- a/tests/inkscape-v2.patch +++ b/tests/inkscape-v2.patch @@ -1,5 +1,4 @@ -This header shouldn't be required -================================= + Custom inkscape entry My Inkscape example From fb40974616d4b5662a722cdd32d1abc44db68dae Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 29 Dec 2021 23:53:46 +0100 Subject: [PATCH 014/196] Cache: Add tests for PageLookupResult::reader Co-authored-by: Dalton Maahs --- src/cache.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/cache.rs b/src/cache.rs index 1a3a31d..8a6d662 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -387,4 +387,55 @@ impl Cache { /// Unit Tests for cache module #[cfg(test)] mod tests { + use super::*; + + use std::{ + fs::File, + io::{Read, Write}, + }; + + #[test] + fn test_reader_with_patch() { + // Write test files + let dir = tempfile::tempdir().unwrap(); + let page_path = dir.path().join("test.page"); + let patch_path = dir.path().join("test.patch"); + { + let mut f1 = File::create(&page_path).unwrap(); + f1.write_all(b"Hello\n").unwrap(); + let mut f2 = File::create(&patch_path).unwrap(); + f2.write_all(b"World").unwrap(); + } + + // Create chained reader from lookup result + let lr = PageLookupResult::with_page(page_path).with_optional_patch(Some(patch_path)); + let mut reader = lr.reader().unwrap(); + + // Read into a Vec + let mut buf = Vec::new(); + reader.read_to_end(&mut buf).unwrap(); + + assert_eq!(&buf, b"Hello\nWorld"); + } + + #[test] + fn test_reader_without_patch() { + // Write test file + let dir = tempfile::tempdir().unwrap(); + let page_path = dir.path().join("test.page"); + { + let mut f = File::create(&page_path).unwrap(); + f.write_all(b"Hello").unwrap(); + } + + // Create chained reader from lookup result + let lr = PageLookupResult::with_page(page_path); + let mut reader = lr.reader().unwrap(); + + // Read into a Vec + let mut buf = Vec::new(); + reader.read_to_end(&mut buf).unwrap(); + + assert_eq!(&buf, b"Hello"); + } } From 2b1167f19b96b1c20ffe4a34b98ed7a5e3d9bba0 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 30 Dec 2021 00:12:51 +0100 Subject: [PATCH 015/196] Update custom patches docs --- docs/src/SUMMARY.md | 2 +- docs/src/usage_custom_pages.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 8aaac31..8d1a634 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -4,7 +4,7 @@ - [Installing](./installing.md) - [Usage](./usage.md) - - [Custom Pages](./usage_custom_pages.md) + - [Custom Pages and Patches](./usage_custom_pages.md) - [Configuration](./config.md) - [Section: \[display\]](./config_display.md) - [Section: \[style\]](./config_style.md) diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md index 589479f..bdae7a9 100644 --- a/docs/src/usage_custom_pages.md +++ b/docs/src/usage_custom_pages.md @@ -4,7 +4,7 @@ Tealdeer allows creating new custom pages, overriding existing pages as well as extending existing pages. The directory, where these custom pages and patches can be placed, follows OS -conventions. On Linux, for example, the default location is +conventions. On Linux for instance, the default location is `~/.local/share/tealdeer/pages/`. To print the path used on your system, simply run `tldr --show-paths`. @@ -33,6 +33,9 @@ want to extend it with your own examples that you frequently need. In this case, use a file called `.patch`, it will be appended to existing pages. +> **Note:** Because the patch file will be concatenated directly to the page +> file, it needs to start with an empty line. + Path: $CUSTOM_PAGES_DIR/.patch From ed3d1ea9af2a069e92a1b0565d9796e1677523ea Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 30 Dec 2021 21:03:44 +0100 Subject: [PATCH 016/196] Always add empty line before concatenating patch file --- src/cache.rs | 8 ++++---- tests/inkscape-v2.patch | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 8a6d662..87db30c 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -74,7 +74,7 @@ impl PageLookupResult { // because it avoids the boxing below. However, the performance impact // would first need to be shown to be significant using a benchmark. Ok(BufReader::new(if let Some(patch_file) = patch_file_opt { - Box::new(page_file.chain(patch_file)) as Box + Box::new(page_file.chain(&b"\n"[..]).chain(patch_file)) as Box } else { Box::new(page_file) as Box })) @@ -415,7 +415,7 @@ mod tests { let mut buf = Vec::new(); reader.read_to_end(&mut buf).unwrap(); - assert_eq!(&buf, b"Hello\nWorld"); + assert_eq!(&buf, b"Hello\n\nWorld"); } #[test] @@ -425,7 +425,7 @@ mod tests { let page_path = dir.path().join("test.page"); { let mut f = File::create(&page_path).unwrap(); - f.write_all(b"Hello").unwrap(); + f.write_all(b"Hello\n").unwrap(); } // Create chained reader from lookup result @@ -436,6 +436,6 @@ mod tests { let mut buf = Vec::new(); reader.read_to_end(&mut buf).unwrap(); - assert_eq!(&buf, b"Hello"); + assert_eq!(&buf, b"Hello\n"); } } diff --git a/tests/inkscape-v2.patch b/tests/inkscape-v2.patch index 762cf15..5cc5d22 100644 --- a/tests/inkscape-v2.patch +++ b/tests/inkscape-v2.patch @@ -1,4 +1,3 @@ - Custom inkscape entry My Inkscape example From e722b4f92ee328009765d72fc084c04562983862 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 30 Dec 2021 22:39:27 +0100 Subject: [PATCH 017/196] Rename main branch (#239) --- .github/workflows/ci.yml | 2 +- .github/workflows/gh-pages.yml | 2 +- README.md | 4 ++-- src/main.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 160d9ae..390e565 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ on: push: branches: - - master + - main pull_request: schedule: - cron: '30 3 * * 2' diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 35f17b3..c32ec71 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -3,7 +3,7 @@ name: github pages on: push: branches: - - master + - main jobs: deploy: diff --git a/README.md b/README.md index 86c82a6..1746860 100644 --- a/README.md +++ b/README.md @@ -120,13 +120,13 @@ Thanks to @severen for coming up with the name "tealdeer"! [outfieldr-gh]: https://gitlab.com/ve-nt/outfieldr [python-gh]: https://github.com/tldr-pages/tldr-python-client -[benchmark-dockerfile]: https://github.com/dbrgn/tealdeer/blob/master/benchmarks/Dockerfile +[benchmark-dockerfile]: https://github.com/dbrgn/tealdeer/blob/main/benchmarks/Dockerfile [client-spec]: https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md [hyperfine-gh]: https://github.com/sharkdp/hyperfine [outfieldr-comment-tls]: https://github.com/dbrgn/tealdeer/issues/129#issuecomment-833596765 -[github-actions]: https://github.com/dbrgn/tealdeer/actions?query=branch%3Amaster +[github-actions]: https://github.com/dbrgn/tealdeer/actions?query=branch%3Amain [github-actions-badge]: https://github.com/dbrgn/tealdeer/workflows/CI/badge.svg [crates-io]: https://crates.io/crates/tealdeer [crates-io-badge]: https://img.shields.io/crates/v/tealdeer.svg diff --git a/src/main.rs b/src/main.rs index 7b2e45c..e6d79df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -340,7 +340,7 @@ fn init_log() {} fn get_languages(env_lang: Option<&str>, env_language: Option<&str>) -> Vec { // Language list according to - // https://github.com/tldr-pages/tldr/blob/master/CLIENT-SPECIFICATION.md#language + // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#language if env_lang.is_none() { return vec!["en".to_string()]; From 2007aa0c325a679d537ea7430fd940aca8db94b4 Mon Sep 17 00:00:00 2001 From: alstjr7375 Date: Thu, 11 Mar 2021 13:37:15 +0900 Subject: [PATCH 018/196] CI: Add initial release workflow --- .github/workflows/release.yml | 97 +++++++++++++++++++++++++++++++++++ upload-asset.sh | 37 +++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 upload-asset.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..974d873 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,97 @@ +on: + push: + tags: + - "v*" # push events to matching v*, i.e. v1.0, v20.15.10 + +jobs: + completions-upload: + runs-on: ubuntu-latest + strategy: + matrix: + target: ["bash", "fish", "zsh"] + steps: + - uses: actions/checkout@v2 + - name: Upload + if: startsWith(github.ref, 'refs/tags/') + run: | + sudo apt update && sudo apt install -y jq + source ./upload-asset.sh + + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} + + license-upload: + runs-on: ubuntu-latest + strategy: + matrix: + target: ["MIT", "APACHE"] + steps: + - uses: actions/checkout@v2 + - name: Upload + if: startsWith(github.ref, 'refs/tags/') + run: | + sudo apt update && sudo apt install -y jq + source ./upload-asset.sh + + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }} + + build-linux: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - arch: "x86_64" + libc: "musl" + - arch: "i686" + libc: "musl" + - arch: "armv7" + libc: "musleabihf" + - arch: "arm" + libc: "musleabi" + - arch: "arm" + libc: "musleabihf" + + steps: + - uses: actions/checkout@v2 + - name: Docker Pull + run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} + - name: Build with Docker + run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release + - name: Stripping + run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr + - uses: actions/upload-artifact@v2 + with: + name: "tldr-linux-${{ matrix.arch }}-${{ matrix.libc }}" + path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" + + build-darwin: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --release --target x86_64-apple-darwin + - uses: actions/upload-artifact@v2 + with: + name: "tldr-apple-darwin-x86_64" + path: "target/x86_64-apple-darwin/release/tldr" + + release-upload: + needs: + - build-linux + - build-darwin + runs-on: ubuntu-latest + strategy: + matrix: + target: ["linux-x86_64-musl", "linux-i686-musl", "linux-armv7-musleabihf", "linux-arm-musleabi", "linux-arm-musleabihf", "apple-darwin-x86_64"] + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + - name: Upload + if: startsWith(github.ref, 'refs/tags/') + run: | + sudo apt update && sudo apt install -y jq + source ./upload-asset.sh + + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} tldr-${{ matrix.target }}/tldr tldr-${{ matrix.target }} diff --git a/upload-asset.sh b/upload-asset.sh new file mode 100644 index 0000000..af85fbf --- /dev/null +++ b/upload-asset.sh @@ -0,0 +1,37 @@ +#! /bin/bash +# https://gist.github.com/schell/2fe896953b6728cc3c5d8d5f9f3a17a3 +# requires curl and jq on PATH: https://stedolan.github.io/jq/ + +# upload a release file. +# this must be called only after a successful create_release, as create_release saves +# the json response in release.json. +# token: github api user token +# repo: github username/reponame +# file: path to the asset file to upload +# name: name to use for the uploaded asset +upload_release_file() { + token=$1 + repo=$2 + file=$3 + name=$4 + + url=`curl --silent "https://api.github.com/repos/${repo}/releases/latest" | jq -r .upload_url | cut -d{ -f'1'` + command="\ + curl -s -o upload.json -w '%{http_code}' \ + --request POST \ + --header 'authorization: Bearer ${token}' \ + --header 'Content-Type: application/octet-stream' \ + --data-binary @\"${file}\" + ${url}?name=${name}" + http_code=`eval $command` + if [ $http_code == "201" ]; then + echo "asset $name uploaded:" + jq -r .browser_download_url upload.json + else + echo "upload failed with code '$http_code':" + cat upload.json + echo "command:" + echo $command + return 1 + fi +} From c155b6f98d0972d4495dc1495591819cda6d550d Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 30 Dec 2021 22:37:39 +0100 Subject: [PATCH 019/196] CI: Clean up release workflow and upload script - Clean up scripts - Create draft release before uploading assets - Find release for current tag, don't simply pick the latest - Add Windows builds - Add checksums for binaries --- .github/workflows/release.yml | 112 ++++++++++++++++++++++++---------- scripts/upload-asset.sh | 88 ++++++++++++++++++++++++++ upload-asset.sh | 37 ----------- 3 files changed, 169 insertions(+), 68 deletions(-) create mode 100644 scripts/upload-asset.sh delete mode 100644 upload-asset.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 974d873..c0a7f1c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,38 +4,51 @@ on: - "v*" # push events to matching v*, i.e. v1.0, v20.15.10 jobs: - completions-upload: - runs-on: ubuntu-latest + create-release: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Create release for tag + if: startsWith(github.ref, 'refs/tags/') + run: | + source ./scripts/upload-asset.sh + # Create: + create_release ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} "Tealdeer version ${GITHUB_REF#refs/*/v}.\n\nFor the full changelog, see https://github.com/dbrgn/tealdeer/blob/main/CHANGELOG.md.\n\nBinaries were generated automatically in CI, and are therefore unsigned. For a fully trusted release, please build from source." + + upload-completions: + needs: + - create-release + runs-on: ubuntu-20.04 strategy: matrix: target: ["bash", "fish", "zsh"] steps: - uses: actions/checkout@v2 - - name: Upload + - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh + source ./scripts/upload-asset.sh + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} - - license-upload: - runs-on: ubuntu-latest + upload-license: + needs: + - create-release + runs-on: ubuntu-20.04 strategy: matrix: target: ["MIT", "APACHE"] steps: - uses: actions/checkout@v2 - - name: Upload + - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh - - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }} + source ./scripts/upload-asset.sh + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }}.txt build-linux: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: matrix: include: @@ -49,22 +62,21 @@ jobs: libc: "musleabi" - arch: "arm" libc: "musleabihf" - steps: - uses: actions/checkout@v2 - - name: Docker Pull + - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - - name: Build with Docker + - name: Build in Docker run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - - name: Stripping + - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - uses: actions/upload-artifact@v2 with: - name: "tldr-linux-${{ matrix.arch }}-${{ matrix.libc }}" + name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" - build-darwin: - runs-on: macos-latest + build-macos: + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Build @@ -74,24 +86,62 @@ jobs: args: --release --target x86_64-apple-darwin - uses: actions/upload-artifact@v2 with: - name: "tldr-apple-darwin-x86_64" + name: "tealdeer-macos-x86_64" path: "target/x86_64-apple-darwin/release/tldr" - release-upload: + build-windows: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v2 + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --release --target x86_64-pc-windows-msvc + - uses: actions/upload-artifact@v2 + with: + name: "tealdeer-windows-x86_64-msvc" + path: "target/x86_64-pc-windows-msvc/release/tldr.exe" + + upload-release: needs: + - create-release - build-linux - - build-darwin - runs-on: ubuntu-latest + - build-macos + - build-windows + runs-on: ubuntu-20.04 strategy: matrix: - target: ["linux-x86_64-musl", "linux-i686-musl", "linux-armv7-musleabihf", "linux-arm-musleabi", "linux-arm-musleabihf", "apple-darwin-x86_64"] + target: + - linux-x86_64-musl + - linux-i686-musl + - linux-armv7-musleabihf + - linux-arm-musleabi + - linux-arm-musleabihf + - macos-x86_64 + - windows-x86_64-msvc steps: - uses: actions/checkout@v2 - uses: actions/download-artifact@v2 - - name: Upload + - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh + source ./scripts/upload-asset.sh - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} tldr-${{ matrix.target }}/tldr tldr-${{ matrix.target }} + # Move/rename file + mkdir out && cd out + if [[ "${{ matrix.target }}" == *windows* ]]; then + src="../tealdeer-${{ matrix.target }}/tldr.exe" + filename="tealdeer-${{ matrix.target }}.exe" + else + src="../tealdeer-${{ matrix.target }}/tldr" + filename="tealdeer-${{ matrix.target }}" + fi + cp $src $filename + + # Create checksum + sha256sum "$filename" > "$filename.sha256" + + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} $filename $filename + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} $filename.sha256 $filename.sha256 diff --git a/scripts/upload-asset.sh b/scripts/upload-asset.sh new file mode 100644 index 0000000..7f0a9c3 --- /dev/null +++ b/scripts/upload-asset.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# +# Upload artifacts to GitHub Actions. +# +# Based on: https://gist.github.com/schell/2fe896953b6728cc3c5d8d5f9f3a17a3 +# +# Requires curl and jq on PATH + +# Args: +# token: GitHub API user token +# repo: GitHub username/reponame +# tag: Name of the tag for which to create a release +# description: Release description +create_release() { + # Args + token=$1 + repo=$2 + tag=$3 + description=$4 + echo "Creating release:" + echo " repo=$repo" + echo " tag=$tag" + echo "" + + # Create release + http_code=$( + curl -s -o create.json -w '%{http_code}' \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + --header "Content-Type:application/json" \ + "https://api.github.com/repos/$repo/releases" \ + -d '{"tag_name":"'"$tag"'","name":"'"${tag/v/Release }"'","draft":true,"body":"'"${description/\"/\\\"}"'"}' + ) + if [ "$http_code" == "201" ]; then + echo "Release for tag $tag created." + else + echo "Asset upload failed with code '$http_code'." + return 1 + fi +} + +# Args: +# token: GitHub API user token +# repo: GitHub username/reponame +# tag: Name of the tag for which to upload the assets +# file: Path to the asset file to upload +# name: Name to use for the uploaded asset +upload_release_file() { + # Args + token=$1 + repo=$2 + tag=$3 + file=$4 + name=$5 + echo "Uploading:" + echo " repo=$repo" + echo " tag=$tag" + echo " file=$file" + echo " name=$name" + echo "" + + # Determine upload URL of latest draft release for the specified tag + upload_url=$( + curl -s \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + "https://api.github.com/repos/$repo/releases" \ + | jq -r '[.[] | select(.tag_name == "'"$tag"'" and .draft)][0].upload_url' \ + | cut -d"{" -f'1' + ) + echo "Determined upload URL: $upload_url" + http_code=$( + curl -s -o upload.json -w '%{http_code}' \ + --request POST \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + --header "Content-Type: application/octet-stream" \ + --data-binary "@$file" "$upload_url?name=$name" + ) + if [ "$http_code" == "201" ]; then + echo "Asset $name uploaded:" + jq -r .browser_download_url upload.json + else + echo "Asset upload failed with code '$http_code':" + cat upload.json + return 1 + fi +} diff --git a/upload-asset.sh b/upload-asset.sh deleted file mode 100644 index af85fbf..0000000 --- a/upload-asset.sh +++ /dev/null @@ -1,37 +0,0 @@ -#! /bin/bash -# https://gist.github.com/schell/2fe896953b6728cc3c5d8d5f9f3a17a3 -# requires curl and jq on PATH: https://stedolan.github.io/jq/ - -# upload a release file. -# this must be called only after a successful create_release, as create_release saves -# the json response in release.json. -# token: github api user token -# repo: github username/reponame -# file: path to the asset file to upload -# name: name to use for the uploaded asset -upload_release_file() { - token=$1 - repo=$2 - file=$3 - name=$4 - - url=`curl --silent "https://api.github.com/repos/${repo}/releases/latest" | jq -r .upload_url | cut -d{ -f'1'` - command="\ - curl -s -o upload.json -w '%{http_code}' \ - --request POST \ - --header 'authorization: Bearer ${token}' \ - --header 'Content-Type: application/octet-stream' \ - --data-binary @\"${file}\" - ${url}?name=${name}" - http_code=`eval $command` - if [ $http_code == "201" ]; then - echo "asset $name uploaded:" - jq -r .browser_download_url upload.json - else - echo "upload failed with code '$http_code':" - cat upload.json - echo "command:" - echo $command - return 1 - fi -} From d1c17f2eb68faafcd95d74240b059e7ef171bbfc Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 31 Dec 2021 18:20:16 +0100 Subject: [PATCH 020/196] Remove release-build.sh We don't need it anymore now that we have a CI pipeline for release binaries. --- release-build.sh | 77 ------------------------------------------------ 1 file changed, 77 deletions(-) delete mode 100755 release-build.sh diff --git a/release-build.sh b/release-build.sh deleted file mode 100755 index 26567a4..0000000 --- a/release-build.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -VERSION=$(grep '^version = ' Cargo.toml | sed 's/.*"\([0-9\.]*\)".*/\1/') -GPG_KEY=EA456E8BAF0109429583EED83578F667F2F3A5FA - -declare -a targets=( - "x86_64-musl" - "i686-musl" - "armv7-musleabihf" - "arm-musleabi" - "arm-musleabihf" -) - -declare -a rusttargets=( - "x86_64-unknown-linux-musl" - "i686-unknown-linux-musl" - "armv7-unknown-linux-musleabihf" - "arm-unknown-linux-musleabi" - "arm-unknown-linux-musleabihf" -) - -declare -a completions=( - "bash" - "fish" - "zsh" -) - -function docker-download { - echo "==> Downloading Docker image: messense/rust-musl-cross:$1" - docker pull messense/rust-musl-cross:$1 -} - -function docker-build { - echo "==> Building target: $1" - docker run --rm -it -v "$(pwd)":/home/rust/src messense/rust-musl-cross:$1 cargo build --release -} - -echo -e "==> Version $VERSION\n" - -for target in ${targets[@]}; do docker-download $target; done -echo "" -for target in ${targets[@]}; do docker-build $target; done -echo "" - -rm -rf "dist-$VERSION" -mkdir "dist-$VERSION" - -for i in ${!targets[@]}; do - echo "==> Copying ${targets[$i]}" - cp "target/${rusttargets[$i]}/release/tldr" "dist-$VERSION/tldr-linux-${targets[$i]}" -done -echo "" - -for target in ${targets[@]}; do - echo "==> Stripping $target" - docker run --rm -it -v "$(pwd)":/home/rust/src messense/rust-musl-cross:$target musl-strip -s /home/rust/src/dist-$VERSION/tldr-linux-$target -done -echo "" - -for target in ${targets[@]}; do - echo "==> Signing $target" - gpg -a --output "dist-$VERSION/tldr-linux-$target.sig" --detach-sig "dist-$VERSION/tldr-linux-$target" -done -echo "" - -for completion in ${completions[@]}; do - echo "==> Copying ${completion} completion" - cp "${completion}_tealdeer" "dist-$VERSION/completions_${completion}" -done -echo "" - -echo "==> Copying licenses" -cp LICENSE-* "dist-$VERSION/" - -echo "Done." From 20b7c5c33f151d0b63be205427d7fab5405d5add Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 31 Dec 2021 18:36:45 +0100 Subject: [PATCH 021/196] Run cargo update --- Cargo.lock | 159 ++++++++++++++++++++------------------------- Cargo.toml | 2 +- docs/src/usage.txt | 2 - 3 files changed, 72 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c937fc5..692eb44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,9 +130,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.0-rc.4" +version = "3.0.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "967965e82fc46fee1a88147a7a977a66d615ed5f83eb95b18577b342c08f90ff" +checksum = "e6f243c7279f09ffed852a0a564c72091331651484cdbb32b7287f16df8611a7" dependencies = [ "atty", "bitflags", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.0.0-rc.4" +version = "3.0.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85946d4034625800196413478a1c6d3a57c12785e1f3970e590e0137dfa07342" +checksum = "8cd9992739777a4a23535089a8d235eac43044ba8b431d9f54fe334dfa779930" dependencies = [ "heck", "proc-macro-error", @@ -228,17 +228,6 @@ dependencies = [ "syn", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "difflib" version = "0.4.0" @@ -322,9 +311,9 @@ dependencies = [ [[package]] name = "escargot" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ead7d8a70259beb627c1ffdd19b0372381f247f88e46a3bd52bb797182690b3" +checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" dependencies = [ "log", "once_cell", @@ -383,42 +372,42 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-io" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-sink" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ "futures-core", "futures-io", @@ -485,13 +474,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] @@ -538,7 +527,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", + "itoa 0.4.8", "pin-project-lite", "socket2", "tokio", @@ -608,6 +597,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "jni" version = "0.19.0" @@ -645,9 +640,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.109" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "log" @@ -780,9 +775,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -790,19 +785,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" dependencies = [ - "derivative", "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -812,9 +806,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "openssl-probe" @@ -849,9 +843,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -861,9 +855,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "predicates" @@ -940,18 +934,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] @@ -1049,9 +1043,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" +checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258" dependencies = [ "base64", "bytes", @@ -1109,7 +1103,7 @@ dependencies = [ "log", "ring", "sct", - "webpki 0.22.0", + "webpki", ] [[package]] @@ -1135,9 +1129,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "254df5081ce98661a883445175e52efe99d1cb2a5552891d965d2f5d0cad1c16" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" @@ -1193,18 +1187,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -1213,11 +1207,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -1229,7 +1223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" dependencies = [ "form_urlencoded", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] @@ -1270,9 +1264,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" dependencies = [ "proc-macro2", "quote", @@ -1375,11 +1369,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -1391,13 +1384,13 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4baa378e417d780beff82bf54ceb0d195193ea6a00c14e22359e7f39456b5689" +checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" dependencies = [ "rustls", "tokio", - "webpki 0.22.0", + "webpki", ] [[package]] @@ -1502,9 +1495,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wait-timeout" @@ -1618,16 +1611,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki" version = "0.22.0" @@ -1640,11 +1623,11 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.21.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" dependencies = [ - "webpki 0.21.4", + "webpki", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5caf131..9ea2c9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ path = "src/main.rs" ansi_term = "0.12.0" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" -clap = { version = "3.0.0-rc.4", features = ["std", "derive", "suggestions", "color"], default-features = false } +clap = { version = "=3.0.0-rc.11", features = ["std", "derive", "suggestions", "color"], default-features = false } env_logger = { version = "0.9", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } diff --git a/docs/src/usage.txt b/docs/src/usage.txt index a1df753..d410139 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,7 +1,5 @@ tealdeer 1.4.1 - Danilo Bargen , Niklas Mohrin - A fast TLDR client USAGE: From 81c30bfb77fcb4ac1d9ee2d645ef9a17c516d48e Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 31 Dec 2021 19:53:57 +0100 Subject: [PATCH 022/196] Release v1.5.0 --- CHANGELOG.md | 160 ++++++++++++++++++++++++++++++++++++++++----- Cargo.lock | 2 +- Cargo.toml | 2 +- RELEASING.md | 8 ++- docs/src/usage.txt | 2 +- 5 files changed, 153 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14718ee..cdf6e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,95 @@ Possible log types: - `[removed]` for deprecated features removed in this release. - `[fixed]` for any bug fixes. - `[security]` to invite users to upgrade in case of vulnerabilities. +- `[docs]` for documentation changes. +- `[chore]` for maintenance work. + + +### [v1.5.0][v1.5.0] (2021-12-31) + +This is quite a big release with many new features. In the 15 months since the +last release, 59 pull requests from 16 different contributors were merged! + +The highlights: + +- **Custom pages and patches**: You can now create your own local-only tldr + pages. But not just that, you can also extend existing upstream pages with + your own examples. For more details, see + [the docs](https://dbrgn.github.io/tealdeer/usage_custom_pages.html). +- **Change argument parsing from docopt to clap**: We replaced docopt.rs as + argument parsing library with clap v3, resulting in almost 1 MiB smaller + binaries and a 22% speed increase when rendering a tldr page. +- **Multi-language support**: You can now override the language with `-L/--language`. +- **A new `--show-paths` command**: By running `tldr --show-paths`, you can list + the currently used config dir, cache dir, upstream pages dir and custom pages dir. +- **Compliance with the tldr client spec v1.5**: We renamed `-o/--os` to + `-p/--platform` and implemented transparent lowercasing of the page names. +- **Docs**: The README based documentation has reached its limits. There are + now new mdbook based docs over at + [dbrgn.github.io/tealdeer/](https://dbrgn.github.io/tealdeer/), we hope these + make using tealdeer easier. Of course, documentation improvements are + welcome! Also, if you're confused about how to use a certain feature, feel + free to open an issue, this way we can improve the docs. + +Note that the MSRV (Minimal Supported Rust Version) of the project +[changed][i190]: + +> When publishing a Tealdeer release, the Rust version required to build it +> should be stable for at least a month. + +Changes: + +- [added] Support custom pages and patches ([#142][i142]) +- [added] Multi-language support ([#125][i125], [#161][i161]) +- [added] Add support for ANSI code and RGB colors ([#148][i148]) +- [added] Implement new `--show-paths` command ([#162][i162]) +- [added] Support for italic text styling ([#197][i197]) +- [added] Allow SunOS platform override ([#176][i176]) +- [added] Automatically lowercase page names before lookup ([#227][i227]) +- [added] Add "macos" alias for "osx" ([#215][i215]) +- [fixed] Consider only standalone command names for styling ([#157][i157]) +- [fixed] Fixed and improved zsh completions ([#168][i168]) +- [fixed] Create cache directory path if it does not exist ([#174][i174]) +- [fixed] Use default style if user-defined style is missing ([#210][i210]) +- [changed] Switch from docopt to clap for argument parsing ([#108][i108]) +- [changed] Performance improvements ([#187][i187]) +- [changed] Send all progress logging messages to stderr ([#171][i171]) +- [changed] Rename `-o/--os` to `-p/--platform` ([#217][i217]) +- [changed] Rename `-m/--markdown` to `-r/--raw` ([#108][i108]) +- [deprecated] The `--config-path` command is deprecated, use `--show-paths` instead ([#162][i162]) +- [deprecated] The `-o/--os` command is deprecated, use `-p/--platform` instead ([#217][i217]) +- [deprecated] The `-m/--markdown` command is deprecated, use `-r/--raw` instead ([#108][i108]) +- [docs] New docs at [dbrgn.github.io/tealdeer/](https://dbrgn.github.io/tealdeer/) +- [docs] Add comparative benchmarks with hyperfine ([#163][i163], [README](https://github.com/dbrgn/tealdeer#goals)) +- [chore] Download tldr pages archive from their website, not from GitHub ([#213][i213]) +- [chore] Bump MSRV to 1.54 and change MSRV policy ([#190][i190]) +- [chore] The `master` branch was renamed to `main` +- [chore] All release binaries are now generated in CI. Binaries for macOS and Windows are also provided. ([#240][i240]) +- [chore] Update all dependencies + +Contributors to this version: + +- [@bl-ue][@bl-ue] +- [Cameron Tod][@cam8001] +- [Dalton][@dmaahs2017] +- [Danilo Bargen][@dbrgn] +- [Danny Mösch][@SimplyDanny] +- [Marcin Puc][@tranzystorek-io] +- [Michael Cho][@cho-m] +- [MS_Y][@black7375] +- [Niklas Mohrin][@niklasmohrin] +- [Rithvik Vibhu][@rithvikvibhu] +- [rnd][@0ndorio] +- [Sondre Nilsen][@sondr3] +- [Tomás Farías Santana][@tomasfarias] +- [Tsvetomir Bonev][@invakid404] +- [@tveness][@tveness] +- [ギャラ][@laxect] + +Thanks! + +Last but not least, [Niklas Mohrin][@niklasmohrin] has joined the project as +co-maintainer. Thank you for your help! ### [v1.4.1][v1.4.1] (2020-09-04) @@ -18,8 +107,9 @@ Possible log types: Contributors to this version: -- [Francesco][@BachoSeven] +- [Danilo Bargen][@dbrgn] - [Bruno A. Muciño][@mucinoab] +- [Francesco][@BachoSeven] Thanks! @@ -35,6 +125,7 @@ Thanks! Contributors to this version: - [Atul Bhosale][@Atul9] +- [Danilo Bargen][@dbrgn] - [Danny Mösch][@SimplyDanny] - [Ilaï Deutel][@ilai-deutel] - [Kornel][@kornelski] @@ -59,13 +150,14 @@ Thanks! Contributors to this version: -- [@Calinou][@Calinou] -- [@Delapouite][@Delapouite] -- [@james2doyle][@james2doyle] -- [@jesdazrez][@jesdazrez] +- [Bruno Heridet][@Delapouite] +- [Danilo Bargen][@dbrgn] +- [Hugo Locurcio][@Calinou] +- [Isak Johansson][@Plommonsorbet] +- [James Doyle][@james2doyle] +- [Jesús Trinidad Díaz Ramírez][@jesdazrez] - [@korrat][@korrat] -- [@ma-renaud][@ma-renaud] -- [@Plommonsorbet][@Plommonsorbet] +- [Marc-André Renaud][@ma-renaud] Thanks! @@ -84,14 +176,15 @@ Thanks! Contributors to this version: -- [@aldanor][@aldanor] -- [@Bassets][@Bassets] -- [@das-g][@das-g] -- [@jcgruenhage][@jcgruenhage] -- [@jdvr][@jdvr] -- [@jedahan][@jedahan] -- [@mystal][@mystal] -- [@natpen][@natpen] +- [Bar Hatsor][@Bassets] +- [Danilo Bargen][@dbrgn] +- [Gabriel Martinez][@mystal] +- [Ivan Smirnov][@aldanor] +- [Jan Christian Grünhage][@jcgruenhage] +- [Jonathan Dahan][@jedahan] +- [Juan D. Vega][@jdvr] +- [Natalie Pendragon][@natpen] +- [Raphael Das Gupta][@das-g] Thanks! @@ -106,6 +199,7 @@ Thanks! Contributors to this version: +- [Danilo Bargen][@dbrgn] - [@equal-l2][@equal-l2] - [Jonathan Dahan][@jedahan] - [Lukas Bergdoll][@Voultapher] @@ -137,15 +231,23 @@ Thanks! - First crates.io release +[@0ndorio]: https://github.com/0ndorio [@aldanor]: https://github.com/aldanor [@Atul9]: https://github.com/Atul9 [@BachoSeven]: https://github.com/BachoSeven [@Bassets]: https://github.com/Bassets +[@black7375]: https://github.com/black7375 +[@bl-ue]: https://github.com/bl-ue [@Calinou]: https://github.com/Calinou +[@cam8001]: https://github.com/cam8001 +[@cho-m]: https://github.com/cho-m [@das-g]: https://github.com/das-g +[@dbrgn]: https://github.com/dbrgn [@Delapouite]: https://github.com/Delapouite +[@dmaahs2017]: https://github.com/dmaahs2017 [@equal-l2]: https://github.com/equal-l2 [@ilai-deutel]: https://github.com/ilai-deutel +[@invakid404]: https://github.com/invakid404 [@james2doyle]: https://github.com/james2doyle [@jcgruenhage]: https://github.com/jcgruenhage [@jdvr]: https://github.com/jdvr @@ -153,6 +255,7 @@ Thanks! [@jesdazrez]: https://github.com/jesdazrez [@kornelski]: https://github.com/kornelski [@korrat]: https://github.com/korrat +[@laxect]: https://github.com/laxect [@LovecraftianHorror]: https://github.com/LovecraftianHorror [@ma-renaud]: https://github.com/ma-renaud [@michaeldel]: https://github.com/michaeldel @@ -161,7 +264,12 @@ Thanks! [@natpen]: https://github.com/natpen [@niklasmohrin]: https://github.com/niklasmohrin [@Plommonsorbet]: https://github.com/Plommonsorbet +[@rithvikvibhu]: https://github.com/rithvikvibhu [@SimplyDanny]: https://github.com/SimplyDanny +[@sondr3]: https://github.com/sondr3 +[@tomasfarias]: https://github.com/tomasfarias +[@tranzystorek-io]: https://github.com/tranzystorek-io +[@tveness]: https://github.com/tveness [@Voultapher]: https://github.com/Voultapher [v1.0.0]: https://github.com/dbrgn/tealdeer/compare/v0.4.0...v1.0.0 @@ -170,6 +278,7 @@ Thanks! [v1.3.0]: https://github.com/dbrgn/tealdeer/compare/v1.2.0...v1.3.0 [v1.4.0]: https://github.com/dbrgn/tealdeer/compare/v1.3.0...v1.4.0 [v1.4.1]: https://github.com/dbrgn/tealdeer/compare/v1.4.0...v1.4.1 +[v1.5.0]: https://github.com/dbrgn/tealdeer/compare/v1.4.1...v1.5.0 [i34]: https://github.com/dbrgn/tealdeer/issues/34 [i43]: https://github.com/dbrgn/tealdeer/issues/43 @@ -191,8 +300,29 @@ Thanks! [i95]: https://github.com/dbrgn/tealdeer/issues/95 [i97]: https://github.com/dbrgn/tealdeer/issues/97 [i99]: https://github.com/dbrgn/tealdeer/issues/99 +[i108]: https://github.com/dbrgn/tealdeer/pull/108 [i111]: https://github.com/dbrgn/tealdeer/issues/111 [i112]: https://github.com/dbrgn/tealdeer/issues/112 [i113]: https://github.com/dbrgn/tealdeer/issues/113 [i115]: https://github.com/dbrgn/tealdeer/issues/115 +[i125]: https://github.com/dbrgn/tealdeer/pull/125 [i138]: https://github.com/dbrgn/tealdeer/issues/138 +[i142]: https://github.com/dbrgn/tealdeer/pull/142 +[i148]: https://github.com/dbrgn/tealdeer/pull/148 +[i157]: https://github.com/dbrgn/tealdeer/pull/157 +[i161]: https://github.com/dbrgn/tealdeer/pull/161 +[i162]: https://github.com/dbrgn/tealdeer/pull/162 +[i163]: https://github.com/dbrgn/tealdeer/pull/163 +[i168]: https://github.com/dbrgn/tealdeer/pull/168 +[i171]: https://github.com/dbrgn/tealdeer/pull/171 +[i174]: https://github.com/dbrgn/tealdeer/pull/174 +[i176]: https://github.com/dbrgn/tealdeer/pull/176 +[i187]: https://github.com/dbrgn/tealdeer/pull/187 +[i190]: https://github.com/dbrgn/tealdeer/issues/190 +[i197]: https://github.com/dbrgn/tealdeer/pull/197 +[i210]: https://github.com/dbrgn/tealdeer/pull/210 +[i213]: https://github.com/dbrgn/tealdeer/pull/213 +[i215]: https://github.com/dbrgn/tealdeer/pull/215 +[i217]: https://github.com/dbrgn/tealdeer/pull/217 +[i227]: https://github.com/dbrgn/tealdeer/pull/227 +[i240]: https://github.com/dbrgn/tealdeer/pull/240 diff --git a/Cargo.lock b/Cargo.lock index 692eb44..0c55e8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1275,7 +1275,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.4.1" +version = "1.5.0" dependencies = [ "ansi_term", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index 9ea2c9d..22c9ca3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" -version = "1.4.1" +version = "1.5.0" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "/bash_tealdeer", "/fish_tealdeer"] edition = "2018" diff --git a/RELEASING.md b/RELEASING.md index 28ccc28..6eb868c 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -14,6 +14,10 @@ Update version numbers: $ vim Cargo.toml $ cargo update -p tealdeer +Update docs: + + $ cargo run -- --help > docs/src/usage.txt + Update changelog: $ vim CHANGELOG.md @@ -28,6 +32,4 @@ Publish: $ cargo publish $ git push && git push --tags -Create release binaries: - - $ ./release-build.sh +Then publish the release on GitHub. diff --git a/docs/src/usage.txt b/docs/src/usage.txt index d410139..8e7ae5b 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.4.1 +tealdeer 1.5.0 Danilo Bargen , Niklas Mohrin A fast TLDR client From 8228d3145107d7e6429f23125abb0c31d6757b4c Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 1 Jan 2022 14:43:58 +0100 Subject: [PATCH 023/196] upload-asset script: Change release name --- scripts/upload-asset.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upload-asset.sh b/scripts/upload-asset.sh index 7f0a9c3..4f9de09 100644 --- a/scripts/upload-asset.sh +++ b/scripts/upload-asset.sh @@ -29,7 +29,7 @@ create_release() { --header "Authorization: Bearer $token" \ --header "Content-Type:application/json" \ "https://api.github.com/repos/$repo/releases" \ - -d '{"tag_name":"'"$tag"'","name":"'"${tag/v/Release }"'","draft":true,"body":"'"${description/\"/\\\"}"'"}' + -d '{"tag_name":"'"$tag"'","name":"'"${tag/v/Version }"'","draft":true,"body":"'"${description/\"/\\\"}"'"}' ) if [ "$http_code" == "201" ]; then echo "Release for tag $tag created." From b09f25037045b4c7b04e26fda8007a3f639696aa Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 1 Jan 2022 15:10:20 +0100 Subject: [PATCH 024/196] Use clap 3 stable (#243) --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c55e8f..e8e1073 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,9 +130,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.0-rc.11" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f243c7279f09ffed852a0a564c72091331651484cdbb32b7287f16df8611a7" +checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" dependencies = [ "atty", "bitflags", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.0.0-rc.11" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd9992739777a4a23535089a8d235eac43044ba8b431d9f54fe334dfa779930" +checksum = "e1b9752c030a14235a0bd5ef3ad60a1dcac8468c30921327fc8af36b20c790b9" dependencies = [ "heck", "proc-macro-error", diff --git a/Cargo.toml b/Cargo.toml index 22c9ca3..45a2f5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ path = "src/main.rs" ansi_term = "0.12.0" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" -clap = { version = "=3.0.0-rc.11", features = ["std", "derive", "suggestions", "color"], default-features = false } +clap = { version = "3", features = ["std", "derive", "suggestions", "color"], default-features = false } env_logger = { version = "0.9", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } From 47a4d6d7ca3be54aca13c183127e4aedb5e486d1 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 02:04:52 +0100 Subject: [PATCH 025/196] Docs: Remove note about patch concatenation (#245) --- docs/src/usage_custom_pages.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md index bdae7a9..d3d1e81 100644 --- a/docs/src/usage_custom_pages.md +++ b/docs/src/usage_custom_pages.md @@ -33,9 +33,6 @@ want to extend it with your own examples that you frequently need. In this case, use a file called `.patch`, it will be appended to existing pages. -> **Note:** Because the patch file will be concatenated directly to the page -> file, it needs to start with an empty line. - Path: $CUSTOM_PAGES_DIR/.patch From eadfe973351bce9624e0b55a2a2e94cd42f1311f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 20:51:44 +0100 Subject: [PATCH 026/196] CHANGELOG: Mention the switch to Rustls --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdf6e5e..5546cc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ Changes: - [fixed] Create cache directory path if it does not exist ([#174][i174]) - [fixed] Use default style if user-defined style is missing ([#210][i210]) - [changed] Switch from docopt to clap for argument parsing ([#108][i108]) +- [changed] Switch from OpenSSL to Rustls ([#187][i187]) - [changed] Performance improvements ([#187][i187]) - [changed] Send all progress logging messages to stderr ([#171][i171]) - [changed] Rename `-o/--os` to `-p/--platform` ([#217][i217]) From 84277cc31ef93cbd9767fe502d89d2675be261e7 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 8 Jan 2022 22:01:36 +0100 Subject: [PATCH 027/196] Cache: Return error if HTTP client cannot be created (#247) Apparently `Client::new` can panic (see #244), so let's return the error instead. --- src/cache.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cache.rs b/src/cache.rs index 87db30c..2eef24a 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -153,7 +153,9 @@ impl Cache { builder = builder.proxy(proxy); } } - let client = builder.build().unwrap_or_else(|_| Client::new()); + let client = builder.build().map_err(|e| { + TealdeerError::UpdateError(format!("Could not instantiate HTTP client: {}", e)) + })?; let mut resp = client.get(&self.url).send()?; let mut buf: Vec = vec![]; let bytes_downloaded = resp.copy_to(&mut buf)?; From 9e97d454f090fc2b3dcd30a0fc9d2a68f130bac0 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 20:13:17 +0100 Subject: [PATCH 028/196] Add anyhow dependency --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + 2 files changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index e8e1073..12da210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyhow" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" + [[package]] name = "app_dirs2" version = "2.3.3" @@ -1278,6 +1284,7 @@ name = "tealdeer" version = "1.5.0" dependencies = [ "ansi_term", + "anyhow", "app_dirs2", "assert_cmd", "atty", diff --git a/Cargo.toml b/Cargo.toml index 45a2f5d..82d7cc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ path = "src/main.rs" [dependencies] ansi_term = "0.12.0" +anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" clap = { version = "3", features = ["std", "derive", "suggestions", "color"], default-features = false } From 405a2c9c8f09facb658975067b81171201348b55 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 20:13:52 +0100 Subject: [PATCH 029/196] Port config module to anyhow results --- src/config.rs | 87 +++++++++++++++++++++------------------------------ src/error.rs | 4 +-- src/main.rs | 31 ++++-------------- src/utils.rs | 11 +++++++ 4 files changed, 53 insertions(+), 80 deletions(-) diff --git a/src/config.rs b/src/config.rs index 32e902e..60c8879 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,19 +1,17 @@ use std::{ env, fs, - io::{Error as IoError, Read, Write}, + io::{Read, Write}, path::PathBuf, time::Duration, }; use ansi_term::{Color, Style}; +use anyhow::{ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use log::debug; use serde_derive::{Deserialize, Serialize}; -use crate::{ - error::TealdeerError::{self, ConfigError}, - types::PathSource, -}; +use crate::types::PathSource; pub const CONFIG_FILE_NAME: &str = "config.toml"; pub const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days @@ -278,32 +276,24 @@ impl From for Config { } } -#[allow(clippy::needless_pass_by_value)] -fn map_io_err_to_config_err(e: IoError) -> TealdeerError { - ConfigError(format!("Io Error: {}", e)) -} - impl Config { - pub fn load(enable_styles: bool) -> Result { + pub fn load(enable_styles: bool) -> Result { debug!("Loading config"); // Determine path - let (config_file_path, _) = get_config_path() - .map_err(|e| ConfigError(format!("Could not determine config path: {}", e)))?; + let (config_file_path, _) = get_config_path().context("Could not determine config path")?; // Load raw config let raw_config: RawConfig = if config_file_path.exists() && config_file_path.is_file() { - let mut config_file = - fs::File::open(&config_file_path).map_err(map_io_err_to_config_err)?; + let mut config_file = fs::File::open(&config_file_path).with_context(|| { + format!("Failed to open config file path at {:?}", &config_file_path) + })?; let mut contents = String::new(); - let _ = config_file - .read_to_string(&mut contents) - .map_err(map_io_err_to_config_err)?; - toml::from_str(&contents).map_err(|err| { - ConfigError(format!( - "Failed to parse config file at {:?}:\n{}", - config_file_path, err - )) + config_file.read_to_string(&mut contents).with_context(|| { + format!("Failed to read from config file at {:?}", &config_file_path) + })?; + toml::from_str(&contents).with_context(|| { + format!("Failed to parse TOML config file at {:?}", config_file_path) })? } else { RawConfig::new() @@ -334,7 +324,7 @@ impl Config { /// /// Note that this function does not verify whether the directory at that /// location exists, or is a directory. -pub fn get_config_dir() -> Result<(PathBuf, PathSource), TealdeerError> { +pub fn get_config_dir() -> Result<(PathBuf, PathSource)> { // Allow overriding the config directory by setting the // $TEALDEER_CONFIG_DIR env variable. if let Ok(value) = env::var("TEALDEER_CONFIG_DIR") { @@ -342,61 +332,54 @@ pub fn get_config_dir() -> Result<(PathBuf, PathSource), TealdeerError> { }; // Otherwise, fall back to the user config directory. - match get_app_root(AppDataType::UserConfig, &crate::APP_INFO) { - Ok(dirs) => Ok((dirs, PathSource::OsConvention)), - Err(_) => Err(ConfigError( - "Could not determine the user config directory.".into(), - )), - } + let dirs = get_app_root(AppDataType::UserConfig, &crate::APP_INFO) + .context("Failed to determine the user config directory")?; + Ok((dirs, PathSource::OsConvention)) } /// Return the path to the config file. /// /// Note that this function does not verify whether the file at that location /// exists, or is a file. -pub fn get_config_path() -> Result<(PathBuf, PathSource), TealdeerError> { +pub fn get_config_path() -> Result<(PathBuf, PathSource)> { let (config_dir, source) = get_config_dir()?; let config_file_path = config_dir.join(CONFIG_FILE_NAME); Ok((config_file_path, source)) } /// Create default config file. -pub fn make_default_config() -> Result { +pub fn make_default_config() -> Result { let (config_dir, _) = get_config_dir()?; // Ensure that config directory exists - if !config_dir.exists() { - if let Err(e) = fs::create_dir_all(&config_dir) { - return Err(ConfigError(format!( - "Could not create config directory: {}", - e - ))); - } - } else if !config_dir.is_dir() { - return Err(ConfigError(format!( + if config_dir.exists() { + ensure!( + config_dir.is_dir(), "Config directory could not be created: {} already exists but is not a directory", config_dir.to_string_lossy(), - ))); + ); + } else { + fs::create_dir_all(&config_dir).context("Could not create config directory")?; } // Ensure that a config file doesn't get overwritten let config_file_path = config_dir.join(CONFIG_FILE_NAME); - if config_file_path.is_file() { - return Err(ConfigError(format!( - "A configuration file already exists at {}, no action was taken.", - config_file_path.to_str().unwrap() - ))); - } + ensure!( + !config_file_path.is_file(), + "A configuration file already exists at {}, no action was taken.", + config_file_path.to_str().unwrap() + ); // Create default config - let serialized_config = toml::to_string(&RawConfig::new()) - .map_err(|err| ConfigError(format!("Failed to serialize default config: {}", err)))?; + let serialized_config = + toml::to_string(&RawConfig::new()).context("Failed to serialize default config")?; // Write default config - let mut config_file = fs::File::create(&config_file_path).map_err(map_io_err_to_config_err)?; + let mut config_file = + fs::File::create(&config_file_path).context("Could not create config file")?; let _wc = config_file .write(serialized_config.as_bytes()) - .map_err(map_io_err_to_config_err)?; + .context("Could not write to config file")?; Ok(config_file_path) } diff --git a/src/error.rs b/src/error.rs index 548c39f..77169e6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,11 +2,11 @@ use std::fmt; use reqwest::Error as ReqwestError; + #[derive(Debug)] #[allow(clippy::enum_variant_names)] pub enum TealdeerError { CacheError(String), - ConfigError(String), UpdateError(String), WriteError(String), } @@ -15,7 +15,6 @@ impl TealdeerError { pub fn message(&self) -> &str { match self { Self::CacheError(msg) - | Self::ConfigError(msg) | Self::UpdateError(msg) | Self::WriteError(msg) => msg, } @@ -32,7 +31,6 @@ impl fmt::Display for TealdeerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::CacheError(e) => write!(f, "CacheError: {}", e), - Self::ConfigError(e) => write!(f, "ConfigError: {}", e), Self::UpdateError(e) => write!(f, "UpdateError: {}", e), Self::WriteError(e) => write!(f, "WriteError: {}", e), } diff --git a/src/main.rs b/src/main.rs index e6d79df..3644361 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,11 +37,10 @@ mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, config::{get_config_dir, get_config_path, make_default_config, Config}, - error::TealdeerError::ConfigError, extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, - utils::{print_error, print_warning}, + utils::{print_anyhow_error, print_error, print_warning}, }; const NAME: &str = "tealdeer"; @@ -242,15 +241,8 @@ fn show_config_path(enable_styles: bool) { Ok((config_file_path, _)) => { println!("Config path is: {}", config_file_path.to_str().unwrap()); } - Err(ConfigError(msg)) => { - print_error( - enable_styles, - &format!("Could not look up config_path: {}", msg), - ); - process::exit(1); - } - Err(_) => { - print_error(enable_styles, "Unknown error"); + Err(e) => { + print_anyhow_error(enable_styles, &e.context("Could not look up config path")); process::exit(1); } } @@ -316,15 +308,8 @@ fn create_config_and_exit(enable_styles: bool) { ); process::exit(0); } - Err(ConfigError(msg)) => { - print_error( - enable_styles, - &format!("Could not create seed config: {}", msg), - ); - process::exit(1); - } - Err(_) => { - print_error(enable_styles, "Unknown error"); + Err(e) => { + print_anyhow_error(enable_styles, &e); process::exit(1); } } @@ -428,12 +413,8 @@ fn main() { // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { Ok(config) => config, - Err(ConfigError(msg)) => { - print_error(enable_styles, &format!("Could not load config: {}", msg)); - process::exit(1); - } Err(e) => { - print_error(enable_styles, &format!("Could not load config: {}", e)); + print_anyhow_error(enable_styles, &e.context("Could not load config")); process::exit(1); } }; diff --git a/src/utils.rs b/src/utils.rs index e6f65f5..912e147 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -12,6 +12,17 @@ pub fn print_error(enable_styles: bool, message: &str) { print_msg(enable_styles, message, "Error: ", Color::Red); } +/// Print an anyhow error to stderr. If `enable_styles` is true, then a red +/// message will be printed. +pub fn print_anyhow_error(enable_styles: bool, error: &anyhow::Error) { + print_msg( + enable_styles, + &format!("{:?}", error), + "Error: ", + Color::Red, + ); +} + fn print_msg(enable_styles: bool, message: &str, prefix: &'static str, color: Color) { if enable_styles { let style = Style::new().fg(color); From fd307757d71ec68fec8c63938490b8266753fd31 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 20:17:22 +0100 Subject: [PATCH 030/196] Port cache and output modules to anyhow results --- src/cache.rs | 116 ++++++++++++++++++++++++-------------------------- src/error.rs | 15 ------- src/main.rs | 31 +++++--------- src/output.rs | 20 ++++----- src/utils.rs | 8 +--- tests/lib.rs | 2 +- 6 files changed, 77 insertions(+), 115 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 2eef24a..457d68e 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -4,19 +4,17 @@ use std::{ fs::{self, File}, io::{BufReader, Cursor, Read, Seek}, path::{Path, PathBuf}, + time::{Duration, SystemTime}, }; +use anyhow::{ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use log::debug; use reqwest::{blocking::Client, Proxy}; -use std::time::{Duration, SystemTime}; use walkdir::{DirEntry, WalkDir}; use zip::ZipArchive; -use crate::{ - error::TealdeerError::{self, CacheError, UpdateError}, - types::{PathSource, PlatformType}, -}; +use crate::types::{PathSource, PlatformType}; static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR"; @@ -53,16 +51,16 @@ impl PageLookupResult { /// /// This will return an error if either the page file or the patch file /// cannot be opened. - pub fn reader(&self) -> Result>, String> { + pub fn reader(&self) -> Result>> { // Open page file let page_file = File::open(&self.page_path) - .map_err(|msg| format!("Could not open page file at {:?}: {}", self.page_path, msg))?; + .with_context(|| format!("Could not open page file at {:?}", self.page_path))?; // Open patch file let patch_file_opt = match &self.patch_path { Some(path) => Some( File::open(path) - .map_err(|msg| format!("Could not open patch file at {:?}: {}", path, msg))?, + .with_context(|| format!("Could not open patch file at {:?}", path))?, ), None => None, }; @@ -102,26 +100,25 @@ impl Cache { } /// Return the path to the cache directory. - pub fn get_cache_dir() -> Result<(PathBuf, PathSource), TealdeerError> { + pub fn get_cache_dir() -> Result<(PathBuf, PathSource)> { // Allow overriding the cache directory by setting the env variable. if let Ok(value) = env::var(CACHE_DIR_ENV_VAR) { let path = PathBuf::from(value); let (path_exists, path_is_dir) = path .metadata() .map_or((false, false), |md| (true, md.is_dir())); - if path_exists && !path_is_dir { - return Err(CacheError(format!( - "Path specified by ${} is not a directory.", - CACHE_DIR_ENV_VAR - ))); - } + ensure!( + !path_exists || path_is_dir, + "Path specified by ${} is not a directory", + CACHE_DIR_ENV_VAR + ); if !path_exists { // Try to create the complete directory path. - fs::create_dir_all(&path).map_err(|_| { - CacheError(format!( - "Directory path specified by ${} cannot be created.", + fs::create_dir_all(&path).with_context(|| { + format!( + "Directory path specified by ${} cannot be created", CACHE_DIR_ENV_VAR - )) + ) })?; eprintln!( "Successfully created cache directory path `{}`.", @@ -132,16 +129,13 @@ impl Cache { }; // Otherwise, fall back to user cache directory. - match get_app_root(AppDataType::UserCache, &crate::APP_INFO) { - Ok(dirs) => Ok((dirs, PathSource::OsConvention)), - Err(_) => Err(CacheError( - "Could not determine user cache directory.".into(), - )), - } + let dirs = get_app_root(AppDataType::UserCache, &crate::APP_INFO) + .context("Could not determine user cache directory")?; + Ok((dirs, PathSource::OsConvention)) } /// Download the archive - fn download(&self) -> Result, TealdeerError> { + fn download(&self) -> Result> { let mut builder = Client::builder(); if let Ok(ref host) = env::var("HTTP_PROXY") { if let Ok(proxy) = Proxy::http(host) { @@ -153,9 +147,9 @@ impl Cache { builder = builder.proxy(proxy); } } - let client = builder.build().map_err(|e| { - TealdeerError::UpdateError(format!("Could not instantiate HTTP client: {}", e)) - })?; + let client = builder + .build() + .context("Could not instantiate HTTP client")?; let mut resp = client.get(&self.url).send()?; let mut buf: Vec = vec![]; let bytes_downloaded = resp.copy_to(&mut buf)?; @@ -169,7 +163,7 @@ impl Cache { } /// Update the pages cache. - pub fn update(&self) -> Result<(), TealdeerError> { + pub fn update(&self) -> Result<()> { // First, download the compressed data let bytes: Vec = self.download()?; @@ -182,8 +176,7 @@ impl Cache { // Make sure that cache directory exists debug!("Ensure cache directory {:?} exists", &cache_dir); - fs::create_dir_all(&cache_dir) - .map_err(|e| UpdateError(format!("Could not create cache directory: {}", e)))?; + fs::create_dir_all(&cache_dir).context("Could not create cache directory")?; // Clear cache directory // Note: This is not the best solution. Ideally we would download the @@ -191,12 +184,12 @@ impl Cache { // But renaming a directory doesn't work across filesystems and Rust // does not yet offer a recursive directory copying function. So for // now, we'll use this approach. - Self::clear()?; + Self::clear().context("Could not clear the cache directory")?; // Extract archive archive .extract(&pages_dir) - .map_err(|e| UpdateError(format!("Could not unpack compressed data: {}", e)))?; + .context("Could not unpack compressed data")?; Ok(()) } @@ -308,7 +301,7 @@ impl Cache { } /// Return the available pages. - pub fn list_pages(&self) -> Result, TealdeerError> { + pub fn list_pages(&self) -> Result> { // Determine platforms directory and platform let (cache_dir, _) = Self::get_cache_dir()?; let platforms_dir = cache_dir.join(TLDR_PAGES_DIR).join("pages"); @@ -353,35 +346,36 @@ impl Cache { } /// Delete the cache directory. - pub fn clear() -> Result<(), TealdeerError> { + pub fn clear() -> Result<()> { let (path, _) = Self::get_cache_dir()?; - if path.exists() && path.is_dir() { - // Delete old tldr-pages cache location as well if present - // TODO: To be removed in the future - for pages_dir_name in [TLDR_PAGES_DIR, TLDR_OLD_PAGES_DIR] { - let pages_dir = path.join(pages_dir_name); - if pages_dir.exists() { - fs::remove_dir_all(&pages_dir).map_err(|e| { - CacheError(format!( - "Could not remove cache directory ({}): {}", - pages_dir.display(), - e - )) - })?; - } + // Check preconditions + ensure!( + path.exists(), + "Cache path ({}) does not exist.", + path.display(), + ); + ensure!( + path.is_dir(), + "Cache path ({}) is not a directory.", + path.display() + ); + + // Delete old tldr-pages cache location as well if present + // TODO: To be removed in the future + for pages_dir_name in [TLDR_PAGES_DIR, TLDR_OLD_PAGES_DIR] { + let pages_dir = path.join(pages_dir_name); + + if pages_dir.exists() { + fs::remove_dir_all(&pages_dir).with_context(|| { + format!( + "Could not remove the cache directory at {}", + pages_dir.display() + ) + })?; } - } else if path.exists() { - return Err(CacheError(format!( - "Cache path ({}) is not a directory.", - path.display() - ))); - } else { - return Err(CacheError(format!( - "Cache path ({}) does not exist.", - path.display() - ))); - }; + } + Ok(()) } } diff --git a/src/error.rs b/src/error.rs index 77169e6..4a1b0b3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,23 +2,10 @@ use std::fmt; use reqwest::Error as ReqwestError; - #[derive(Debug)] #[allow(clippy::enum_variant_names)] pub enum TealdeerError { - CacheError(String), UpdateError(String), - WriteError(String), -} - -impl TealdeerError { - pub fn message(&self) -> &str { - match self { - Self::CacheError(msg) - | Self::UpdateError(msg) - | Self::WriteError(msg) => msg, - } - } } impl From for TealdeerError { @@ -30,9 +17,7 @@ impl From for TealdeerError { impl fmt::Display for TealdeerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::CacheError(e) => write!(f, "CacheError: {}", e), Self::UpdateError(e) => write!(f, "UpdateError: {}", e), - Self::WriteError(e) => write!(f, "WriteError: {}", e), } } } diff --git a/src/main.rs b/src/main.rs index 3644361..25f31e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,7 @@ use crate::{ extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, - utils::{print_anyhow_error, print_error, print_warning}, + utils::{print_error, print_warning}, }; const NAME: &str = "tealdeer"; @@ -210,10 +210,7 @@ fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult { /// Clear the cache fn clear_cache(quietly: bool, enable_styles: bool) { Cache::clear().unwrap_or_else(|e| { - print_error( - enable_styles, - &format!("Could not delete cache: {}", e.message()), - ); + print_error(enable_styles, &e.context("Could not clear cache")); process::exit(1); }); if !quietly { @@ -224,10 +221,7 @@ fn clear_cache(quietly: bool, enable_styles: bool) { /// Update the cache fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { cache.update().unwrap_or_else(|e| { - print_error( - enable_styles, - &format!("Could not update cache: {}", e.message()), - ); + print_error(enable_styles, &e.context("Could not update cache")); process::exit(1); }); if !quietly { @@ -242,7 +236,7 @@ fn show_config_path(enable_styles: bool) { println!("Config path is: {}", config_file_path.to_str().unwrap()); } Err(e) => { - print_anyhow_error(enable_styles, &e.context("Could not look up config path")); + print_error(enable_styles, &e.context("Could not look up config path")); process::exit(1); } } @@ -309,7 +303,7 @@ fn create_config_and_exit(enable_styles: bool) { process::exit(0); } Err(e) => { - print_anyhow_error(enable_styles, &e); + print_error(enable_styles, &e); process::exit(1); } } @@ -414,7 +408,7 @@ fn main() { let config = match Config::load(enable_styles) { Ok(config) => config, Err(e) => { - print_anyhow_error(enable_styles, &e.context("Could not load config")); + print_error(enable_styles, &e.context("Could not load config")); process::exit(1); } }; @@ -440,8 +434,8 @@ fn main() { // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); - if let Err(msg) = print_page(&path, args.raw, &config) { - print_error(enable_styles, &msg); + if let Err(ref e) = print_page(&path, args.raw, &config) { + print_error(enable_styles, e); process::exit(1); } else { process::exit(0); @@ -476,10 +470,7 @@ fn main() { if args.list { // Get list of pages let pages = cache.list_pages().unwrap_or_else(|e| { - print_error( - enable_styles, - &format!("Could not get list of pages: {}", e.message()), - ); + print_error(enable_styles, &e.context("Could not get list of pages")); process::exit(1); }); @@ -506,8 +497,8 @@ fn main() { &languages, config.directories.custom_pages_dir.as_deref(), ) { - if let Err(msg) = print_page(&lookup_result, args.raw, &config) { - print_error(enable_styles, &msg); + if let Err(ref e) = print_page(&lookup_result, args.raw, &config) { + print_error(enable_styles, e); process::exit(1); } process::exit(0); diff --git a/src/output.rs b/src/output.rs index cad0690..44464dd 100644 --- a/src/output.rs +++ b/src/output.rs @@ -2,10 +2,11 @@ use std::io::{self, BufRead, Write}; +use anyhow::{Context, Result}; + use crate::{ cache::PageLookupResult, config::{Config, StyleConfig}, - error::TealdeerError::WriteError, formatter::{highlight_lines, PageSnippet}, line_iterator::LineIterator, }; @@ -15,7 +16,7 @@ pub fn print_page( lookup_result: &PageLookupResult, enable_markdown: bool, config: &Config, -) -> Result<(), String> { +) -> Result<()> { // Create reader from file(s) let reader = lookup_result.reader()?; @@ -26,8 +27,8 @@ pub fn print_page( if enable_markdown { // Print the raw markdown of the file. for line in reader.lines() { - writeln!(handle, "{}", line.unwrap()) - .map_err(|_| "Could not write to stdout".to_string())?; + let line = line.context("Error while reading from a page")?; + writeln!(handle, "{}", line).context("Could not write to stdout")?; } } else { // Closure that processes a page snippet and writes it to stdout @@ -35,8 +36,7 @@ pub fn print_page( if snip.is_empty() { Ok(()) } else { - print_snippet(&mut handle, snip, &config.style) - .map_err(|e| WriteError(e.to_string())) + print_snippet(&mut handle, snip, &config.style).context("Failed to print snippet") } }; @@ -46,13 +46,11 @@ pub fn print_page( &mut process_snippet, !config.display.compact, ) - .map_err(|e| format!("Could not write to stdout: {}", e.message()))?; + .context("Could not write to stdout")?; }; // We're done outputting data, flush stdout now! - handle - .flush() - .map_err(|_| "Could not flush stdout".to_string())?; + handle.flush().context("Could not flush stdout")?; Ok(()) } @@ -61,7 +59,7 @@ fn print_snippet( writer: &mut impl Write, snip: PageSnippet<'_>, style: &StyleConfig, -) -> Result<(), io::Error> { +) -> io::Result<()> { use PageSnippet::*; match snip { diff --git a/src/utils.rs b/src/utils.rs index 912e147..b47d9f6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,15 +6,9 @@ pub fn print_warning(enable_styles: bool, message: &str) { print_msg(enable_styles, message, "Warning: ", Color::Yellow); } -/// Print an error to stderr. If `enable_styles` is true, then a red message -/// will be printed. -pub fn print_error(enable_styles: bool, message: &str) { - print_msg(enable_styles, message, "Error: ", Color::Red); -} - /// Print an anyhow error to stderr. If `enable_styles` is true, then a red /// message will be printed. -pub fn print_anyhow_error(enable_styles: bool, error: &anyhow::Error) { +pub fn print_error(enable_styles: bool, error: &anyhow::Error) { print_msg( enable_styles, &format!("{:?}", error), diff --git a/tests/lib.rs b/tests/lib.rs index dd03135..0f3128e 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -263,7 +263,7 @@ fn test_cache_location_not_a_directory() { .assert() .failure() .stderr(contains(format!( - "Path specified by ${} is not a directory.", + "Path specified by ${} is not a directory", CACHE_DIR_ENV_VAR ))); } From 52622348466aaf0670162f7940bdf4083b2e2270 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Jan 2022 20:20:48 +0100 Subject: [PATCH 031/196] Remove error module and clean up --- src/error.rs | 23 ----------------------- src/formatter.rs | 4 ++-- src/main.rs | 3 +-- src/types.rs | 11 ++++++----- 4 files changed, 9 insertions(+), 32 deletions(-) delete mode 100644 src/error.rs diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 4a1b0b3..0000000 --- a/src/error.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::fmt; - -use reqwest::Error as ReqwestError; - -#[derive(Debug)] -#[allow(clippy::enum_variant_names)] -pub enum TealdeerError { - UpdateError(String), -} - -impl From for TealdeerError { - fn from(err: ReqwestError) -> Self { - Self::UpdateError(format!("HTTP error: {}", err.to_string())) - } -} - -impl fmt::Display for TealdeerError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::UpdateError(e) => write!(f, "UpdateError: {}", e), - } - } -} diff --git a/src/formatter.rs b/src/formatter.rs index 9789975..c87d39b 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -1,9 +1,9 @@ //! Functions related to formatting and printing lines from a `Tokenizer`. -use crate::{extensions::FindFrom, types::LineType}; - use log::debug; +use crate::{extensions::FindFrom, types::LineType}; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// Represents a snippet from a page of a specific highlighting class. pub enum PageSnippet<'a> { diff --git a/src/main.rs b/src/main.rs index 25f31e4..a7d376d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,6 @@ use pager::Pager; mod cache; mod config; -mod error; pub mod extensions; mod formatter; mod line_iterator; @@ -303,7 +302,7 @@ fn create_config_and_exit(enable_styles: bool) { process::exit(0); } Err(e) => { - print_error(enable_styles, &e); + print_error(enable_styles, &e.context("Could not create seed config")); process::exit(1); } } diff --git a/src/types.rs b/src/types.rs index 3981776..f80aa98 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use std::{fmt, str}; +use anyhow::{anyhow, Result}; use serde_derive::{Deserialize, Serialize}; #[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)] @@ -26,7 +27,7 @@ impl fmt::Display for PlatformType { } impl str::FromStr for PlatformType { - type Err = String; + type Err = anyhow::Error; fn from_str(s: &str) -> Result { match s { @@ -34,7 +35,7 @@ impl str::FromStr for PlatformType { "osx" | "macos" => Ok(Self::OsX), "sunos" => Ok(Self::SunOs), "windows" => Ok(Self::Windows), - other => Err(format!( + other => Err(anyhow!( "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows", other )), @@ -87,14 +88,14 @@ pub enum ColorOptions { } impl str::FromStr for ColorOptions { - type Err = String; + type Err = anyhow::Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { match s { "always" => Ok(Self::Always), "auto" => Ok(Self::Auto), "never" => Ok(Self::Never), - other => Err(format!( + other => Err(anyhow!( "Unknown color option: {}. Possible values: always, auto, never", other )), From 82e4b97f92083407b46939d0d8db0317cb8e9060 Mon Sep 17 00:00:00 2001 From: Marcin Puc Date: Sun, 5 Dec 2021 21:11:31 +0100 Subject: [PATCH 032/196] Move pager configuration near render logic --- src/main.rs | 24 ++++-------------------- src/output.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index a7d376d..a37715f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,8 +21,6 @@ use std::{env, path::PathBuf, process}; use app_dirs::AppInfo; use atty::Stream; use clap::{AppSettings, ArgGroup, Parser}; -#[cfg(not(target_os = "windows"))] -use pager::Pager; mod cache; mod config; @@ -155,17 +153,6 @@ struct Args { version: bool, } -/// Set up display pager -#[cfg(not(target_os = "windows"))] -fn configure_pager(_: bool) { - Pager::with_default_pager("less -R").setup(); -} - -#[cfg(target_os = "windows")] -fn configure_pager(enable_styles: bool) { - print_warning(enable_styles, "--pager flag not available on Windows!"); -} - /// The cache should get updated if this was requested by the user, or if auto /// updates are enabled and the cache age is longer than the auto update interval. fn should_update_cache(args: &Args, config: &Config) -> bool { @@ -412,11 +399,6 @@ fn main() { } }; - // Set up pager - if args.pager || config.display.use_pager { - configure_pager(enable_styles); - } - // Show various paths if args.show_paths { show_paths(&config); @@ -433,7 +415,7 @@ fn main() { // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); - if let Err(ref e) = print_page(&path, args.raw, &config) { + if let Err(ref e) = print_page(&path, args.raw, enable_styles, args.pager, &config) { print_error(enable_styles, e); process::exit(1); } else { @@ -496,7 +478,9 @@ fn main() { &languages, config.directories.custom_pages_dir.as_deref(), ) { - if let Err(ref e) = print_page(&lookup_result, args.raw, &config) { + if let Err(ref e) = + print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) + { print_error(enable_styles, e); process::exit(1); } diff --git a/src/output.rs b/src/output.rs index 44464dd..288dc37 100644 --- a/src/output.rs +++ b/src/output.rs @@ -11,15 +11,34 @@ use crate::{ line_iterator::LineIterator, }; +// Set up display pager +#[cfg(not(target_os = "windows"))] +fn configure_pager(_: bool) { + pager::Pager::with_default_pager("less -R").setup(); +} + +#[cfg(target_os = "windows")] +fn configure_pager(enable_styles: bool) { + use crate::utils::print_warning; + print_warning(enable_styles, "--pager flag not available on Windows!"); +} + /// Print page by path pub fn print_page( lookup_result: &PageLookupResult, enable_markdown: bool, + enable_styles: bool, + use_pager: bool, config: &Config, ) -> Result<()> { // Create reader from file(s) let reader = lookup_result.reader()?; + // Configure pager if applicable + if use_pager || config.display.use_pager { + configure_pager(enable_styles); + } + // Lock stdout only once, this improves performance considerably let stdout = io::stdout(); let mut handle = stdout.lock(); From 4a9763a78335ddea8d6c5614a739318a7c266d05 Mon Sep 17 00:00:00 2001 From: Marcin Puc Date: Sun, 9 Jan 2022 01:43:06 +0100 Subject: [PATCH 033/196] Ensure that pager configuration is run at most once --- src/output.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/output.rs b/src/output.rs index 288dc37..e09481e 100644 --- a/src/output.rs +++ b/src/output.rs @@ -11,10 +11,14 @@ use crate::{ line_iterator::LineIterator, }; -// Set up display pager +/// Set up display pager +/// +/// SAFETY: this function may be called multiple times #[cfg(not(target_os = "windows"))] fn configure_pager(_: bool) { - pager::Pager::with_default_pager("less -R").setup(); + use std::sync::Once; + static INIT: Once = Once::new(); + INIT.call_once(|| pager::Pager::with_default_pager("less -R").setup()); } #[cfg(target_os = "windows")] From 71b6e037a7488cfbacc343ddc5a2a83252df2449 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 9 Jan 2022 15:20:50 +0100 Subject: [PATCH 034/196] When decompressing ZIP fails, propagate error Do not unwrap. Instead, propagate the error with a anyhow context. --- src/cache.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 457d68e..3760067 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -2,7 +2,7 @@ use std::{ env, ffi::OsStr, fs::{self, File}, - io::{BufReader, Cursor, Read, Seek}, + io::{BufReader, Cursor, Read}, path::{Path, PathBuf}, time::{Duration, SystemTime}, }; @@ -157,18 +157,14 @@ impl Cache { Ok(buf) } - /// Decompress and open the archive - fn decompress(reader: R) -> ZipArchive { - ZipArchive::new(reader).unwrap() - } - /// Update the pages cache. pub fn update(&self) -> Result<()> { // First, download the compressed data let bytes: Vec = self.download()?; // Decompress the response body into an `Archive` - let mut archive = Self::decompress(Cursor::new(bytes)); + let mut archive = ZipArchive::new(Cursor::new(bytes)) + .context("Could not decompress downloaded ZIP archive")?; // Determine paths let (cache_dir, _) = Self::get_cache_dir()?; From 77a6d483817862b4b284a2136b4a7ef5f6c94ebc Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 9 Jan 2022 15:23:49 +0100 Subject: [PATCH 035/196] Pages download: Check return status --- src/cache.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cache.rs b/src/cache.rs index 3760067..411a6dd 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -150,7 +150,11 @@ impl Cache { let client = builder .build() .context("Could not instantiate HTTP client")?; - let mut resp = client.get(&self.url).send()?; + let mut resp = client + .get(&self.url) + .send()? + .error_for_status() + .with_context(|| format!("Could not download tldr pages from {}", &self.url))?; let mut buf: Vec = vec![]; let bytes_downloaded = resp.copy_to(&mut buf)?; debug!("{} bytes downloaded", bytes_downloaded); From ef7432c76206df0e9cc8bbdf22735b3633d2d298 Mon Sep 17 00:00:00 2001 From: cyqsimon <28627918+cyqsimon@users.noreply.github.com> Date: Sun, 16 Jan 2022 16:45:11 +0800 Subject: [PATCH 036/196] Enforce default rustfmt settings (#257) --- rustfmt.toml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..e69de29 From 3b4451f8fa352d8a9ffdb293d96ceab90f2d1c7c Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Wed, 19 Jan 2022 23:49:23 +0100 Subject: [PATCH 037/196] Move definition of CLI arguments and options into own file (#258) --- src/cli.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 112 ++------------------------------------------------- 2 files changed, 117 insertions(+), 108 deletions(-) create mode 100644 src/cli.rs diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..38a451a --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,113 @@ +//! Definition of the CLI arguments and options. + +use std::path::PathBuf; + +use clap::{AppSettings, ArgGroup, Parser}; + +use crate::types::{ColorOptions, PlatformType}; + +// Note: flag names are specified explicitly in clap attributes +// to improve readability and allow contributors to grep names like "clear-cache" +#[derive(Parser, Debug)] +#[clap(about = "A fast TLDR client", author, version)] +#[clap(setting = AppSettings::ArgRequiredElseHelp)] +#[clap(setting = AppSettings::DeriveDisplayOrder)] +#[clap(setting = AppSettings::DisableColoredHelp)] +#[clap( + after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." +)] +#[clap(group = ArgGroup::new("command_or_file").args(&["command", "render"]))] +pub(crate) struct Args { + /// The command to show (e.g. `tar` or `git log`) + #[clap(min_values = 1)] + pub command: Vec, + + /// List all commands in the cache + #[clap(short = 'l', long = "list")] + pub list: bool, + + /// Render a specific markdown file + #[clap( + short = 'f', + long = "render", + value_name = "FILE", + conflicts_with = "command" + )] + pub render: Option, + + /// Override the operating system + #[clap( + short = 'p', + long = "platform", + possible_values = ["linux", "macos", "windows", "sunos", "osx"], + )] + pub platform: Option, + + /// Deprecated alias of `platform` + #[clap( + short = 'o', + long = "os", + possible_values = ["linux", "macos", "windows", "sunos", "osx"], + hide = true + )] + pub os: Option, + + /// Override the language + #[clap(short = 'L', long = "language")] + pub language: Option, + + /// Update the local cache + #[clap(short = 'u', long = "update")] + pub update: bool, + + /// Clear the local cache + #[clap(short = 'c', long = "clear-cache")] + pub clear_cache: bool, + + /// Use a pager to page output + #[clap(long = "pager", requires = "command_or_file")] + pub pager: bool, + + /// Display the raw markdown instead of rendering it + #[clap(short = 'r', long = "--raw", requires = "command_or_file")] + pub raw: bool, + + /// Deprecated alias of `raw` + #[clap( + long = "markdown", + short = 'm', + requires = "command_or_file", + hide = true + )] + pub markdown: bool, + + /// Suppress informational messages + #[clap(short = 'q', long = "quiet")] + pub quiet: bool, + + /// Show file and directory paths used by tealdeer + #[clap(long = "show-paths")] + pub show_paths: bool, + + /// Show config file path + #[clap(long = "config-path")] + pub config_path: bool, + + /// Create a basic config + #[clap(long = "seed-config")] + pub seed_config: bool, + + /// Control whether to use color + #[clap( + long = "color", + value_name = "WHEN", + possible_values = ["always", "auto", "never"] + )] + pub color: Option, + + /// Print the version + // Note: We override the version flag because clap uses `-V` by default, + // while TLDR specification requires `-v` to be used. + #[clap(short = 'v', long = "version")] + pub version: bool, +} diff --git a/src/main.rs b/src/main.rs index a37715f..d96b03d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,13 +16,14 @@ #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_lines)] -use std::{env, path::PathBuf, process}; +use std::{env, process}; use app_dirs::AppInfo; use atty::Stream; -use clap::{AppSettings, ArgGroup, Parser}; +use clap::Parser; mod cache; +mod cli; mod config; pub mod extensions; mod formatter; @@ -33,6 +34,7 @@ mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, + cli::Args, config::{get_config_dir, get_config_path, make_default_config, Config}, extensions::Dedup, output::print_page, @@ -47,112 +49,6 @@ const APP_INFO: AppInfo = AppInfo { }; const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; -// Note: flag names are specified explicitly in clap attributes -// to improve readability and allow contributors to grep names like "clear-cache" -#[derive(Parser, Debug)] -#[clap(about = "A fast TLDR client", author, version)] -#[clap(setting = AppSettings::ArgRequiredElseHelp)] -#[clap(setting = AppSettings::DeriveDisplayOrder)] -#[clap(setting = AppSettings::DisableColoredHelp)] -#[clap( - after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." -)] -#[clap(group = ArgGroup::new("command_or_file").args(&["command", "render"]))] -struct Args { - /// The command to show (e.g. `tar` or `git log`) - #[clap(min_values = 1)] - command: Vec, - - /// List all commands in the cache - #[clap(short = 'l', long = "list")] - list: bool, - - /// Render a specific markdown file - #[clap( - short = 'f', - long = "render", - value_name = "FILE", - conflicts_with = "command" - )] - render: Option, - - /// Override the operating system - #[clap( - short = 'p', - long = "platform", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], - )] - platform: Option, - - /// Deprecated alias of `platform` - #[clap( - short = 'o', - long = "os", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], - hide = true - )] - os: Option, - - /// Override the language - #[clap(short = 'L', long = "language")] - language: Option, - - /// Update the local cache - #[clap(short = 'u', long = "update")] - update: bool, - - /// Clear the local cache - #[clap(short = 'c', long = "clear-cache")] - clear_cache: bool, - - /// Use a pager to page output - #[clap(long = "pager", requires = "command_or_file")] - pager: bool, - - /// Display the raw markdown instead of rendering it - #[clap(short = 'r', long = "--raw", requires = "command_or_file")] - raw: bool, - - /// Deprecated alias of `raw` - #[clap( - long = "markdown", - short = 'm', - requires = "command_or_file", - hide = true - )] - markdown: bool, - - /// Suppress informational messages - #[clap(short = 'q', long = "quiet")] - quiet: bool, - - /// Show file and directory paths used by tealdeer - #[clap(long = "show-paths")] - show_paths: bool, - - /// Show config file path - #[clap(long = "config-path")] - config_path: bool, - - /// Create a basic config - #[clap(long = "seed-config")] - seed_config: bool, - - /// Control whether to use color - #[clap( - long = "color", - value_name = "WHEN", - possible_values = ["always", "auto", "never"] - )] - color: Option, - - /// Print the version - // Note: We override the version flag because clap uses `-V` by default, - // while TLDR specification requires `-v` to be used. - #[clap(short = 'v', long = "version")] - version: bool, -} - /// The cache should get updated if this was requested by the user, or if auto /// updates are enabled and the cache age is longer than the auto update interval. fn should_update_cache(args: &Args, config: &Config) -> bool { From 21772978718a71e9d216cdcae2431bf08853a843 Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Thu, 20 Jan 2022 09:10:18 +0100 Subject: [PATCH 038/196] Move shell completion scripts to their own directory (#259) * Move shell completion scripts to their own directory * Remove completion scripts from published Cargo package --- .github/workflows/release.yml | 2 +- Cargo.toml | 2 +- bash_tealdeer => completion/bash_tealdeer | 0 fish_tealdeer => completion/fish_tealdeer | 0 zsh_tealdeer => completion/zsh_tealdeer | 0 docs/src/installing.md | 9 ++++++--- 6 files changed, 8 insertions(+), 5 deletions(-) rename bash_tealdeer => completion/bash_tealdeer (100%) rename fish_tealdeer => completion/fish_tealdeer (100%) rename zsh_tealdeer => completion/zsh_tealdeer (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0a7f1c..eb0c0cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: run: | source ./scripts/upload-asset.sh # Upload: - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} completion/${{ matrix.target }}_tealdeer completions_${{ matrix.target }} upload-license: needs: diff --git a/Cargo.toml b/Cargo.toml index 82d7cc1..6752a3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" version = "1.5.0" -include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "/bash_tealdeer", "/fish_tealdeer"] +include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png"] edition = "2018" [[bin]] diff --git a/bash_tealdeer b/completion/bash_tealdeer similarity index 100% rename from bash_tealdeer rename to completion/bash_tealdeer diff --git a/fish_tealdeer b/completion/fish_tealdeer similarity index 100% rename from fish_tealdeer rename to completion/fish_tealdeer diff --git a/zsh_tealdeer b/completion/zsh_tealdeer similarity index 100% rename from zsh_tealdeer rename to completion/zsh_tealdeer diff --git a/docs/src/installing.md b/docs/src/installing.md index ed16a33..9ad35e2 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -57,6 +57,9 @@ To enable the log output, set the `RUST_LOG` env variable: ## Autocompletion -- *Bash*: copy `bash_tealdeer` to `/usr/share/bash-completion/completions/tldr` -- *Fish*: copy `fish_tealdeer` to `~/.config/fish/completions/tldr.fish` -- *Zsh*: copy `zsh_tealdeer` to `/usr/share/zsh/site-functions/_tldr` +Shell completion scripts are located in the folder `completion`. +Just copy them to their designated location: + +- *Bash*: `cp completion/bash_tealdeer /usr/share/bash-completion/completions/tldr` +- *Fish*: `cp completion/fish_tealdeer ~/.config/fish/completions/tldr.fish` +- *Zsh*: `cp completion/zsh_tealdeer /usr/share/zsh/site-functions/_tldr` From d5dbe3084ba36d5e9c549bc8ba948d9275014b3b Mon Sep 17 00:00:00 2001 From: cyqsimon <28627918+cyqsimon@users.noreply.github.com> Date: Fri, 21 Jan 2022 16:12:10 +0800 Subject: [PATCH 039/196] Add `no-auto-update` flag (#257) * Added `no-auto-update` * Updated usage.txt * Add `no-auto-update` to completion scripts * Apply review suggestions --- completion/bash_tealdeer | 2 +- completion/fish_tealdeer | 27 ++++++++++++++------------- completion/zsh_tealdeer | 1 + docs/src/usage.txt | 1 + src/cli.rs | 4 ++++ src/main.rs | 7 ++++--- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/completion/bash_tealdeer b/completion/bash_tealdeer index 2a1429d..ec54b89 100644 --- a/completion/bash_tealdeer +++ b/completion/bash_tealdeer @@ -6,7 +6,7 @@ _tealdeer() _init_completion || return case $prev in - -h|--help|-v|--version|-l|--list|-u|--update|-c|--clear-cache|-p|--pager|-r|--raw|--show-paths|--seed-config|-q|--quiet) + -h|--help|-v|--version|-l|--list|-u|--update|--no-auto-update|-c|--clear-cache|-p|--pager|-r|--raw|--show-paths|--seed-config|-q|--quiet) return ;; -f|--render) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index ee68e2a..2bcf551 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -3,19 +3,20 @@ # https://github.com/dbrgn/tealdeer/ # -complete -c tldr -s h -l help -d 'Print the help message.' -f -complete -c tldr -s v -l version -d 'Show version information.' -f -complete -c tldr -s l -l list -d 'List all commands in the cache.' -f -complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r -complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows' -complete -c tldr -s u -l update -d 'Update the local cache.' -f -complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f -complete -c tldr -s p -l pager -d 'Use a pager to page output.' -f -complete -c tldr -s r -l raw -d 'Display the raw markdown instead of rendering it.' -f -complete -c tldr -s q -l quiet -d 'Suppress informational messages.' -f -complete -c tldr -l show-paths -d 'Show file and directory paths used by tealdeer.' -f -complete -c tldr -l seed-config -d 'Create a basic config.' -f -complete -c tldr -l color -d 'Controls when to use color.' -xa 'always auto never' +complete -c tldr -s h -l help -d 'Print the help message.' -f +complete -c tldr -s v -l version -d 'Show version information.' -f +complete -c tldr -s l -l list -d 'List all commands in the cache.' -f +complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r +complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows' +complete -c tldr -s u -l update -d 'Update the local cache.' -f +complete -c tldr -l no-auto-update -d 'Disable auto-update, override config file' -f +complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f +complete -c tldr -s p -l pager -d 'Use a pager to page output.' -f +complete -c tldr -s r -l raw -d 'Display the raw markdown instead of rendering it.' -f +complete -c tldr -s q -l quiet -d 'Suppress informational messages.' -f +complete -c tldr -l show-paths -d 'Show file and directory paths used by tealdeer.' -f +complete -c tldr -l seed-config -d 'Create a basic config.' -f +complete -c tldr -l color -d 'Controls when to use color.' -xa 'always auto never' function __tealdeer_entries tldr --list | string replace -a -i -r "\,\s" "\n" diff --git a/completion/zsh_tealdeer b/completion/zsh_tealdeer index 28cd34b..872b474 100644 --- a/completion/zsh_tealdeer +++ b/completion/zsh_tealdeer @@ -22,6 +22,7 @@ _tealdeer() { ))' "($I -L --language)"{-L,--language}"[Override the language settings]:lang" "($I -u --update)"{-u,--update}"[Update the local cache]" + "($I)--no-auto-update[Disable auto-update, override config file]" "($I -c --clear-cache)"{-c,--clear-cache}"[Clear the local cache]" "($I)--pager[Use a pager to page output]" "($I -r --raw)"{-r,--raw}"[Display the raw markdown instead of rendering it]" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 8e7ae5b..789b6e3 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -15,6 +15,7 @@ OPTIONS: windows, sunos, osx] -L, --language Override the language -u, --update Update the local cache + --no-auto-update If auto update is configured, disable it for this run -c, --clear-cache Clear the local cache --pager Use a pager to page output -r, --raw Display the raw markdown instead of rendering it diff --git a/src/cli.rs b/src/cli.rs index 38a451a..c7bf0aa 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -60,6 +60,10 @@ pub(crate) struct Args { #[clap(short = 'u', long = "update")] pub update: bool, + /// If auto update is configured, disable it for this run + #[clap(long = "no-auto-update", requires = "command_or_file")] + pub no_auto_update: bool, + /// Clear the local cache #[clap(short = 'c', long = "clear-cache")] pub clear_cache: bool, diff --git a/src/main.rs b/src/main.rs index d96b03d..17e7358 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,11 +49,12 @@ const APP_INFO: AppInfo = AppInfo { }; const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; -/// The cache should get updated if this was requested by the user, or if auto -/// updates are enabled and the cache age is longer than the auto update interval. +/// The cache should be updated if it was explicitly requested, +/// or if an automatic update is due and allowed. fn should_update_cache(args: &Args, config: &Config) -> bool { args.update - || (config.updates.auto_update + || (!args.no_auto_update + && config.updates.auto_update && Cache::last_update().map_or(true, |ago| ago >= config.updates.auto_update_interval)) } From cab6666ffb014aa8bb0a9a31fa36caa85bb78ed1 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 21 Jan 2022 09:14:30 +0100 Subject: [PATCH 040/196] Fix completions: Remove -p for pager --- completion/bash_tealdeer | 2 +- completion/fish_tealdeer | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/completion/bash_tealdeer b/completion/bash_tealdeer index ec54b89..439f546 100644 --- a/completion/bash_tealdeer +++ b/completion/bash_tealdeer @@ -6,7 +6,7 @@ _tealdeer() _init_completion || return case $prev in - -h|--help|-v|--version|-l|--list|-u|--update|--no-auto-update|-c|--clear-cache|-p|--pager|-r|--raw|--show-paths|--seed-config|-q|--quiet) + -h|--help|-v|--version|-l|--list|-u|--update|--no-auto-update|-c|--clear-cache|--pager|-r|--raw|--show-paths|--seed-config|-q|--quiet) return ;; -f|--render) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index 2bcf551..77bc02f 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -11,7 +11,7 @@ complete -c tldr -s p -l platform -d 'Override the operating system.' -xa complete -c tldr -s u -l update -d 'Update the local cache.' -f complete -c tldr -l no-auto-update -d 'Disable auto-update, override config file' -f complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f -complete -c tldr -s p -l pager -d 'Use a pager to page output.' -f +complete -c tldr -l pager -d 'Use a pager to page output.' -f complete -c tldr -s r -l raw -d 'Display the raw markdown instead of rendering it.' -f complete -c tldr -s q -l quiet -d 'Suppress informational messages.' -f complete -c tldr -l show-paths -d 'Show file and directory paths used by tealdeer.' -f From cc22760e5ad438f6fce2e5da4ae62294d6589ef1 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 21 Jan 2022 09:15:52 +0100 Subject: [PATCH 041/196] Align help text and completion descriptions --- completion/fish_tealdeer | 2 +- completion/zsh_tealdeer | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index 77bc02f..acf7f5f 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -9,7 +9,7 @@ complete -c tldr -s l -l list -d 'List all commands in the cache.' -f complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows' complete -c tldr -s u -l update -d 'Update the local cache.' -f -complete -c tldr -l no-auto-update -d 'Disable auto-update, override config file' -f +complete -c tldr -l no-auto-update -d 'If auto update is configured, disable it for this run.' -f complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f complete -c tldr -l pager -d 'Use a pager to page output.' -f complete -c tldr -s r -l raw -d 'Display the raw markdown instead of rendering it.' -f diff --git a/completion/zsh_tealdeer b/completion/zsh_tealdeer index 872b474..7ed5750 100644 --- a/completion/zsh_tealdeer +++ b/completion/zsh_tealdeer @@ -22,7 +22,7 @@ _tealdeer() { ))' "($I -L --language)"{-L,--language}"[Override the language settings]:lang" "($I -u --update)"{-u,--update}"[Update the local cache]" - "($I)--no-auto-update[Disable auto-update, override config file]" + "($I)--no-auto-update[If auto update is configured, disable it for this run]" "($I -c --clear-cache)"{-c,--clear-cache}"[Clear the local cache]" "($I)--pager[Use a pager to page output]" "($I -r --raw)"{-r,--raw}"[Display the raw markdown instead of rendering it]" From 5a1a21b8ab9c8d76fc781ec639cc6d298b25c6fe Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 6 Feb 2022 22:53:48 +0100 Subject: [PATCH 042/196] Add note about auto-updates when cache is missing (#254) --- src/main.rs | 14 ++++++++++++-- tests/lib.rs | 8 ++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 17e7358..216c349 100644 --- a/src/main.rs +++ b/src/main.rs @@ -81,10 +81,20 @@ fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult { CheckCacheResult::CacheFound } CacheFreshness::Missing => { - print_warning( + print_error( enable_styles, - "Cache not found. Please run `tldr --update`.", + &anyhow::anyhow!( + "Page cache not found. Please run `tldr --update` to download the cache." + ), ); + println!("\nNote: You can optionally enable automatic cache updates by adding the"); + println!("following config to your config file:\n"); + println!(" [updates]"); + println!(" auto_update = true\n"); + println!("The path to your config file can be looked up with `tldr --show-paths`."); + println!("To create an initial config file, use `tldr --seed-config`.\n"); + println!("You can find more tips and tricks in our docs:\n"); + println!(" https://dbrgn.github.io/tealdeer/config_updates.html"); CheckCacheResult::CacheMissing } } diff --git a/tests/lib.rs b/tests/lib.rs index 0f3128e..7c54477 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -131,7 +131,7 @@ fn test_missing_cache() { .args(["sl"]) .assert() .failure() - .stderr(contains("Cache not found. Please run `tldr --update`.")); + .stderr(contains("Page cache not found. Please run `tldr --update`")); } #[test] @@ -143,7 +143,7 @@ fn test_update_cache() { .args(["sl"]) .assert() .failure() - .stderr(contains("Cache not found. Please run `tldr --update`.")); + .stderr(contains("Page cache not found. Please run `tldr --update`")); testenv .command() @@ -518,7 +518,7 @@ fn test_list_flag_rendering() { .args(["--list"]) .assert() .failure() - .stderr(contains("Cache not found. Please run `tldr --update`.")); + .stderr(contains("Page cache not found. Please run `tldr --update`")); testenv.add_entry("foo", ""); @@ -551,7 +551,7 @@ fn test_autoupdate_cache() { .args(["--list"]) .assert() .failure() - .stderr(contains("Cache not found. Please run `tldr --update`.")); + .stderr(contains("Page 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_PAGES_DIR); From 786933e5078ff69ed8b0559779bb02e72ae8814a Mon Sep 17 00:00:00 2001 From: Simon Perdrisat Date: Sat, 9 Apr 2022 17:10:22 +0200 Subject: [PATCH 043/196] Docs: Add MacPorts in the list of package managers (#270) --- docs/src/installing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/installing.md b/docs/src/installing.md index 9ad35e2..67c3748 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -19,6 +19,7 @@ Tealdeer has been added to a few package managers: - FreeBSD: [`sysutils/tealdeer`](https://www.freshports.org/sysutils/tealdeer/) - Funtoo: [`app-misc/tealdeer`](https://github.com/funtoo/core-kit/tree/1.4-release/app-misc/tealdeer) - Homebrew: [`tealdeer`](https://formulae.brew.sh/formula/tealdeer) +- MacPorts: [`tealdeer`](https://ports.macports.org/port/tealdeer/) - NetBSD: [`sysutils/tealdeer`](https://pkgsrc.se/sysutils/tealdeer) - Nix: [`tealdeer`](https://nixos.org/nixos/packages.html#tealdeer) - openSUSE: [`tealdeer`](https://software.opensuse.org/package/tealdeer?search_term=tealdeer) From 6e09af2f8b8bbbf25c347453ff07bd7be1090398 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 3 May 2022 21:47:15 +0200 Subject: [PATCH 044/196] Run cargo update --- Cargo.lock | 637 +++++++++++++++++++++-------------------------------- 1 file changed, 252 insertions(+), 385 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12da210..f870127 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,27 +28,27 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.52" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "app_dirs2" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd95d9b31f552568dcad90bb809b795f63795fba32f733eb7435a4d13f5d28f" +checksum = "d6f731ef6e0f345c835c86724f619d3a73d8be0a9505b83d5e2fa34fd1d50261" dependencies = [ "jni", - "ndk-glue", + "ndk-context", "winapi", "xdg", ] [[package]] name = "assert_cmd" -version = "2.0.2" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e996dc7940838b7ef1096b882e29ec30a3149a3a443cdc8dba19ed382eca1fe2" +checksum = "93ae1ddd39efd67689deb1979d80bad3bf7f2b09c6e6117c8d1f2443b5e2f83e" dependencies = [ "bstr", "doc-comment", @@ -71,9 +71,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byteorder" @@ -118,9 +118,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cesu8" @@ -136,26 +136,26 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.0" +version = "3.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" +checksum = "85a35a599b11c089a7f49105658d089b8f2cf0882993c17daf6de15285c2c35d" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", "lazy_static", - "os_str_bytes", - "strsim 0.10.0", + "strsim", "termcolor", "textwrap", ] [[package]] name = "clap_derive" -version = "3.0.0" +version = "3.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b9752c030a14235a0bd5ef3ad60a1dcac8468c30921327fc8af36b20c790b9" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" dependencies = [ "heck", "proc-macro-error", @@ -165,10 +165,19 @@ dependencies = [ ] [[package]] -name = "combine" -version = "4.6.2" +name = "clap_lex" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b2f5d0ee456f3928812dfc8c6d9a1d592b98678f6d56db9b0cd2b7bc6c8db5" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "combine" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" dependencies = [ "bytes", "memchr", @@ -176,9 +185,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -192,48 +201,13 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "crc32fast" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "difflib" version = "0.4.0" @@ -242,18 +216,18 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "dirs" -version = "3.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -274,9 +248,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] @@ -328,10 +302,19 @@ dependencies = [ ] [[package]] -name = "filetime" -version = "0.2.15" +name = "fastrand" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" dependencies = [ "cfg-if", "libc", @@ -341,9 +324,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ "cfg-if", "crc32fast", @@ -378,42 +361,42 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-core", "futures-io", @@ -426,20 +409,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "h2" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ "bytes", "fnv", @@ -462,12 +445,9 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "heck" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -480,13 +460,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" dependencies = [ "bytes", "fnv", - "itoa 1.0.1", + "itoa", ] [[package]] @@ -502,9 +482,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.5.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "httpdate" @@ -520,9 +500,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.16" +version = "0.14.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" dependencies = [ "bytes", "futures-channel", @@ -533,7 +513,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 0.4.8", + "itoa", "pin-project-lite", "socket2", "tokio", @@ -555,12 +535,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.2.3" @@ -574,19 +548,28 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", ] [[package]] -name = "ipnet" -version = "2.3.1" +name = "instant" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" @@ -597,12 +580,6 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.1" @@ -631,9 +608,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] @@ -646,15 +623,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -667,9 +644,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" @@ -679,24 +656,24 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg", ] [[package]] name = "mio" -version = "0.7.14" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", "log", "miow", "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi", ] @@ -710,50 +687,10 @@ dependencies = [ ] [[package]] -name = "ndk" -version = "0.4.0" +name = "ndk-context" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" -dependencies = [ - "bitflags", - "jni-sys", - "ndk-sys", - "num_enum", - "thiserror", -] - -[[package]] -name = "ndk-glue" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" -dependencies = [ - "lazy_static", - "libc", - "log", - "ndk", - "ndk-macro", - "ndk-sys", -] - -[[package]] -name = "ndk-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" -dependencies = [ - "darling", - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ndk-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "normalize-line-endings" @@ -763,18 +700,18 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "ntapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ "winapi", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -789,47 +726,23 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" -dependencies = [ - "proc-macro-crate 1.1.0", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "once_cell" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] [[package]] name = "pager" @@ -849,9 +762,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -859,17 +772,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - [[package]] name = "predicates" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e5a7689e456ab905c22c2b48225bb921aba7c8dfa58440d68ba13f6222a715" +checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" dependencies = [ "difflib", "float-cmp", @@ -881,39 +788,20 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" +checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" [[package]] name = "predicates-tree" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7" +checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" dependencies = [ "predicates-core", "termtree", ] -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-crate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" -dependencies = [ - "thiserror", - "toml", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -940,86 +828,47 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -1049,15 +898,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.8" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258" +checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "hyper", @@ -1071,7 +921,7 @@ dependencies = [ "pin-project-lite", "rustls", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 0.3.0", "serde", "serde_json", "serde_urlencoded", @@ -1102,9 +952,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.2" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" dependencies = [ "log", "ring", @@ -1114,21 +964,30 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.0", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" dependencies = [ "base64", ] @@ -1170,9 +1029,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ "bitflags", "core-foundation", @@ -1183,9 +1042,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ "core-foundation-sys", "libc", @@ -1193,18 +1052,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.132" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -1213,38 +1072,38 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "itoa 1.0.1", + "itoa", "ryu", "serde", ] [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 0.4.8", + "itoa", "ryu", "serde", ] [[package]] name = "slab" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", "winapi", @@ -1256,12 +1115,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -1270,9 +1123,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.84" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" dependencies = [ "proc-macro2", "quote", @@ -1306,13 +1159,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -1320,39 +1173,39 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ "winapi-util", ] [[package]] name = "termtree" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" +checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" [[package]] name = "textwrap" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -1361,9 +1214,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -1376,24 +1229,26 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.15.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc" dependencies = [ "bytes", "libc", "memchr", "mio", "num_cpus", + "once_cell", "pin-project-lite", + "socket2", "winapi", ] [[package]] name = "tokio-rustls" -version = "0.23.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" +checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e" dependencies = [ "rustls", "tokio", @@ -1402,23 +1257,23 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] @@ -1431,20 +1286,32 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] [[package]] -name = "tracing-core" +name = "tracing-attributes" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ "lazy_static", ] @@ -1457,9 +1324,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-normalization" @@ -1470,17 +1337,11 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "untrusted" @@ -1543,10 +1404,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] -name = "wasm-bindgen" -version = "0.2.78" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1554,9 +1421,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", @@ -1569,9 +1436,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" dependencies = [ "cfg-if", "js-sys", @@ -1581,9 +1448,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1591,9 +1458,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -1604,15 +1471,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -1630,9 +1497,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" +checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" dependencies = [ "webpki", ] @@ -1670,18 +1537,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] [[package]] name = "xdg" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a23fe958c70412687039c86f578938b4a0bb50ec788e96bce4d6ab00ddd5803" +checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6" dependencies = [ "dirs", ] From 3629002d5cd22fd53b6a945ae8a662ca11fab029 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 3 May 2022 21:49:44 +0200 Subject: [PATCH 045/196] =?UTF-8?q?Upgrade=20zip:=200.5=20=E2=86=92=200.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 16 +++++++++++++--- Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f870127..5d2a872 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,6 +208,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if", + "lazy_static", +] + [[package]] name = "difflib" version = "0.4.0" @@ -1555,12 +1565,12 @@ dependencies = [ [[package]] name = "zip" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" dependencies = [ "byteorder", "crc32fast", + "crossbeam-utils", "flate2", - "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 6752a3b..6715a8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ serde = "1.0.21" serde_derive = "1.0.21" toml = "0.5.1" walkdir = "2.0.1" -zip = { version = "0.5", default-features = false, features = ["deflate"] } +zip = { version = "0.6", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] pager = "0.16" From 62b6405685aa8a2a125d65a6725ef3f1ef35860f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 3 May 2022 22:10:18 +0200 Subject: [PATCH 046/196] Fix clap deprecation warnings --- src/cli.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index c7bf0aa..ffef863 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -10,12 +10,12 @@ use crate::types::{ColorOptions, PlatformType}; // to improve readability and allow contributors to grep names like "clear-cache" #[derive(Parser, Debug)] #[clap(about = "A fast TLDR client", author, version)] -#[clap(setting = AppSettings::ArgRequiredElseHelp)] -#[clap(setting = AppSettings::DeriveDisplayOrder)] -#[clap(setting = AppSettings::DisableColoredHelp)] #[clap( after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." )] +#[clap(setting = AppSettings::DeriveDisplayOrder)] +#[clap(arg_required_else_help(true))] +#[clap(disable_colored_help(true))] #[clap(group = ArgGroup::new("command_or_file").args(&["command", "render"]))] pub(crate) struct Args { /// The command to show (e.g. `tar` or `git log`) From 750ebf653cee3ee56651668c98b7e4db4c2a5090 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 3 May 2022 22:20:13 +0200 Subject: [PATCH 047/196] CI: Bump rustfmt toolchain to 1.60 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 390e565..8fd0512 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - rust: [1.54, stable] + rust: ['1.54', stable] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 @@ -60,7 +60,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.54 + toolchain: '1.60' override: true - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 From 0f82aa5950e3966b0c1ded6512841d7324a2ba18 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 6 May 2022 12:43:30 +0200 Subject: [PATCH 048/196] Create macOS release builds with bundled root certificates (#272) As reported in https://github.com/dbrgn/tealdeer/issues/244, some users on macOS had problems with `rustls-tls-native-roots`. Since we did not find the root cause of this, we'll build macOS release builds with `rustls-tls-webpki-roots` instead. Fixes #244. --- .github/workflows/ci.yml | 7 +++---- .github/workflows/release.yml | 2 +- Cargo.toml | 5 ++++- src/main.rs | 8 ++++++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fd0512..148913c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,16 +27,15 @@ jobs: uses: actions-rs/cargo@v1 with: command: build - - name: Build with all features + - name: Build with logging and webpki roots uses: actions-rs/cargo@v1 with: command: build - args: --all-features + args: --features logging,webpki-roots --no-default-features - name: Run tests uses: actions-rs/cargo@v1 with: command: test - args: --all-features clippy: name: run clippy lints @@ -51,7 +50,7 @@ jobs: - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - args: --all-features + args: --features logging fmt: name: run rustfmt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eb0c0cf..1e42acc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,7 +83,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: build - args: --release --target x86_64-apple-darwin + args: --release --target x86_64-apple-darwin --no-default-features --features webpki-roots - uses: actions/upload-artifact@v2 with: name: "tealdeer-macos-x86_64" diff --git a/Cargo.toml b/Cargo.toml index 6715a8e..842a9e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ atty = "0.2" clap = { version = "3", features = ["std", "derive", "suggestions", "color"], default-features = false } env_logger = { version = "0.9", optional = true } log = "0.4" -reqwest = { version = "0.11.3", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], default-features = false } +reqwest = { version = "0.11.3", features = ["blocking"], default-features = false } serde = "1.0.21" serde_derive = "1.0.21" toml = "0.5.1" @@ -44,6 +44,9 @@ tempfile = "3.1.0" filetime = "0.2.10" [features] +default = ["native-roots"] +native-roots = ["reqwest/rustls-tls-native-roots"] +webpki-roots = ["reqwest/rustls-tls-webpki-roots"] logging = ["env_logger"] [profile.release] diff --git a/src/main.rs b/src/main.rs index 216c349..8449565 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,14 @@ #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_lines)] +#[cfg(any( + all(feature = "native-roots", feature = "webpki-roots"), + not(any(feature = "native-roots", feature = "webpki-roots")), +))] +compile_error!( + "exactly one of feature \"native-roots\" and feature \"webpki-roots\" must be enabled" +); + use std::{env, process}; use app_dirs::AppInfo; From 4a5410fd0b7944d354c7c50c8b912c80f2acef03 Mon Sep 17 00:00:00 2001 From: Evan Lloyd New-Schmidt Date: Thu, 2 Jun 2022 11:45:11 -0400 Subject: [PATCH 049/196] Add support for android platform tldr added android-specific commands under a new 'android' platform last year: --- completion/bash_tealdeer | 2 +- completion/fish_tealdeer | 2 +- completion/zsh_tealdeer | 1 + docs/src/usage.txt | 2 +- src/cache.rs | 1 + src/cli.rs | 2 +- src/types.rs | 5 ++++- 7 files changed, 10 insertions(+), 5 deletions(-) diff --git a/completion/bash_tealdeer b/completion/bash_tealdeer index 439f546..507e956 100644 --- a/completion/bash_tealdeer +++ b/completion/bash_tealdeer @@ -14,7 +14,7 @@ _tealdeer() return ;; -p|--platform) - COMPREPLY=( $(compgen -W 'linux macos sunos windows' -- "${cur}") ) + COMPREPLY=( $(compgen -W 'linux macos sunos windows android' -- "${cur}") ) return ;; --color) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index acf7f5f..13f0742 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -7,7 +7,7 @@ complete -c tldr -s h -l help -d 'Print the help message.' -f complete -c tldr -s v -l version -d 'Show version information.' -f complete -c tldr -s l -l list -d 'List all commands in the cache.' -f complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r -complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows' +complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows android' complete -c tldr -s u -l update -d 'Update the local cache.' -f complete -c tldr -l no-auto-update -d 'If auto update is configured, disable it for this run.' -f complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f diff --git a/completion/zsh_tealdeer b/completion/zsh_tealdeer index 7ed5750..99c12be 100644 --- a/completion/zsh_tealdeer +++ b/completion/zsh_tealdeer @@ -19,6 +19,7 @@ _tealdeer() { macos sunos windows + android ))' "($I -L --language)"{-L,--language}"[Override the language settings]:lang" "($I -u --update)"{-u,--update}"[Update the local cache]" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 789b6e3..fdc0c9f 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -12,7 +12,7 @@ OPTIONS: -l, --list List all commands in the cache -f, --render Render a specific markdown file -p, --platform Override the operating system [possible values: linux, macos, - windows, sunos, osx] + windows, sunos, osx, android] -L, --language Override the language -u, --update Update the local cache --no-auto-update If auto update is configured, disable it for this run diff --git a/src/cache.rs b/src/cache.rs index 411a6dd..8df8424 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -223,6 +223,7 @@ impl Cache { PlatformType::OsX => "osx", PlatformType::SunOs => "sunos", PlatformType::Windows => "windows", + PlatformType::Android => "android", } } diff --git a/src/cli.rs b/src/cli.rs index ffef863..a35df31 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -39,7 +39,7 @@ pub(crate) struct Args { #[clap( short = 'p', long = "platform", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], + possible_values = ["linux", "macos", "windows", "sunos", "osx", "android"], )] pub platform: Option, diff --git a/src/types.rs b/src/types.rs index f80aa98..aebd32f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -13,6 +13,7 @@ pub enum PlatformType { OsX, SunOs, Windows, + Android, } impl fmt::Display for PlatformType { @@ -22,6 +23,7 @@ impl fmt::Display for PlatformType { Self::OsX => write!(f, "macOS / BSD"), Self::SunOs => write!(f, "SunOS"), Self::Windows => write!(f, "Windows"), + Self::Android => write!(f, "Android"), } } } @@ -35,8 +37,9 @@ impl str::FromStr for PlatformType { "osx" | "macos" => Ok(Self::OsX), "sunos" => Ok(Self::SunOs), "windows" => Ok(Self::Windows), + "android" => Ok(Self::Android), other => Err(anyhow!( - "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows", + "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows, android", other )), } From abbbbf01ed997c891a8fa24cf35c6bb1684b9367 Mon Sep 17 00:00:00 2001 From: Evan Lloyd New-Schmidt Date: Tue, 14 Jun 2022 15:50:18 -0400 Subject: [PATCH 050/196] Add PlatformType::current for android target --- src/types.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/types.rs b/src/types.rs index aebd32f..0cd82d0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -68,6 +68,11 @@ impl PlatformType { Self::Windows } + #[cfg(target_os = "android")] + pub fn current() -> Self { + Self::Android + } + #[cfg(not(any( target_os = "linux", target_os = "macos", @@ -75,7 +80,8 @@ impl PlatformType { target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", - target_os = "windows" + target_os = "windows", + target_os = "android", )))] pub fn current() -> Self { Self::Other From 97b4395e258ae809060dd6cdceb5cab9c76dadcc Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Mon, 20 Jun 2022 20:35:17 +0800 Subject: [PATCH 051/196] Fix typos (#277) --- src/formatter.rs | 8 ++++---- tests/lib.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/formatter.rs b/src/formatter.rs index c87d39b..d5e3b32 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -83,7 +83,7 @@ fn highlight_code<'a, E>( Ok(()) } -/// Yields `NormalCode` and `CommandName` in alternating order according to the occurences of +/// Yields `NormalCode` and `CommandName` in alternating order according to the occurrences of /// `command_name` in `segment`. Variables are not detected here, see `highlight_code` /// instead. fn highlight_code_segment<'a, E>( @@ -113,15 +113,15 @@ fn highlight_code_segment<'a, E>( } /// Checks whether the characters right before and after the substring (given by half-open index interval) are whitespace (if they exist). -fn is_freestanding_substring(surrouding: &str, substring: (usize, usize)) -> bool { +fn is_freestanding_substring(surrounding: &str, substring: (usize, usize)) -> bool { let (start, end) = substring; // "okay" meaning or - let char_before_is_okay = surrouding[..start] + let char_before_is_okay = surrounding[..start] .chars() .last() .filter(|prev_char| !prev_char.is_whitespace()) .is_none(); - let char_after_is_okay = surrouding[end..] + let char_after_is_okay = surrounding[end..] .chars() .next() .filter(|next_char| !next_char.is_whitespace()) diff --git a/tests/lib.rs b/tests/lib.rs index 7c54477..1b25bdb 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -624,7 +624,7 @@ fn test_custom_page_overwrites() { .stdout(diff(expected)); } -/// End-End test to ensure that .patch files are appened to pages in the cache_dir +/// End-End test to ensure that .patch files are appended to pages in the cache_dir #[test] fn test_custom_patch_appends_to_common() { let testenv = TestEnv::new(); From b369678794a7062bdcbc0dceaee8f68910acabb2 Mon Sep 17 00:00:00 2001 From: bagohart Date: Mon, 18 Jul 2022 12:01:03 +0200 Subject: [PATCH 052/196] added missing fish completion for language (#280) --- completion/fish_tealdeer | 1 + 1 file changed, 1 insertion(+) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index 13f0742..601b114 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -8,6 +8,7 @@ complete -c tldr -s v -l version -d 'Show version information.' -f complete -c tldr -s l -l list -d 'List all commands in the cache.' -f complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows android' +complete -c tldr -s L -l language -d 'Override the language' -x complete -c tldr -s u -l update -d 'Update the local cache.' -f complete -c tldr -l no-auto-update -d 'If auto update is configured, disable it for this run.' -f complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f From e94ee92db4dca201a3a91223b26c54c8ff8910aa Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 21 Aug 2022 21:53:10 +0200 Subject: [PATCH 053/196] `cargo clippy --fix` --- src/config.rs | 6 +++--- src/types.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 60c8879..06f5fd4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -224,19 +224,19 @@ pub struct StyleConfig { pub example_variable: Style, } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct DisplayConfig { pub compact: bool, pub use_pager: bool, } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct UpdatesConfig { pub auto_update: bool, pub auto_update_interval: Duration, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct DirectoriesConfig { pub custom_pages_dir: Option, } diff --git a/src/types.rs b/src/types.rs index 0cd82d0..683a81a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -185,7 +185,7 @@ impl LineType { } /// The reason why a certain path (e.g. config path or cache dir) was chosen. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum PathSource { /// OS convention (e.g. XDG on Linux) OsConvention, From db492bc0cf0d16e47e9e9c357a4cbc037ba70e84 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 21 Aug 2022 22:10:40 +0200 Subject: [PATCH 054/196] Upgrade to 2021 edition of Rust To do so, we need to bump the MSRV to 1.56 (released 10/2021). While at it, I actually bumped it all the way to 1.62, where the latest version, (1.62.1) has been released on July 19, which is just more than one month ago. Additionally, I removed `clippy.toml` and instead specified the MSRV in `Cargo.toml`. This will also print an error when trying to compile with an older compiler. --- .github/workflows/ci.yml | 2 +- Cargo.toml | 3 ++- clippy.toml | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 clippy.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 148913c..bfaa6db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - rust: ['1.54', stable] + rust: ['1.62', stable] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index 842a9e4..91c87a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,8 @@ repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" version = "1.5.0" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png"] -edition = "2018" +rust-version = "1.62" +edition = "2021" [[bin]] name = "tldr" diff --git a/clippy.toml b/clippy.toml deleted file mode 100644 index ece14b8..0000000 --- a/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -msrv = "1.54" From a6023a52349f35f533fcb7efee42119ee9ccca31 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 21 Aug 2022 22:13:32 +0200 Subject: [PATCH 055/196] Small fixes in `ci.yml` - Add `profile: minimal` - Install `rustfmt` when installing the toolchain, not afterwards - Use stable toolchain for `rustfmt` - Replace `override` with `default`. I think this better reflects the "use what we just installed" intent. --- .github/workflows/ci.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bfaa6db..8f53a47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,6 @@ on: name: CI jobs: - test: name: run tests strategy: @@ -22,7 +21,8 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} - override: true + profile: minimal + default: true - name: Build with default features uses: actions-rs/cargo@v1 with: @@ -45,8 +45,9 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + profile: minimal + default: true components: clippy - override: true - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -59,9 +60,10 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: '1.60' - override: true - - run: rustup component add rustfmt + toolchain: stable + profile: minimal + default: true + components: rustfmt - uses: actions-rs/cargo@v1 with: command: fmt @@ -79,7 +81,8 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable - override: true + profile: minimal + default: true - name: Build uses: actions-rs/cargo@v1 with: From 65cbe80e9d441833eb37acac51ad964e2d5bf0ae Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 21 Aug 2022 22:24:18 +0200 Subject: [PATCH 056/196] Add comment to empty `rustfmt.toml` --- rustfmt.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/rustfmt.toml b/rustfmt.toml index e69de29..f857430 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -0,0 +1 @@ +# Empty file, use defaults and disregard global settings From f4a94112f49b01570becaa2a5c45d2daeb3a79be Mon Sep 17 00:00:00 2001 From: Olav de Haas <23523462+Olavhaasie@users.noreply.github.com> Date: Sat, 24 Sep 2022 21:27:35 +0200 Subject: [PATCH 057/196] Add custom pages to list output (#285) Fixes #205. --- src/cache.rs | 38 +++++++++++++++++++++++++++++++------- src/main.rs | 10 ++++++---- tests/lib.rs | 12 +++++++++++- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 8df8424..66b1ef7 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -302,7 +302,7 @@ impl Cache { } /// Return the available pages. - pub fn list_pages(&self) -> Result> { + pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Result> { // Determine platforms directory and platform let (cache_dir, _) = Self::get_cache_dir()?; let platforms_dir = cache_dir.join(TLDR_PAGES_DIR).join("pages"); @@ -324,23 +324,47 @@ impl Cache { false }; + let to_stem = |entry: DirEntry| -> Option { + entry + .path() + .file_stem() + .and_then(OsStr::to_str) + .map(str::to_string) + }; + // 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_entry(should_walk) // Filter out pages for other architectures .filter_map(Result::ok) // Convert results to options, filter out errors .filter_map(|e| { - let path = e.path(); - let extension = &path.extension().and_then(OsStr::to_str).unwrap_or(""); - if e.file_type().is_file() && extension == &"md" { - path.file_stem() - .and_then(|stem| stem.to_str().map(Into::into)) + let extension = e.path().extension().unwrap_or_default(); + if e.file_type().is_file() && extension == "md" { + to_stem(e) } else { None } }) .collect::>(); + + if let Some(custom_pages_dir) = custom_pages_dir { + let is_page = |entry: &DirEntry| -> bool { + let extension = entry.path().extension().unwrap_or_default(); + entry.file_type().is_file() && extension == "page" + }; + + let custom_pages = WalkDir::new(custom_pages_dir) + .min_depth(1) + .max_depth(1) + .into_iter() + .filter_entry(is_page) + .filter_map(Result::ok) + .filter_map(to_stem); + + pages.extend(custom_pages); + } + pages.sort(); pages.dedup(); Ok(pages) diff --git a/src/main.rs b/src/main.rs index 8449565..d7d0091 100644 --- a/src/main.rs +++ b/src/main.rs @@ -365,10 +365,12 @@ fn main() { // List cached commands and exit if args.list { // Get list of pages - let pages = cache.list_pages().unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not get list of pages")); - process::exit(1); - }); + let pages = cache + .list_pages(config.directories.custom_pages_dir.as_deref()) + .unwrap_or_else(|e| { + print_error(enable_styles, &e.context("Could not get list of pages")); + process::exit(1); + }); // Print pages println!("{}", pages.join("\n")); diff --git a/tests/lib.rs b/tests/lib.rs index 1b25bdb..6e66764 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -513,6 +513,12 @@ fn test_pager_flag_enable() { fn test_list_flag_rendering() { let testenv = TestEnv::new(); + // set custom pages directory + testenv.write_config(format!( + "[directories]\ncustom_pages_dir = '{}'", + testenv.custom_pages_dir.path().to_str().unwrap() + )); + testenv .command() .args(["--list"]) @@ -532,13 +538,17 @@ fn test_list_flag_rendering() { testenv.add_entry("bar", ""); testenv.add_entry("baz", ""); testenv.add_entry("qux", ""); + testenv.add_page_entry("faz", ""); + testenv.add_page_entry("bar", ""); + testenv.add_page_entry("fiz", ""); + testenv.add_patch_entry("buz", ""); testenv .command() .args(["--list"]) .assert() .success() - .stdout("bar\nbaz\nfoo\nqux\n"); + .stdout("bar\nbaz\nfaz\nfiz\nfoo\nqux\n"); } #[test] From f45a502383917c98b7bb3cace40f0e4c0efbdded Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Sep 2022 22:54:01 +0200 Subject: [PATCH 058/196] Run cargo update (#287) --- Cargo.lock | 456 ++++++++++++++++++++++++++--------------------------- 1 file changed, 223 insertions(+), 233 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d2a872..a5acd53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -28,15 +28,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "app_dirs2" -version = "2.4.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f731ef6e0f345c835c86724f619d3a73d8be0a9505b83d5e2fa34fd1d50261" +checksum = "47a8d2d8dbda5fca0a522259fb88e4f55d2b10ad39f5f03adeebf85031eba501" dependencies = [ "jni", "ndk-context", @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byteorder" @@ -112,9 +112,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" @@ -136,16 +136,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.15" +version = "3.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a35a599b11c089a7f49105658d089b8f2cf0882993c17daf6de15285c2c35d" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim", "termcolor", "textwrap", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.7" +version = "3.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" dependencies = [ "heck", "proc-macro-error", @@ -166,18 +166,18 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] name = "combine" -version = "4.6.4" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes", "memchr", @@ -210,12 +210,12 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] @@ -252,9 +252,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" @@ -267,9 +267,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" dependencies = [ "atty", "humantime", @@ -313,34 +313,32 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "filetime" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi", + "windows-sys", ] [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -361,52 +359,51 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-core", "futures-io", @@ -419,20 +416,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -449,9 +446,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -470,9 +467,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -481,9 +478,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -492,9 +489,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -510,9 +507,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.18" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -547,20 +544,19 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", @@ -583,18 +579,18 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jni" @@ -618,9 +614,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -633,9 +629,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.125" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "log" @@ -646,12 +642,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.5.0" @@ -666,34 +656,23 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "wasi", + "windows-sys", ] [[package]] @@ -708,15 +687,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -738,9 +708,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "openssl-probe" @@ -750,15 +720,15 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "pager" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c7d08cf0d0b55c4f0ffedb5e06569ea212e85d622975071370393970491968" +checksum = "2599211a5c97fbbb1061d3dc751fa15f404927e4846e07c643287d6d1f462880" dependencies = [ "errno", "libc", @@ -766,9 +736,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" @@ -838,27 +808,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -876,9 +846,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -893,9 +863,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -908,9 +878,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ "base64", "bytes", @@ -924,19 +894,20 @@ dependencies = [ "hyper-rustls", "ipnet", "js-sys", - "lazy_static", "log", "mime", + "once_cell", "percent-encoding", "pin-project-lite", "rustls", "rustls-native-certs", - "rustls-pemfile 0.3.0", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-rustls", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -962,9 +933,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" dependencies = [ "log", "ring", @@ -979,34 +950,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.0", + "rustls-pemfile", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "0.3.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" -dependencies = [ - "base64", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ "base64", ] [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1019,12 +981,12 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi", + "windows-sys", ] [[package]] @@ -1039,9 +1001,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -1062,18 +1024,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -1082,9 +1044,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -1105,15 +1067,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -1133,13 +1098,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.92" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" +checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1198,24 +1163,24 @@ checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" [[package]] name = "textwrap" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" dependencies = [ "proc-macro2", "quote", @@ -1239,10 +1204,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.18.1" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc" +checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" dependencies = [ + "autocfg", "bytes", "libc", "memchr", @@ -1256,9 +1222,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ "rustls", "tokio", @@ -1267,9 +1233,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -1290,40 +1256,28 @@ dependencies = [ [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -1339,20 +1293,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] -name = "unicode-normalization" -version = "0.1.19" +name = "unicode-ident" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" - [[package]] name = "untrusted" version = "0.7.1" @@ -1361,13 +1315,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -1407,12 +1360,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1421,9 +1368,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1431,13 +1378,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1446,9 +1393,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -1458,9 +1405,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1468,9 +1415,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -1481,15 +1428,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -1507,9 +1454,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" dependencies = [ "webpki", ] @@ -1545,6 +1492,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "winreg" version = "0.10.1" From 026ae7274220ac4805f22d40dcd8533441a28210 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 27 Sep 2022 23:55:50 +0200 Subject: [PATCH 059/196] Switch from ansi_term to yansi (#288) ansi_term is not actively maintained anymore (see https://rustsec.org/advisories/RUSTSEC-2021-0139). Replace it with a suitable alternative. I looked at termcolor, owo-colors and yansi and picked yansi: - It is very simple - It does not do terminal color support checking (we already do that in tealdeer) - Its color enum type is almost identical to the one from ansi_term, so migrating is easy The only change from a config API point of view is that "purple" is now renamed to "magenta", but "purple" still works. --- Cargo.lock | 17 +++++++---------- Cargo.toml | 2 +- docs/src/config_style.md | 2 +- src/config.rs | 13 +++++++------ src/main.rs | 2 +- src/utils.rs | 5 ++--- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5acd53..a812506 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.65" @@ -1111,7 +1102,6 @@ dependencies = [ name = "tealdeer" version = "1.5.0" dependencies = [ - "ansi_term", "anyhow", "app_dirs2", "assert_cmd", @@ -1129,6 +1119,7 @@ dependencies = [ "tempfile", "toml", "walkdir", + "yansi", "zip", ] @@ -1553,6 +1544,12 @@ dependencies = [ "dirs", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "zip" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index 91c87a1..d845906 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ name = "tldr" path = "src/main.rs" [dependencies] -ansi_term = "0.12.0" anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" @@ -32,6 +31,7 @@ serde = "1.0.21" serde_derive = "1.0.21" toml = "0.5.1" walkdir = "2.0.1" +yansi = "0.5" zip = { version = "0.6", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] diff --git a/docs/src/config_style.md b/docs/src/config_style.md index be2a4cc..527e3e5 100644 --- a/docs/src/config_style.md +++ b/docs/src/config_style.md @@ -22,7 +22,7 @@ Using the config file, the style (e.g. colors or underlines) can be customized. Colors can be specified in one of three ways: -- Color string (`black`, `red`, `green`, `yellow`, `blue`, `purple`, `cyan`, `white`): +- Color string (`black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`): Example: diff --git a/src/config.rs b/src/config.rs index 06f5fd4..74ba195 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,11 +5,11 @@ use std::{ time::Duration, }; -use ansi_term::{Color, Style}; use anyhow::{ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use log::debug; use serde_derive::{Deserialize, Serialize}; +use yansi::{Color, Style}; use crate::types::PathSource; @@ -37,7 +37,8 @@ pub enum RawColor { Green, Yellow, Blue, - Purple, + Magenta, + Purple, // Backwards compatibility with ansi_term (until tealdeer 1.5.0) Cyan, White, Ansi(u8), @@ -52,7 +53,7 @@ impl From for Color { RawColor::Green => Self::Green, RawColor::Yellow => Self::Yellow, RawColor::Blue => Self::Blue, - RawColor::Purple => Self::Purple, + RawColor::Magenta | RawColor::Purple => Self::Magenta, RawColor::Cyan => Self::Cyan, RawColor::White => Self::White, RawColor::Ansi(num) => Self::Fixed(num), @@ -95,7 +96,7 @@ impl From for Style { } if let Some(background) = raw_style.background { - style = style.on(Color::from(background)); + style = style.bg(Color::from(background)); } if raw_style.underline { @@ -215,7 +216,7 @@ impl Default for RawConfig { } } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct StyleConfig { pub description: Style, pub command_name: Style, @@ -241,7 +242,7 @@ pub struct DirectoriesConfig { pub custom_pages_dir: Option, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct Config { pub style: StyleConfig, pub display: DisplayConfig, diff --git a/src/main.rs b/src/main.rs index d7d0091..6752358 100644 --- a/src/main.rs +++ b/src/main.rs @@ -263,7 +263,7 @@ fn main() { // Determine the usage of styles #[cfg(target_os = "windows")] - let ansi_support = ansi_term::enable_ansi_support().is_ok(); + let ansi_support = yansi::Paint::enable_windows_ascii(); #[cfg(not(target_os = "windows"))] let ansi_support = true; let enable_styles = match args.color.unwrap_or_default() { diff --git a/src/utils.rs b/src/utils.rs index b47d9f6..879733a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use ansi_term::{Color, Style}; +use yansi::Color; /// Print a warning to stderr. If `enable_styles` is true, then a yellow /// message will be printed. @@ -19,8 +19,7 @@ pub fn print_error(enable_styles: bool, error: &anyhow::Error) { fn print_msg(enable_styles: bool, message: &str, prefix: &'static str, color: Color) { if enable_styles { - let style = Style::new().fg(color); - eprintln!("{}{}", style.paint(prefix), style.paint(message)); + eprintln!("{}{}", color.paint(prefix), color.paint(message)); } else { eprintln!("{}", message); } From 33f0f108d8c39f8039966d5b9a008ad5ddf754eb Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 16 Jun 2022 20:33:04 +0200 Subject: [PATCH 060/196] Allow overriding cache directory through config - Config: Add `cache_dir` to `[directories]` section - Logic to handle legacy env var, config override and default cache dir selection is now in the `Config::try_from(RawConfig)` impl - Deprecate old `TEALDEER_CACHE_DIR` env variable - Update docs Co-authored-by: Hans Gaiser --- docs/src/config_directories.md | 13 ++++ src/cache.rs | 137 ++++++++++++++------------------- src/config.rs | 94 +++++++++++++++------- src/main.rs | 71 ++++++++--------- tests/lib.rs | 9 ++- 5 files changed, 170 insertions(+), 154 deletions(-) diff --git a/docs/src/config_directories.md b/docs/src/config_directories.md index d894e90..b194dbb 100644 --- a/docs/src/config_directories.md +++ b/docs/src/config_directories.md @@ -2,6 +2,19 @@ This section allows overriding some directory paths. +## `cache_dir` + +Override the cache directory. Remember to use an absolute path. Variable +expansion will not be performed on the path. If the directory does not yet +exist, it will be created. + + [directories] + cache_dir = "/home/myuser/.tealdeer-cache/" + +If no `cache_dir` is specified, tealdeer will fall back to a location that +follows OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`. +Use `tldr --show-paths` to show the path that is being used. + ## `custom_pages_dir` Set the directory to be used to look up [custom diff --git a/src/cache.rs b/src/cache.rs index 66b1ef7..35807ea 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -8,15 +8,12 @@ use std::{ }; use anyhow::{ensure, Context, Result}; -use app_dirs::{get_app_root, AppDataType}; use log::debug; use reqwest::{blocking::Client, Proxy}; use walkdir::{DirEntry, WalkDir}; use zip::ZipArchive; -use crate::types::{PathSource, PlatformType}; - -static CACHE_DIR_ENV_VAR: &str = "TEALDEER_CACHE_DIR"; +use crate::types::PlatformType; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; @@ -25,6 +22,7 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; pub struct Cache { url: String, platform: PlatformType, + cache_dir: PathBuf, } #[derive(Debug)] @@ -54,13 +52,13 @@ impl PageLookupResult { pub fn reader(&self) -> Result>> { // Open page file let page_file = File::open(&self.page_path) - .with_context(|| format!("Could not open page file at {:?}", self.page_path))?; + .with_context(|| format!("Could not open page file at {}", self.page_path.display()))?; // Open patch file let patch_file_opt = match &self.patch_path { Some(path) => Some( File::open(path) - .with_context(|| format!("Could not open patch file at {:?}", path))?, + .with_context(|| format!("Could not open patch file at {}", path.display()))?, ), None => None, }; @@ -89,49 +87,42 @@ pub enum CacheFreshness { } impl Cache { - pub fn new(url: S, platform: PlatformType) -> Self + pub fn new(url: S, platform: PlatformType, cache_dir: P) -> Result where S: Into, + P: Into, { - Self { + // Check whether `cache_dir` exists and is a directory + let cache_dir = cache_dir.into(); + let (cache_dir_exists, cache_dir_is_dir) = cache_dir + .metadata() + .map_or((false, false), |md| (true, md.is_dir())); + ensure!( + !cache_dir_exists || cache_dir_is_dir, + "Cache directory path `{}` is not a directory", + cache_dir.display(), + ); + + // If necessary, create cache directory + if !cache_dir_exists { + // Try to create the complete directory path + fs::create_dir_all(&cache_dir).with_context(|| { + format!( + "Cache directory path `{}` cannot be created", + cache_dir.display(), + ) + })?; + eprintln!( + "Successfully created cache directory path `{}`.", + cache_dir.display(), + ); + } + + Ok(Self { url: url.into(), platform, - } - } - - /// Return the path to the cache directory. - pub fn get_cache_dir() -> Result<(PathBuf, PathSource)> { - // Allow overriding the cache directory by setting the env variable. - if let Ok(value) = env::var(CACHE_DIR_ENV_VAR) { - let path = PathBuf::from(value); - let (path_exists, path_is_dir) = path - .metadata() - .map_or((false, false), |md| (true, md.is_dir())); - ensure!( - !path_exists || path_is_dir, - "Path specified by ${} is not a directory", - CACHE_DIR_ENV_VAR - ); - if !path_exists { - // Try to create the complete directory path. - fs::create_dir_all(&path).with_context(|| { - format!( - "Directory path specified by ${} cannot be created", - CACHE_DIR_ENV_VAR - ) - })?; - eprintln!( - "Successfully created cache directory path `{}`.", - path.to_str().unwrap() - ); - } - return Ok((path, PathSource::EnvVar)); - }; - - // Otherwise, fall back to user cache directory. - let dirs = get_app_root(AppDataType::UserCache, &crate::APP_INFO) - .context("Could not determine user cache directory")?; - Ok((dirs, PathSource::OsConvention)) + cache_dir, + }) } /// Download the archive @@ -171,12 +162,7 @@ impl Cache { .context("Could not decompress downloaded ZIP archive")?; // 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); - fs::create_dir_all(&cache_dir).context("Could not create cache directory")?; + let pages_dir = self.cache_dir.join(TLDR_PAGES_DIR); // Clear cache directory // Note: This is not the best solution. Ideally we would download the @@ -184,7 +170,8 @@ impl Cache { // But renaming a directory doesn't work across filesystems and Rust // does not yet offer a recursive directory copying function. So for // now, we'll use this approach. - Self::clear().context("Could not clear the cache directory")?; + self.clear() + .context("Could not clear the cache directory")?; // Extract archive archive @@ -195,21 +182,19 @@ 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_PAGES_DIR)) { - if let Ok(mtime) = metadata.modified() { - let now = SystemTime::now(); - return now.duration_since(mtime).ok(); - }; + pub fn last_update(&self) -> Option { + if let Ok(metadata) = fs::metadata(self.cache_dir.join(TLDR_PAGES_DIR)) { + if let Ok(mtime) = metadata.modified() { + let now = SystemTime::now(); + return now.duration_since(mtime).ok(); }; }; None } /// Return the freshness of the cache (fresh, stale or missing). - pub fn freshness() -> CacheFreshness { - match Cache::last_update() { + pub fn freshness(&self) -> CacheFreshness { + match self.last_update() { Some(ago) if ago > crate::config::MAX_CACHE_AGE => CacheFreshness::Stale(ago), Some(_) => CacheFreshness::Fresh, None => CacheFreshness::Missing, @@ -258,15 +243,8 @@ impl Cache { let patch_filename = format!("{}.patch", name); let custom_filename = format!("{}.page", name); - // Get cache dir - let cache_dir = match Self::get_cache_dir() { - Ok((cache_dir, _)) => cache_dir.join(TLDR_PAGES_DIR), - Err(e) => { - log::error!("Could not get cache directory: {}", e); - return None; - } - }; - + // Determine directories + let cache_dir = self.cache_dir.join(TLDR_PAGES_DIR); let lang_dirs: Vec = languages .iter() .map(|lang| { @@ -302,10 +280,9 @@ impl Cache { } /// Return the available pages. - pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Result> { + pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Vec { // Determine platforms directory and platform - let (cache_dir, _) = Self::get_cache_dir()?; - let platforms_dir = cache_dir.join(TLDR_PAGES_DIR).join("pages"); + let platforms_dir = self.cache_dir.join(TLDR_PAGES_DIR).join("pages"); let platform_dir = self.get_platform_dir(); // Closure that allows the WalkDir instance to traverse platform @@ -367,29 +344,27 @@ impl Cache { pages.sort(); pages.dedup(); - Ok(pages) + pages } /// Delete the cache directory. - pub fn clear() -> Result<()> { - let (path, _) = Self::get_cache_dir()?; - + pub fn clear(&self) -> Result<()> { // Check preconditions ensure!( - path.exists(), + self.cache_dir.exists(), "Cache path ({}) does not exist.", - path.display(), + self.cache_dir.display(), ); ensure!( - path.is_dir(), + self.cache_dir.is_dir(), "Cache path ({}) is not a directory.", - path.display() + self.cache_dir.display(), ); // Delete old tldr-pages cache location as well if present // TODO: To be removed in the future for pages_dir_name in [TLDR_PAGES_DIR, TLDR_OLD_PAGES_DIR] { - let pages_dir = path.join(pages_dir_name); + let pages_dir = self.cache_dir.join(pages_dir_name); if pages_dir.exists() { fs::remove_dir_all(&pages_dir).with_context(|| { diff --git a/src/config.rs b/src/config.rs index 74ba195..f5e996a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,7 +5,7 @@ use std::{ time::Duration, }; -use anyhow::{ensure, Context, Result}; +use anyhow::{bail, ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use log::debug; use serde_derive::{Deserialize, Serialize}; @@ -164,6 +164,8 @@ impl Default for RawUpdatesConfig { #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] struct RawDirectoriesConfig { + #[serde(default)] + pub cache_dir: Option, #[serde(default)] pub custom_pages_dir: Option, } @@ -171,6 +173,7 @@ struct RawDirectoriesConfig { impl Default for RawDirectoriesConfig { fn default() -> Self { Self { + cache_dir: None, custom_pages_dir: get_app_root(AppDataType::UserData, &crate::APP_INFO) .map(|path| { // Note: The `join("")` call ensures that there's a trailing slash @@ -239,6 +242,7 @@ pub struct UpdatesConfig { #[derive(Clone, Debug, PartialEq, Eq)] pub struct DirectoriesConfig { + pub cache_dir: PathBuf, pub custom_pages_dir: Option, } @@ -250,34 +254,66 @@ pub struct Config { pub directories: DirectoriesConfig, } -impl From for Config { - fn from(raw_config: RawConfig) -> Self { - Self { - style: StyleConfig { - command_name: raw_config.style.command_name.into(), - description: raw_config.style.description.into(), - example_text: raw_config.style.example_text.into(), - example_code: raw_config.style.example_code.into(), - example_variable: raw_config.style.example_variable.into(), - }, - display: DisplayConfig { - compact: raw_config.display.compact, - use_pager: raw_config.display.use_pager, - }, - updates: UpdatesConfig { - auto_update: raw_config.updates.auto_update, - auto_update_interval: Duration::from_secs( - raw_config.updates.auto_update_interval_hours * 3600, - ), - }, - directories: DirectoriesConfig { - custom_pages_dir: raw_config.directories.custom_pages_dir, - }, - } - } -} - impl Config { + /// Convert a `RawConfig` to a high-level `Config`. + /// + /// For this, some values need to be converted to other types and some + /// defaults need to be set (sometimes based on env variables). + fn from_raw(raw_config: RawConfig) -> Result { + // Style config + let style = StyleConfig { + command_name: raw_config.style.command_name.into(), + description: raw_config.style.description.into(), + example_text: raw_config.style.example_text.into(), + example_code: raw_config.style.example_code.into(), + example_variable: raw_config.style.example_variable.into(), + }; + + // Display config + let display = DisplayConfig { + compact: raw_config.display.compact, + use_pager: raw_config.display.use_pager, + }; + + // Updates config + let updates = UpdatesConfig { + auto_update: raw_config.updates.auto_update, + auto_update_interval: Duration::from_secs( + raw_config.updates.auto_update_interval_hours * 3600, + ), + }; + + // Directories config + let cache_dir_env_var = "TEALDEER_CACHE_DIR"; + let cache_dir = if let Ok(env_var) = env::var(cache_dir_env_var) { + // For backwards compatibility reasons, the cache directory can be + // overridden using an env variable. This is deprecated and will be + // phased out in the future. + eprintln!("Warning: The ${} env variable is deprecated, use the `cache_dir` option in the config file instead.", cache_dir_env_var); + PathBuf::from(env_var) + } else if let Some(config_value) = raw_config.directories.cache_dir { + // If the user explicitly configured a cache directory, use that. + config_value + } else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) { + // Otherwise, fall back to the default user cache directory. + default_dir + } else { + // If everything fails, give up + bail!("Could not determine user cache directory"); + }; + let directories = DirectoriesConfig { + cache_dir, + custom_pages_dir: raw_config.directories.custom_pages_dir, + }; + + Ok(Self { + style, + display, + updates, + directories, + }) + } + pub fn load(enable_styles: bool) -> Result { debug!("Loading config"); @@ -301,7 +337,7 @@ impl Config { }; // Convert to config - let mut config = Self::from(raw_config); + let mut config = Self::from_raw(raw_config).context("Could not process raw config")?; // Potentially override styles if !enable_styles { diff --git a/src/main.rs b/src/main.rs index 6752358..83cb673 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,11 +59,13 @@ const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; /// The cache should be updated if it was explicitly requested, /// or if an automatic update is due and allowed. -fn should_update_cache(args: &Args, config: &Config) -> bool { +fn should_update_cache(cache: &Cache, args: &Args, config: &Config) -> bool { args.update || (!args.no_auto_update && config.updates.auto_update - && Cache::last_update().map_or(true, |ago| ago >= config.updates.auto_update_interval)) + && cache + .last_update() + .map_or(true, |ago| ago >= config.updates.auto_update_interval)) } #[derive(PartialEq)] @@ -73,8 +75,8 @@ enum CheckCacheResult { } /// Check the cache for freshness. If it's stale or missing, show a warning. -fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult { - match Cache::freshness() { +fn check_cache(cache: &Cache, args: &Args, enable_styles: bool) -> CheckCacheResult { + match cache.freshness() { CacheFreshness::Fresh => CheckCacheResult::CacheFound, CacheFreshness::Stale(_) if args.quiet => CheckCacheResult::CacheFound, CacheFreshness::Stale(age) => { @@ -109,8 +111,8 @@ fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult { } /// Clear the cache -fn clear_cache(quietly: bool, enable_styles: bool) { - Cache::clear().unwrap_or_else(|e| { +fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { + cache.clear().unwrap_or_else(|e| { print_error(enable_styles, &e.context("Could not clear cache")); process::exit(1); }); @@ -157,28 +159,15 @@ fn show_paths(config: &Config) { ); let config_path = get_config_path().map_or_else( |e| format!("[Error: {}]", e), - |(path, _)| path.to_str().unwrap_or("[Invalid]").to_string(), - ); - let cache_dir = Cache::get_cache_dir().map_or_else( - |e| format!("[Error: {}]", e), - |(mut path, source)| { - path.push(""); // Trailing path separator - match path.to_str() { - Some(path) => format!("{} ({})", path, source), - None => "[Invalid]".to_string(), - } - }, - ); - let pages_dir = Cache::get_cache_dir().map_or_else( - |e| format!("[Error: {}]", e), - |(mut path, _)| { - path.push(TLDR_PAGES_DIR); - path.push(""); // Trailing path separator - path.into_os_string() - .into_string() - .unwrap_or_else(|_| "[Invalid]".to_string()) - }, + |(path, _)| path.display().to_string(), ); + let cache_dir = config.directories.cache_dir.display(); + let pages_dir = { + let mut path = config.directories.cache_dir.clone(); + path.push(TLDR_PAGES_DIR); + path.push(""); // Trailing path separator + path.display().to_string() + }; let custom_pages_dir = config.directories.custom_pages_dir.as_deref().map_or_else( || "[None]".to_string(), |path| { @@ -339,15 +328,19 @@ fn main() { } // Initialize cache - let cache = Cache::new(ARCHIVE_URL, platform); + let cache = + Cache::new(ARCHIVE_URL, platform, &config.directories.cache_dir).unwrap_or_else(|e| { + print_error(enable_styles, &e.context("Could not initialize cache")); + process::exit(1); + }); // Clear cache, pass through if args.clear_cache { - clear_cache(args.quiet, enable_styles); + clear_cache(&cache, args.quiet, enable_styles); } // Cache update, pass through - let cache_updated = if should_update_cache(&args, &config) { + let cache_updated = if should_update_cache(&cache, &args, &config) { update_cache(&cache, args.quiet, enable_styles); true } else { @@ -357,23 +350,19 @@ fn main() { // Check cache presence and freshness if !cache_updated && (args.list || !args.command.is_empty()) - && check_cache(&args, enable_styles) == CheckCacheResult::CacheMissing + && check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing { process::exit(1); } // List cached commands and exit if args.list { - // Get list of pages - let pages = cache - .list_pages(config.directories.custom_pages_dir.as_deref()) - .unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not get list of pages")); - process::exit(1); - }); - - // Print pages - println!("{}", pages.join("\n")); + println!( + "{}", + cache + .list_pages(config.directories.custom_pages_dir.as_deref()) + .join("\n") + ); process::exit(0); } diff --git a/tests/lib.rs b/tests/lib.rs index 6e66764..71efe09 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -263,9 +263,12 @@ fn test_cache_location_not_a_directory() { .assert() .failure() .stderr(contains(format!( - "Path specified by ${} is not a directory", - CACHE_DIR_ENV_VAR - ))); + "Cache directory path `{}` is not a directory", + internal_file.display(), + ))) + .stderr(contains( + "Warning: The $TEALDEER_CACHE_DIR env variable is deprecated", + )); } #[test] From afbdfa674686e2e64bfa45a5555bbd013d4b5650 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 16 Jun 2022 20:57:03 +0200 Subject: [PATCH 061/196] Bring back path source for cache directory --- src/config.rs | 23 +++++++++++++++++++---- src/main.rs | 12 ++++++++---- src/types.rs | 10 ++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/config.rs b/src/config.rs index f5e996a..28c15ef 100644 --- a/src/config.rs +++ b/src/config.rs @@ -240,9 +240,15 @@ pub struct UpdatesConfig { pub auto_update_interval: Duration, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PathWithSource { + pub path: PathBuf, + pub source: PathSource, +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct DirectoriesConfig { - pub cache_dir: PathBuf, + pub cache_dir: PathWithSource, pub custom_pages_dir: Option, } @@ -290,13 +296,22 @@ impl Config { // overridden using an env variable. This is deprecated and will be // phased out in the future. eprintln!("Warning: The ${} env variable is deprecated, use the `cache_dir` option in the config file instead.", cache_dir_env_var); - PathBuf::from(env_var) + PathWithSource { + path: PathBuf::from(env_var), + source: PathSource::EnvVar, + } } else if let Some(config_value) = raw_config.directories.cache_dir { // If the user explicitly configured a cache directory, use that. - config_value + PathWithSource { + path: config_value, + source: PathSource::ConfigFile, + } } else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) { // Otherwise, fall back to the default user cache directory. - default_dir + PathWithSource { + path: default_dir, + source: PathSource::OsConvention, + } } else { // If everything fails, give up bail!("Could not determine user cache directory"); diff --git a/src/main.rs b/src/main.rs index 83cb673..c1151bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -161,9 +161,13 @@ fn show_paths(config: &Config) { |e| format!("[Error: {}]", e), |(path, _)| path.display().to_string(), ); - let cache_dir = config.directories.cache_dir.display(); + let cache_dir = format!( + "{} ({})", + config.directories.cache_dir.path.display(), + config.directories.cache_dir.source + ); let pages_dir = { - let mut path = config.directories.cache_dir.clone(); + let mut path = config.directories.cache_dir.path.clone(); path.push(TLDR_PAGES_DIR); path.push(""); // Trailing path separator path.display().to_string() @@ -328,8 +332,8 @@ fn main() { } // Initialize cache - let cache = - Cache::new(ARCHIVE_URL, platform, &config.directories.cache_dir).unwrap_or_else(|e| { + let cache = Cache::new(ARCHIVE_URL, platform, &config.directories.cache_dir.path) + .unwrap_or_else(|e| { print_error(enable_styles, &e.context("Could not initialize cache")); process::exit(1); }); diff --git a/src/types.rs b/src/types.rs index 683a81a..f3318a9 100644 --- a/src/types.rs +++ b/src/types.rs @@ -185,16 +185,14 @@ impl LineType { } /// The reason why a certain path (e.g. config path or cache dir) was chosen. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum PathSource { /// OS convention (e.g. XDG on Linux) OsConvention, /// Env variable (TEALDEER_*) EnvVar, - - #[allow(dead_code)] // Waiting for Pull Request #141 - /// Config file variable - ConfigVar, + /// Config file + ConfigFile, } impl fmt::Display for PathSource { @@ -205,7 +203,7 @@ impl fmt::Display for PathSource { match self { Self::OsConvention => "OS convention", Self::EnvVar => "env variable", - Self::ConfigVar => "config file variable", + Self::ConfigFile => "config file", } ) } From 7338933de543cc1c05db91aa396c8460513033a6 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 16 Jun 2022 21:20:05 +0200 Subject: [PATCH 062/196] Add integration test for cache_dir --- tests/lib.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/tests/lib.rs b/tests/lib.rs index 71efe09..230b2f2 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -10,9 +10,9 @@ use std::{ use assert_cmd::prelude::*; use predicates::{ boolean::PredicateBooleanExt, - prelude::predicate::str::{contains, diff, is_empty}, + prelude::predicate::str::{contains, diff, is_empty, is_match}, }; -use tempfile::{Builder, TempDir}; +use tempfile::{Builder as TempfileBuilder, 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"; @@ -31,13 +31,22 @@ struct TestEnv { impl TestEnv { fn new() -> Self { TestEnv { - cache_dir: Builder::new().prefix(".tldr.test.cache").tempdir().unwrap(), - config_dir: Builder::new().prefix(".tldr.test.conf").tempdir().unwrap(), - custom_pages_dir: Builder::new() + cache_dir: TempfileBuilder::new() + .prefix(".tldr.test.cache") + .tempdir() + .unwrap(), + config_dir: TempfileBuilder::new() + .prefix(".tldr.test.conf") + .tempdir() + .unwrap(), + custom_pages_dir: TempfileBuilder::new() .prefix(".tldr.test.custom-pages") .tempdir() .unwrap(), - input_dir: Builder::new().prefix(".tldr.test.input").tempdir().unwrap(), + input_dir: TempfileBuilder::new() + .prefix(".tldr.test.input") + .tempdir() + .unwrap(), default_features: true, features: vec![], } @@ -271,6 +280,47 @@ fn test_cache_location_not_a_directory() { )); } +#[test] +fn test_cache_location_source() { + let testenv = TestEnv::new(); + let default_cache_dir = testenv.cache_dir.path(); + let tmp_cache_dir = TempfileBuilder::new() + .prefix(".tldr.test.cache_dir") + .tempdir() + .unwrap(); + + // Source: Default (OS convention) + let mut command = testenv.command(); + command.env_remove(CACHE_DIR_ENV_VAR); + command + .arg("--show-paths") + .assert() + .success() + .stdout(is_match("\nCache dir: [^(]* \\(OS convention\\)\n").unwrap()); + + // Source: Config variable + let mut command = testenv.command(); + command.env_remove(CACHE_DIR_ENV_VAR); + testenv.write_config(format!( + "[directories]\ncache_dir = '{}'", + tmp_cache_dir.path().to_str().unwrap(), + )); + command + .arg("--show-paths") + .assert() + .success() + .stdout(is_match("\nCache dir: [^(]* \\(config file\\)\n").unwrap()); + + // Source: Env var + let mut command = testenv.command(); + command.env(CACHE_DIR_ENV_VAR, default_cache_dir.to_str().unwrap()); + command + .arg("--show-paths") + .assert() + .success() + .stdout(is_match("\nCache dir: [^(]* \\(env variable\\)\n").unwrap()); +} + #[test] fn test_setup_seed_config() { let testenv = TestEnv::new(); From fb89303e85a76e8f42e2e639d62df2cbcbd2c2b3 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 16 Jun 2022 21:51:16 +0200 Subject: [PATCH 063/196] Move custom_pages_dir business logic from RawConfig to Config This also introduces the path source information for that directory, which was previously unknown. --- src/config.rs | 54 +++++++++++++++++++++++++++++++++------------------ src/main.rs | 37 ++++++++++++++++------------------- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/config.rs b/src/config.rs index 28c15ef..4907de0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ use std::{ - env, fs, + env, fmt, fs, io::{Read, Write}, - path::PathBuf, + path::{Path, PathBuf}, time::Duration, }; @@ -162,7 +162,7 @@ impl Default for RawUpdatesConfig { } } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawDirectoriesConfig { #[serde(default)] pub cache_dir: Option, @@ -170,20 +170,6 @@ struct RawDirectoriesConfig { pub custom_pages_dir: Option, } -impl Default for RawDirectoriesConfig { - fn default() -> Self { - Self { - cache_dir: None, - custom_pages_dir: get_app_root(AppDataType::UserData, &crate::APP_INFO) - .map(|path| { - // Note: The `join("")` call ensures that there's a trailing slash - path.join("pages").join("") - }) - .ok(), - } - } -} - #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(default)] struct RawConfig { @@ -246,10 +232,22 @@ pub struct PathWithSource { pub source: PathSource, } +impl PathWithSource { + pub fn path(&self) -> &Path { + &self.path + } +} + +impl fmt::Display for PathWithSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} ({})", self.path.display(), self.source) + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct DirectoriesConfig { pub cache_dir: PathWithSource, - pub custom_pages_dir: Option, + pub custom_pages_dir: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -316,9 +314,27 @@ impl Config { // If everything fails, give up bail!("Could not determine user cache directory"); }; + let custom_pages_dir = raw_config + .directories + .custom_pages_dir + .map(|path| PathWithSource { + path, + source: PathSource::OsConvention, + }) + .or_else(|| { + get_app_root(AppDataType::UserData, &crate::APP_INFO) + .map(|path| { + // Note: The `join("")` call ensures that there's a trailing slash + PathWithSource { + path: path.join("pages").join(""), + source: PathSource::ConfigFile, + } + }) + .ok() + }); let directories = DirectoriesConfig { cache_dir, - custom_pages_dir: raw_config.directories.custom_pages_dir, + custom_pages_dir, }; Ok(Self { diff --git a/src/main.rs b/src/main.rs index c1151bf..ab30391 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, cli::Args, - config::{get_config_dir, get_config_path, make_default_config, Config}, + config::{get_config_dir, get_config_path, make_default_config, Config, PathWithSource}, extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, @@ -161,24 +161,17 @@ fn show_paths(config: &Config) { |e| format!("[Error: {}]", e), |(path, _)| path.display().to_string(), ); - let cache_dir = format!( - "{} ({})", - config.directories.cache_dir.path.display(), - config.directories.cache_dir.source - ); + let cache_dir = config.directories.cache_dir.to_string(); let pages_dir = { let mut path = config.directories.cache_dir.path.clone(); path.push(TLDR_PAGES_DIR); path.push(""); // Trailing path separator path.display().to_string() }; - let custom_pages_dir = config.directories.custom_pages_dir.as_deref().map_or_else( - || "[None]".to_string(), - |path| { - path.to_str() - .map_or_else(|| "[Invalid]".to_string(), ToString::to_string) - }, - ); + let custom_pages_dir = match config.directories.custom_pages_dir { + Some(ref path_with_source) => path_with_source.to_string(), + None => "[None]".to_string(), + }; println!("Config dir: {}", config_dir); println!("Config path: {}", config_path); println!("Cache dir: {}", cache_dir); @@ -361,12 +354,12 @@ fn main() { // List cached commands and exit if args.list { - println!( - "{}", - cache - .list_pages(config.directories.custom_pages_dir.as_deref()) - .join("\n") - ); + let custom_pages_dir = config + .directories + .custom_pages_dir + .as_ref() + .map(PathWithSource::path); + println!("{}", cache.list_pages(custom_pages_dir).join("\n")); process::exit(0); } @@ -386,7 +379,11 @@ fn main() { if let Some(lookup_result) = cache.find_page( &command, &languages, - config.directories.custom_pages_dir.as_deref(), + config + .directories + .custom_pages_dir + .as_ref() + .map(PathWithSource::path), ) { if let Err(ref e) = print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) From 3e7dfb3c7165a257c9dbf1010e9cf4780baa0882 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Sep 2022 21:55:06 +0200 Subject: [PATCH 064/196] Cache: Make URL a parameter, not a field --- src/cache.rs | 19 ++++++++----------- src/main.rs | 11 +++++------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 35807ea..659fd9f 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -20,7 +20,6 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; #[derive(Debug)] pub struct Cache { - url: String, platform: PlatformType, cache_dir: PathBuf, } @@ -87,9 +86,8 @@ pub enum CacheFreshness { } impl Cache { - pub fn new(url: S, platform: PlatformType, cache_dir: P) -> Result + pub fn new

(platform: PlatformType, cache_dir: P) -> Result where - S: Into, P: Into, { // Check whether `cache_dir` exists and is a directory @@ -119,14 +117,13 @@ impl Cache { } Ok(Self { - url: url.into(), platform, cache_dir, }) } - /// Download the archive - fn download(&self) -> Result> { + /// Download the archive from the specified URL. + fn download(archive_url: &str) -> Result> { let mut builder = Client::builder(); if let Ok(ref host) = env::var("HTTP_PROXY") { if let Ok(proxy) = Proxy::http(host) { @@ -142,20 +139,20 @@ impl Cache { .build() .context("Could not instantiate HTTP client")?; let mut resp = client - .get(&self.url) + .get(archive_url) .send()? .error_for_status() - .with_context(|| format!("Could not download tldr pages from {}", &self.url))?; + .with_context(|| format!("Could not download tldr pages from {}", archive_url))?; let mut buf: Vec = vec![]; let bytes_downloaded = resp.copy_to(&mut buf)?; debug!("{} bytes downloaded", bytes_downloaded); Ok(buf) } - /// Update the pages cache. - pub fn update(&self) -> Result<()> { + /// Update the pages cache from the specified URL. + pub fn update(&self, archive_url: &str) -> Result<()> { // First, download the compressed data - let bytes: Vec = self.download()?; + let bytes: Vec = Self::download(archive_url)?; // Decompress the response body into an `Archive` let mut archive = ZipArchive::new(Cursor::new(bytes)) diff --git a/src/main.rs b/src/main.rs index ab30391..9c8fe58 100644 --- a/src/main.rs +++ b/src/main.rs @@ -123,7 +123,7 @@ fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { /// Update the cache fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { - cache.update().unwrap_or_else(|e| { + cache.update(ARCHIVE_URL).unwrap_or_else(|e| { print_error(enable_styles, &e.context("Could not update cache")); process::exit(1); }); @@ -325,11 +325,10 @@ fn main() { } // Initialize cache - let cache = Cache::new(ARCHIVE_URL, platform, &config.directories.cache_dir.path) - .unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not initialize cache")); - process::exit(1); - }); + let cache = Cache::new(platform, &config.directories.cache_dir.path).unwrap_or_else(|e| { + print_error(enable_styles, &e.context("Could not initialize cache")); + process::exit(1); + }); // Clear cache, pass through if args.clear_cache { From d702a1fab678d34a6a2201270aed5fb15f66cdeb Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Sep 2022 22:07:16 +0200 Subject: [PATCH 065/196] Cache: Add pages_dir helper method Additionally, rename `cache_dir` to `pages_dir` where terminology was wrong. --- src/cache.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 659fd9f..b7fab2a 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -122,6 +122,10 @@ impl Cache { }) } + fn pages_dir(&self) -> PathBuf { + self.cache_dir.join(TLDR_PAGES_DIR) + } + /// Download the archive from the specified URL. fn download(archive_url: &str) -> Result> { let mut builder = Client::builder(); @@ -158,9 +162,6 @@ impl Cache { let mut archive = ZipArchive::new(Cursor::new(bytes)) .context("Could not decompress downloaded ZIP archive")?; - // Determine paths - let pages_dir = self.cache_dir.join(TLDR_PAGES_DIR); - // Clear cache directory // Note: This is not the best solution. Ideally we would download the // archive to a temporary directory and then swap the two directories. @@ -170,9 +171,9 @@ impl Cache { self.clear() .context("Could not clear the cache directory")?; - // Extract archive + // Extract archive into pages dir archive - .extract(&pages_dir) + .extract(&self.pages_dir()) .context("Could not unpack compressed data")?; Ok(()) @@ -180,7 +181,7 @@ impl Cache { /// Return the duration since the cache directory was last modified. pub fn last_update(&self) -> Option { - if let Ok(metadata) = fs::metadata(self.cache_dir.join(TLDR_PAGES_DIR)) { + if let Ok(metadata) = fs::metadata(self.pages_dir()) { if let Ok(mtime) = metadata.modified() { let now = SystemTime::now(); return now.duration_since(mtime).ok(); @@ -212,13 +213,13 @@ impl Cache { /// Check for pages for a given platform in one of the given languages. fn find_page_for_platform( page_name: &str, - cache_dir: &Path, + pages_dir: &Path, platform: &str, language_dirs: &[String], ) -> Option { language_dirs .iter() - .map(|lang_dir| cache_dir.join(lang_dir).join(platform).join(page_name)) + .map(|lang_dir| pages_dir.join(lang_dir).join(platform).join(page_name)) .find(|path| path.exists() && path.is_file()) } @@ -240,8 +241,8 @@ impl Cache { let patch_filename = format!("{}.patch", name); let custom_filename = format!("{}.page", name); - // Determine directories - let cache_dir = self.cache_dir.join(TLDR_PAGES_DIR); + // Determine directory paths + let pages_dir = self.pages_dir(); let lang_dirs: Vec = languages .iter() .map(|lang| { @@ -266,20 +267,20 @@ impl Cache { // Try to find a platform specific path next, append custom patch to it. let platform_dir = self.get_platform_dir(); if let Some(page) = - Self::find_page_for_platform(&page_filename, &cache_dir, platform_dir, &lang_dirs) + Self::find_page_for_platform(&page_filename, &pages_dir, platform_dir, &lang_dirs) { return Some(PageLookupResult::with_page(page).with_optional_patch(patch_path)); } // Did not find platform specific results, fall back to "common" - Self::find_page_for_platform(&page_filename, &cache_dir, "common", &lang_dirs) + Self::find_page_for_platform(&page_filename, &pages_dir, "common", &lang_dirs) .map(|page| PageLookupResult::with_page(page).with_optional_patch(patch_path)) } /// Return the available pages. pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Vec { // Determine platforms directory and platform - let platforms_dir = self.cache_dir.join(TLDR_PAGES_DIR).join("pages"); + let platforms_dir = self.pages_dir().join("pages"); let platform_dir = self.get_platform_dir(); // Closure that allows the WalkDir instance to traverse platform From 3f528ba5cb2724502a847f9b9dc798dc7714df19 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Sep 2022 22:13:59 +0200 Subject: [PATCH 066/196] Impl From for more config types - StyleConfig - DisplayConfig - UpdatesConfig --- src/config.rs | 61 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/config.rs b/src/config.rs index 4907de0..0889271 100644 --- a/src/config.rs +++ b/src/config.rs @@ -129,6 +129,18 @@ struct RawStyleConfig { pub example_variable: RawStyle, } +impl From for StyleConfig { + fn from(raw_style_config: RawStyleConfig) -> Self { + Self { + command_name: raw_style_config.command_name.into(), + description: raw_style_config.description.into(), + example_text: raw_style_config.example_text.into(), + example_code: raw_style_config.example_code.into(), + example_variable: raw_style_config.example_variable.into(), + } + } +} + #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawDisplayConfig { #[serde(default)] @@ -137,6 +149,15 @@ struct RawDisplayConfig { pub use_pager: bool, } +impl From for DisplayConfig { + fn from(raw_display_config: RawDisplayConfig) -> Self { + Self { + compact: raw_display_config.compact, + use_pager: raw_display_config.use_pager, + } + } +} + /// Serde doesn't support default values yet (tracking issue: /// ), so we need to wrap /// `DEFAULT_UPDATE_INTERVAL_HOURS` in a function to be able to use @@ -162,6 +183,17 @@ impl Default for RawUpdatesConfig { } } +impl From for UpdatesConfig { + fn from(raw_updates_config: RawUpdatesConfig) -> Self { + Self { + auto_update: raw_updates_config.auto_update, + auto_update_interval: Duration::from_secs( + raw_updates_config.auto_update_interval_hours * 3600, + ), + } + } +} + #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawDirectoriesConfig { #[serde(default)] @@ -264,30 +296,13 @@ impl Config { /// For this, some values need to be converted to other types and some /// defaults need to be set (sometimes based on env variables). fn from_raw(raw_config: RawConfig) -> Result { - // Style config - let style = StyleConfig { - command_name: raw_config.style.command_name.into(), - description: raw_config.style.description.into(), - example_text: raw_config.style.example_text.into(), - example_code: raw_config.style.example_code.into(), - example_variable: raw_config.style.example_variable.into(), - }; + let style = raw_config.style.into(); + let display = raw_config.display.into(); + let updates = raw_config.updates.into(); - // Display config - let display = DisplayConfig { - compact: raw_config.display.compact, - use_pager: raw_config.display.use_pager, - }; - - // Updates config - let updates = UpdatesConfig { - auto_update: raw_config.updates.auto_update, - auto_update_interval: Duration::from_secs( - raw_config.updates.auto_update_interval_hours * 3600, - ), - }; - - // Directories config + // Determine directories config. For this, we need to take some + // additional factory into account, like env variables, or the + // user config. let cache_dir_env_var = "TEALDEER_CACHE_DIR"; let cache_dir = if let Ok(env_var) = env::var(cache_dir_env_var) { // For backwards compatibility reasons, the cache directory can be From c44faf2b0919e2eab408a24ef9d06d9382572435 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 28 Sep 2022 23:31:40 +0200 Subject: [PATCH 067/196] Lazy creation of cache directory --- src/cache.rs | 55 +++++++++++++++++++++++++++++++--------------------- src/main.rs | 19 +++++++++++------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index b7fab2a..57b1a30 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -86,40 +86,49 @@ pub enum CacheFreshness { } impl Cache { - pub fn new

(platform: PlatformType, cache_dir: P) -> Result + pub fn new

(platform: PlatformType, cache_dir: P) -> Self where P: Into, { + Self { + platform, + cache_dir: cache_dir.into(), + } + } + + pub fn cache_dir(&self) -> &Path { + &self.cache_dir + } + + /// Make sure that the cache directory exists and is a directory. + /// If necessary, create the directory. + fn ensure_cache_dir_exists(&self) -> Result<()> { // Check whether `cache_dir` exists and is a directory - let cache_dir = cache_dir.into(); - let (cache_dir_exists, cache_dir_is_dir) = cache_dir + let (cache_dir_exists, cache_dir_is_dir) = self + .cache_dir .metadata() .map_or((false, false), |md| (true, md.is_dir())); ensure!( !cache_dir_exists || cache_dir_is_dir, "Cache directory path `{}` is not a directory", - cache_dir.display(), + self.cache_dir.display(), ); - // If necessary, create cache directory if !cache_dir_exists { - // Try to create the complete directory path - fs::create_dir_all(&cache_dir).with_context(|| { + // If missing, try to create the complete directory path + fs::create_dir_all(&self.cache_dir).with_context(|| { format!( "Cache directory path `{}` cannot be created", - cache_dir.display(), + self.cache_dir.display(), ) })?; eprintln!( "Successfully created cache directory path `{}`.", - cache_dir.display(), + self.cache_dir.display(), ); } - Ok(Self { - platform, - cache_dir, - }) + Ok(()) } fn pages_dir(&self) -> PathBuf { @@ -155,6 +164,8 @@ impl Cache { /// Update the pages cache from the specified URL. pub fn update(&self, archive_url: &str) -> Result<()> { + self.ensure_cache_dir_exists()?; + // First, download the compressed data let bytes: Vec = Self::download(archive_url)?; @@ -345,14 +356,14 @@ impl Cache { pages } - /// Delete the cache directory. - pub fn clear(&self) -> Result<()> { - // Check preconditions - ensure!( - self.cache_dir.exists(), - "Cache path ({}) does not exist.", - self.cache_dir.display(), - ); + /// Delete the cache directory + /// + /// Returns true if the cache was deleted and false if the cache dir did + /// not exist. + pub fn clear(&self) -> Result { + if !self.cache_dir.exists() { + return Ok(false); + } ensure!( self.cache_dir.is_dir(), "Cache path ({}) is not a directory.", @@ -374,7 +385,7 @@ impl Cache { } } - Ok(()) + Ok(true) } } diff --git a/src/main.rs b/src/main.rs index 9c8fe58..ffacae2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -112,12 +112,20 @@ fn check_cache(cache: &Cache, args: &Args, enable_styles: bool) -> CheckCacheRes /// Clear the cache fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { - cache.clear().unwrap_or_else(|e| { + let cache_dir_found = cache.clear().unwrap_or_else(|e| { print_error(enable_styles, &e.context("Could not clear cache")); process::exit(1); }); if !quietly { - eprintln!("Successfully deleted cache."); + let cache_dir = cache.cache_dir().display(); + if cache_dir_found { + eprintln!("Successfully cleared cache at `{}`.", cache_dir); + } else { + eprintln!( + "Cache directory not found at `{}`, nothing to do.", + cache_dir + ); + } } } @@ -324,11 +332,8 @@ fn main() { }; } - // Initialize cache - let cache = Cache::new(platform, &config.directories.cache_dir.path).unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not initialize cache")); - process::exit(1); - }); + // Instantiate cache. This will not yet create the cache directory! + let cache = Cache::new(platform, &config.directories.cache_dir.path); // Clear cache, pass through if args.clear_cache { From 0c93a4cfe9c51422170c18c5ea4b22f2d069cccd Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 1 Oct 2022 23:52:03 +0200 Subject: [PATCH 068/196] Remove deprecated --config-path command --- docs/src/usage.txt | 1 - src/cli.rs | 4 ---- src/main.rs | 22 ---------------------- 3 files changed, 27 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index fdc0c9f..f6b159d 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -21,7 +21,6 @@ OPTIONS: -r, --raw Display the raw markdown instead of rendering it -q, --quiet Suppress informational messages --show-paths Show file and directory paths used by tealdeer - --config-path Show config file path --seed-config Create a basic config --color Control whether to use color [possible values: always, auto, never] -v, --version Print the version diff --git a/src/cli.rs b/src/cli.rs index a35df31..2108a1d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -93,10 +93,6 @@ pub(crate) struct Args { #[clap(long = "show-paths")] pub show_paths: bool, - /// Show config file path - #[clap(long = "config-path")] - pub config_path: bool, - /// Create a basic config #[clap(long = "seed-config")] pub seed_config: bool, diff --git a/src/main.rs b/src/main.rs index ffacae2..156eba6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -140,19 +140,6 @@ fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { } } -/// Show the config path (DEPRECATED) -fn show_config_path(enable_styles: bool) { - match get_config_path() { - Ok((config_file_path, _)) => { - println!("Config path is: {}", config_file_path.to_str().unwrap()); - } - Err(e) => { - print_error(enable_styles, &e.context("Could not look up config path")); - process::exit(1); - } - } -} - /// Show file paths fn show_paths(config: &Config) { let config_dir = get_config_dir().map_or_else( @@ -290,15 +277,6 @@ fn main() { } args.platform = args.platform.or(args.os); - // Show config file and path, pass through - if args.config_path { - print_warning( - enable_styles, - "The --config-path flag is deprecated, use --show-paths instead", - ); - show_config_path(enable_styles); - } - // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { Ok(config) => config, From efe1b5769638e96fcb02b9cbef70ccdd20a04d30 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 1 Oct 2022 23:53:28 +0200 Subject: [PATCH 069/196] Remove deprecated -o/--os command --- src/cli.rs | 9 --------- src/main.rs | 7 ------- 2 files changed, 16 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 2108a1d..5c8e238 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -43,15 +43,6 @@ pub(crate) struct Args { )] pub platform: Option, - /// Deprecated alias of `platform` - #[clap( - short = 'o', - long = "os", - possible_values = ["linux", "macos", "windows", "sunos", "osx"], - hide = true - )] - pub os: Option, - /// Override the language #[clap(short = 'L', long = "language")] pub language: Option, diff --git a/src/main.rs b/src/main.rs index 156eba6..f4a4687 100644 --- a/src/main.rs +++ b/src/main.rs @@ -269,13 +269,6 @@ fn main() { "The -m / --markdown flag is deprecated, use -r / --raw instead", ); } - if args.os.is_some() { - print_warning( - enable_styles, - "The -o / --os flag is deprecated, use -p / --platform instead", - ); - } - args.platform = args.platform.or(args.os); // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { From 2ebf86b265f1cc6f24e649f938056ff4afdfc661 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 1 Oct 2022 23:54:37 +0200 Subject: [PATCH 070/196] Remove deprecated -m/--markdown command --- src/cli.rs | 9 --------- src/main.rs | 11 +---------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 5c8e238..8646cac 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -67,15 +67,6 @@ pub(crate) struct Args { #[clap(short = 'r', long = "--raw", requires = "command_or_file")] pub raw: bool, - /// Deprecated alias of `raw` - #[clap( - long = "markdown", - short = 'm', - requires = "command_or_file", - hide = true - )] - pub markdown: bool, - /// Suppress informational messages #[clap(short = 'q', long = "quiet")] pub quiet: bool, diff --git a/src/main.rs b/src/main.rs index f4a4687..8f601e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -240,7 +240,7 @@ fn main() { init_log(); // Parse arguments - let mut args = Args::parse(); + let args = Args::parse(); // Determine the usage of styles #[cfg(target_os = "windows")] @@ -261,15 +261,6 @@ fn main() { ColorOptions::Never => false, }; - // Handle renamed arguments - if args.markdown { - args.raw = true; - print_warning( - enable_styles, - "The -m / --markdown flag is deprecated, use -r / --raw instead", - ); - } - // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { Ok(config) => config, From 7ded00eda02611a021d10ef252200b3346bfa1e9 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 00:23:26 +0200 Subject: [PATCH 071/196] Run cargo update (#291) --- Cargo.lock | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a812506..7ee4185 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,12 +201,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -620,9 +619,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.133" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "log" @@ -799,9 +798,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] @@ -1089,9 +1088,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" dependencies = [ "proc-macro2", "quote", @@ -1160,18 +1159,18 @@ checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thiserror" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -1195,9 +1194,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.1" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ "autocfg", "bytes", @@ -1205,7 +1204,6 @@ dependencies = [ "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "socket2", "winapi", @@ -1445,9 +1443,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.4" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" dependencies = [ "webpki", ] From 357f0e7e717f83dc4564c918f08b6a400a7fd318 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 00:28:34 +0200 Subject: [PATCH 072/196] Release v1.6.0 --- CHANGELOG.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/usage.txt | 2 +- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5546cc6..e7d61ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,55 @@ Possible log types: - `[chore]` for maintenance work. +### [v1.6.0][v1.6.0] (2022-10-02) + +It's been 9 months since the last release already! This is not a huge update +feature-wise, but it still contains a few nice new improvements and a few +bugfixes, contributed by 11 different people. The most important new feature is +probably the option to override the cache directory through the config file. +The `TEALDEER_CACHE_DIR` env variable is now deprecated. + +A note to packagers: Shell completions have been moved to the `completion/` +subdirectory! Packaging scripst might need to be updated. + +Changes: + +- [added] Allow overriding cache directory through config ([#276]) +- [added] Add `--no-auto-update` CLI flag ([#257]) +- [added] Show note about auto-updates when cache is missing ([#254]) +- [added] Add support for android platform ([#274]) +- [added] Add custom pages to list output ([#285]) +- [fixed] Cache: Return error if HTTP client cannot be created ([#247]) +- [fixed] Handle cache download errors ([#253]) +- [fixed] Do not page output of `tldr --update` ([#231]) +- [fixed] Create macOS release builds with bundled root certificates ([#272]) +- [fixed] Clean up and fix shell completions ([#262]) +- [deprecated] The `TEALDEER_CACHE_DIR` env variable is now deprecated ([#276]) +- [removed] The `--config-path` command was removed, use `--show-paths` instead ([#290]) +- [removed] The `-o/--os` command was removed, use `-p/--platform` instead ([#290]) +- [removed] The `-m/--markdown` command was removed, use `-r/--raw` instead ([#290]) +- [chore] Move shell completion scripts to their own directory ([#259]) +- [chore] Update dependencies ([#271], [#287], [#291]) +- [chore] Use anyhow for error handling ([#249]) +- [chore] Switch to Rust 2021 edition ([#284]) + +Contributors to this version: + +- [@bagohart][@bagohart] +- [@cyqsimon][@cyqsimon] +- [Danilo Bargen][@dbrgn] +- [Danny Mösch][@SimplyDanny] +- [Evan Lloyd New-Schmidt][@newsch] +- [Hans Gaiser][@hgaiser] +- [Kian-Meng Ang][@kianmeng] +- [Marcin Puc][@tranzystorek-io] +- [Niklas Mohrin][@niklasmohrin] +- [Olav de Haas][@Olavhaasie] +- [Simon Perdrisat][@gagarine] + +Thanks! + + ### [v1.5.0][v1.5.0] (2021-12-31) This is quite a big release with many new features. In the 15 months since the @@ -236,17 +285,21 @@ Thanks! [@aldanor]: https://github.com/aldanor [@Atul9]: https://github.com/Atul9 [@BachoSeven]: https://github.com/BachoSeven +[@bagohart]: https://github.com/bagohart [@Bassets]: https://github.com/Bassets [@black7375]: https://github.com/black7375 [@bl-ue]: https://github.com/bl-ue [@Calinou]: https://github.com/Calinou [@cam8001]: https://github.com/cam8001 +[@cyqsimon]: https://github.com/cyqsimon [@cho-m]: https://github.com/cho-m [@das-g]: https://github.com/das-g [@dbrgn]: https://github.com/dbrgn [@Delapouite]: https://github.com/Delapouite [@dmaahs2017]: https://github.com/dmaahs2017 [@equal-l2]: https://github.com/equal-l2 +[@gagarine]: https://github.com/gagarine +[@hgaiser]: https://github.com/hgaiser [@ilai-deutel]: https://github.com/ilai-deutel [@invakid404]: https://github.com/invakid404 [@james2doyle]: https://github.com/james2doyle @@ -254,6 +307,7 @@ Thanks! [@jdvr]: https://github.com/jdvr [@jedahan]: https://github.com/jedahan [@jesdazrez]: https://github.com/jesdazrez +[@kianmeng]: https://github.com/kianmeng [@kornelski]: https://github.com/kornelski [@korrat]: https://github.com/korrat [@laxect]: https://github.com/laxect @@ -263,7 +317,9 @@ Thanks! [@mucinoab]: https://github.com/mucinoab [@mystal]: https://github.com/mystal [@natpen]: https://github.com/natpen +[@newsch]: https://github.com/newsch [@niklasmohrin]: https://github.com/niklasmohrin +[@Olavhaasie]: https://github.com/Olavhaasie [@Plommonsorbet]: https://github.com/Plommonsorbet [@rithvikvibhu]: https://github.com/rithvikvibhu [@SimplyDanny]: https://github.com/SimplyDanny @@ -280,6 +336,7 @@ Thanks! [v1.4.0]: https://github.com/dbrgn/tealdeer/compare/v1.3.0...v1.4.0 [v1.4.1]: https://github.com/dbrgn/tealdeer/compare/v1.4.0...v1.4.1 [v1.5.0]: https://github.com/dbrgn/tealdeer/compare/v1.4.1...v1.5.0 +[v1.6.0]: https://github.com/dbrgn/tealdeer/compare/v1.5.0...v1.6.0 [i34]: https://github.com/dbrgn/tealdeer/issues/34 [i43]: https://github.com/dbrgn/tealdeer/issues/43 @@ -326,4 +383,21 @@ Thanks! [i215]: https://github.com/dbrgn/tealdeer/pull/215 [i217]: https://github.com/dbrgn/tealdeer/pull/217 [i227]: https://github.com/dbrgn/tealdeer/pull/227 +[#231]: https://github.com/dbrgn/tealdeer/pull/231 [i240]: https://github.com/dbrgn/tealdeer/pull/240 +[#247]: https://github.com/dbrgn/tealdeer/pull/247 +[#249]: https://github.com/dbrgn/tealdeer/pull/249 +[#253]: https://github.com/dbrgn/tealdeer/pull/253 +[#254]: https://github.com/dbrgn/tealdeer/pull/254 +[#257]: https://github.com/dbrgn/tealdeer/pull/257 +[#259]: https://github.com/dbrgn/tealdeer/pull/259 +[#262]: https://github.com/dbrgn/tealdeer/pull/262 +[#271]: https://github.com/dbrgn/tealdeer/pull/271 +[#272]: https://github.com/dbrgn/tealdeer/pull/272 +[#274]: https://github.com/dbrgn/tealdeer/pull/274 +[#276]: https://github.com/dbrgn/tealdeer/pull/276 +[#284]: https://github.com/dbrgn/tealdeer/pull/284 +[#285]: https://github.com/dbrgn/tealdeer/pull/285 +[#287]: https://github.com/dbrgn/tealdeer/pull/287 +[#290]: https://github.com/dbrgn/tealdeer/pull/290 +[#291]: https://github.com/dbrgn/tealdeer/pull/291 diff --git a/Cargo.lock b/Cargo.lock index 7ee4185..752737c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1099,7 +1099,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.5.0" +version = "1.6.0" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index d845906..9d4b7b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" -version = "1.5.0" +version = "1.6.0" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png"] rust-version = "1.62" edition = "2021" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index f6b159d..9977a03 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.5.0 +tealdeer 1.6.0 Danilo Bargen , Niklas Mohrin A fast TLDR client From 86c850282e395497f88f2020f3c8c7cc0fd3d843 Mon Sep 17 00:00:00 2001 From: Cyrus Yip <60951091+CyrusYip@users.noreply.github.com> Date: Tue, 11 Oct 2022 20:08:41 +0800 Subject: [PATCH 073/196] Docs: improve grammar (#296) --- docs/src/intro.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/intro.md b/docs/src/intro.md index 71ebce0..09106b0 100644 --- a/docs/src/intro.md +++ b/docs/src/intro.md @@ -1,7 +1,8 @@ # Tealdeer: Introduction -Tealdeer very fast implementation of [tldr](https://github.com/tldr-pages/tldr) -in Rust: Simplified, example based and community-driven man pages. +Tealdeer is a very fast implementation of +[tldr](https://github.com/tldr-pages/tldr) in Rust: Simplified, example based +and community-driven man pages. ![Screenshot](screenshot-default.png) From ab5148f237a8eacddba6ab25e0761b6dfa9c5e1b Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 22 Oct 2022 22:00:29 +0200 Subject: [PATCH 074/196] Fix path source for custom pages dir (#297) --- src/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 0889271..e1bc4ba 100644 --- a/src/config.rs +++ b/src/config.rs @@ -334,7 +334,7 @@ impl Config { .custom_pages_dir .map(|path| PathWithSource { path, - source: PathSource::OsConvention, + source: PathSource::ConfigFile, }) .or_else(|| { get_app_root(AppDataType::UserData, &crate::APP_INFO) @@ -342,7 +342,7 @@ impl Config { // Note: The `join("")` call ensures that there's a trailing slash PathWithSource { path: path.join("pages").join(""), - source: PathSource::ConfigFile, + source: PathSource::OsConvention, } }) .ok() From b10f8a9485b9803282634756008bc7eafb49c57d Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 22 Oct 2022 22:24:57 +0200 Subject: [PATCH 075/196] Run cargo update (#299) --- Cargo.lock | 169 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 752737c..68ed79c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "app_dirs2" @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ae1ddd39efd67689deb1979d80bad3bf7f2b09c6e6117c8d1f2443b5e2f83e" +checksum = "d5c2ca00549910ec251e3bd15f87aeeb206c9456b9a77b43ff6c97c54042a472" dependencies = [ "bstr", "doc-comment", @@ -68,9 +68,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bitflags" @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "byteorder" @@ -312,14 +312,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -358,42 +358,42 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-core", "futures-io", @@ -406,9 +406,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -578,9 +578,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jni" @@ -619,9 +619,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.134" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "log" @@ -662,7 +662,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -798,9 +798,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -923,9 +923,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ "log", "ring", @@ -976,7 +976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -1014,18 +1014,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", @@ -1034,9 +1034,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", @@ -1088,9 +1088,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", @@ -1251,9 +1251,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -1262,9 +1262,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", ] @@ -1283,9 +1283,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" @@ -1487,43 +1487,100 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.10.1" @@ -1550,9 +1607,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zip" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" +checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" dependencies = [ "byteorder", "crc32fast", From 7c371a6852d4b2bdad280be766283abbf93e56ff Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 24 Oct 2022 14:42:37 +0200 Subject: [PATCH 076/196] Release v1.6.1 --- CHANGELOG.md | 20 +++++++++++++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/usage.txt | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d61ae..874b2b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,20 @@ Possible log types: - `[chore]` for maintenance work. +### [v1.6.1][v1.6.1] (2022-10-24) + +Changes: + +- [fixed] Fix path source for custom pages dir ([#297]) +- [chore] Update dependendencies ([#299]) + +Contributors to this version: + +- [Cyrus Yip][@CyrusYip] + +Thanks! + + ### [v1.6.0][v1.6.0] (2022-10-02) It's been 9 months since the last release already! This is not a huge update @@ -291,8 +305,9 @@ Thanks! [@bl-ue]: https://github.com/bl-ue [@Calinou]: https://github.com/Calinou [@cam8001]: https://github.com/cam8001 -[@cyqsimon]: https://github.com/cyqsimon [@cho-m]: https://github.com/cho-m +[@cyqsimon]: https://github.com/cyqsimon +[@CyrusYip]: https://github.com/CyrusYip [@das-g]: https://github.com/das-g [@dbrgn]: https://github.com/dbrgn [@Delapouite]: https://github.com/Delapouite @@ -337,6 +352,7 @@ Thanks! [v1.4.1]: https://github.com/dbrgn/tealdeer/compare/v1.4.0...v1.4.1 [v1.5.0]: https://github.com/dbrgn/tealdeer/compare/v1.4.1...v1.5.0 [v1.6.0]: https://github.com/dbrgn/tealdeer/compare/v1.5.0...v1.6.0 +[v1.6.1]: https://github.com/dbrgn/tealdeer/compare/v1.6.0...v1.6.1 [i34]: https://github.com/dbrgn/tealdeer/issues/34 [i43]: https://github.com/dbrgn/tealdeer/issues/43 @@ -401,3 +417,5 @@ Thanks! [#287]: https://github.com/dbrgn/tealdeer/pull/287 [#290]: https://github.com/dbrgn/tealdeer/pull/290 [#291]: https://github.com/dbrgn/tealdeer/pull/291 +[#297]: https://github.com/dbrgn/tealdeer/pull/297 +[#299]: https://github.com/dbrgn/tealdeer/pull/299 diff --git a/Cargo.lock b/Cargo.lock index 68ed79c..baf16a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1099,7 +1099,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.6.0" +version = "1.6.1" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index 9d4b7b4..de29b01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" -version = "1.6.0" +version = "1.6.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png"] rust-version = "1.62" edition = "2021" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 9977a03..09edc5e 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.6.0 +tealdeer 1.6.1 Danilo Bargen , Niklas Mohrin A fast TLDR client From 76bb4e72bc1a9ba23b527dd01ddf5707e7200700 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 24 Oct 2022 15:04:23 +0200 Subject: [PATCH 077/196] Update CHANGELOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forgot to add myself 🙃 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 874b2b6..baccbf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Changes: Contributors to this version: - [Cyrus Yip][@CyrusYip] +- [Danilo Bargen][@dbrgn] Thanks! From fc8266d1c990996d4aa20a64958bbd2cf0af34c5 Mon Sep 17 00:00:00 2001 From: Mohit Raj Date: Mon, 19 Dec 2022 04:10:27 +0530 Subject: [PATCH 078/196] Docs: Add scoop package manager as supported installation method (#305) --- docs/src/installing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/installing.md b/docs/src/installing.md index 67c3748..fd8f202 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -23,6 +23,7 @@ Tealdeer has been added to a few package managers: - NetBSD: [`sysutils/tealdeer`](https://pkgsrc.se/sysutils/tealdeer) - Nix: [`tealdeer`](https://nixos.org/nixos/packages.html#tealdeer) - openSUSE: [`tealdeer`](https://software.opensuse.org/package/tealdeer?search_term=tealdeer) +- Scoop: [`tealdeer`](https://github.com/ScoopInstaller/Main/blob/master/bucket/tealdeer.json) - Solus: [`tealdeer`](https://packages.getsol.us/shannon/t/tealdeer/) - Void Linux: [`tealdeer`](https://github.com/void-linux/void-packages/tree/master/srcpkgs/tealdeer) From e75f8142948cd6437e6e44b731cc58c04273fecf Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Dec 2022 14:54:40 +0100 Subject: [PATCH 079/196] Run cargo update --- Cargo.lock | 196 ++++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index baf16a6..346c47b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,18 +10,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "app_dirs2" @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.5" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5c2ca00549910ec251e3bd15f87aeeb206c9456b9a77b43ff6c97c54042a472" +checksum = "fa3d466004a8b4cb1bc34044240a2fd29d17607e2e3bd613eb44fd48e8100da3" dependencies = [ "bstr", "doc-comment", @@ -55,7 +55,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -80,13 +80,14 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" -version = "0.2.17" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" dependencies = [ - "lazy_static", "memchr", + "once_cell", "regex-automata", + "serde", ] [[package]] @@ -103,15 +104,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cesu8" @@ -127,9 +128,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.22" +version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", "bitflags", @@ -201,9 +202,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", ] @@ -257,9 +258,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -312,9 +313,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" dependencies = [ "cfg-if", "libc", @@ -324,9 +325,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "miniz_oxide", @@ -417,9 +418,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -455,6 +456,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "http" version = "0.2.8" @@ -497,9 +507,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -521,9 +531,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ "http", "hyper", @@ -544,9 +554,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -563,9 +573,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" [[package]] name = "itertools" @@ -578,9 +588,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "jni" @@ -619,9 +629,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.135" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "log" @@ -646,23 +656,23 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -688,19 +698,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "openssl-probe" @@ -710,9 +720,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "os_str_bytes" -version = "6.3.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "pager" @@ -744,9 +754,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "predicates" -version = "2.1.1" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" +checksum = "f54fc5dc63ed3bbf19494623db4f3af16842c0d975818e469022d09e53f0aa05" dependencies = [ "difflib", "float-cmp", @@ -758,15 +768,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" +checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" [[package]] name = "predicates-tree" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" +checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" dependencies = [ "predicates-core", "termtree", @@ -798,18 +808,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -836,9 +846,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -853,9 +863,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -868,9 +878,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" dependencies = [ "base64", "bytes", @@ -956,9 +966,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "same-file" @@ -1014,18 +1024,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", @@ -1034,9 +1044,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", @@ -1088,9 +1098,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -1147,30 +1157,30 @@ dependencies = [ [[package]] name = "termtree" -version = "0.2.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" +checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" [[package]] name = "textwrap" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -1194,9 +1204,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -1206,7 +1216,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -1236,9 +1246,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] @@ -1283,9 +1293,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -1443,9 +1453,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.5" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] From b5f2c6ff3994e985e4d8eb7d2c89e86a4217b897 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sat, 24 Dec 2022 14:55:45 +0100 Subject: [PATCH 080/196] =?UTF-8?q?Upgrade=20env=5Flogger:=200.9=20?= =?UTF-8?q?=E2=86=92=200.10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 48 +++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 346c47b..755b774 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,12 +258,12 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", @@ -571,12 +571,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -633,6 +655,12 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "log" version = "0.4.17" @@ -931,6 +959,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "rustls" version = "0.20.7" diff --git a/Cargo.toml b/Cargo.toml index de29b01..6522fd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" clap = { version = "3", features = ["std", "derive", "suggestions", "color"], default-features = false } -env_logger = { version = "0.9", optional = true } +env_logger = { version = "0.10", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking"], default-features = false } serde = "1.0.21" From c077ff05e4545fd4ba9c218d87c932b2ec916a82 Mon Sep 17 00:00:00 2001 From: "Y.D.X" <73375426+YDX-2147483647@users.noreply.github.com> Date: Wed, 11 Jan 2023 18:22:49 +0800 Subject: [PATCH 081/196] =?UTF-8?q?Docs:=20Fix=20typo=20(irregular=20space?= =?UTF-8?q?=20=E2=86=92=20regular=20space)=20(#310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was a no-break space (U+00A0), which causes mdBook to ignore the line break and [render wrongly](https://dbrgn.github.io/tealdeer/installing.html#package-managers). Instead, a regular space (U+0020) should be used. --- docs/src/installing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/installing.md b/docs/src/installing.md index fd8f202..61c1fcf 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -23,7 +23,7 @@ Tealdeer has been added to a few package managers: - NetBSD: [`sysutils/tealdeer`](https://pkgsrc.se/sysutils/tealdeer) - Nix: [`tealdeer`](https://nixos.org/nixos/packages.html#tealdeer) - openSUSE: [`tealdeer`](https://software.opensuse.org/package/tealdeer?search_term=tealdeer) -- Scoop: [`tealdeer`](https://github.com/ScoopInstaller/Main/blob/master/bucket/tealdeer.json) +- Scoop: [`tealdeer`](https://github.com/ScoopInstaller/Main/blob/master/bucket/tealdeer.json) - Solus: [`tealdeer`](https://packages.getsol.us/shannon/t/tealdeer/) - Void Linux: [`tealdeer`](https://github.com/void-linux/void-packages/tree/master/srcpkgs/tealdeer) From 76d9d0bbdaa50503a192821e4c2215aedac59117 Mon Sep 17 00:00:00 2001 From: tveness Date: Tue, 7 Feb 2023 20:56:41 +0000 Subject: [PATCH 082/196] Obey 1.67 clippy lints (#313) --- src/cache.rs | 10 +++++----- src/config.rs | 4 ++-- src/main.rs | 23 ++++++++++------------- src/output.rs | 2 +- src/utils.rs | 9 ++------- tests/lib.rs | 18 +++++++++--------- 6 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 57b1a30..b0d1fce 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -155,7 +155,7 @@ impl Cache { .get(archive_url) .send()? .error_for_status() - .with_context(|| format!("Could not download tldr pages from {}", archive_url))?; + .with_context(|| format!("Could not download tldr pages from {archive_url}"))?; let mut buf: Vec = vec![]; let bytes_downloaded = resp.copy_to(&mut buf)?; debug!("{} bytes downloaded", bytes_downloaded); @@ -248,9 +248,9 @@ impl Cache { languages: &[String], custom_pages_dir: Option<&Path>, ) -> Option { - let page_filename = format!("{}.md", name); - let patch_filename = format!("{}.patch", name); - let custom_filename = format!("{}.page", name); + let page_filename = format!("{name}.md"); + let patch_filename = format!("{name}.patch"); + let custom_filename = format!("{name}.page"); // Determine directory paths let pages_dir = self.pages_dir(); @@ -260,7 +260,7 @@ impl Cache { if lang == "en" { String::from("pages") } else { - format!("pages.{}", lang) + format!("pages.{lang}") } }) .collect(); diff --git a/src/config.rs b/src/config.rs index e1bc4ba..98d4e46 100644 --- a/src/config.rs +++ b/src/config.rs @@ -308,7 +308,7 @@ impl Config { // For backwards compatibility reasons, the cache directory can be // overridden using an env variable. This is deprecated and will be // phased out in the future. - eprintln!("Warning: The ${} env variable is deprecated, use the `cache_dir` option in the config file instead.", cache_dir_env_var); + eprintln!("Warning: The ${cache_dir_env_var} env variable is deprecated, use the `cache_dir` option in the config file instead."); PathWithSource { path: PathBuf::from(env_var), source: PathSource::EnvVar, @@ -376,7 +376,7 @@ impl Config { format!("Failed to read from config file at {:?}", &config_file_path) })?; toml::from_str(&contents).with_context(|| { - format!("Failed to parse TOML config file at {:?}", config_file_path) + format!("Failed to parse TOML config file at {config_file_path:?}") })? } else { RawConfig::new() diff --git a/src/main.rs b/src/main.rs index 8f601e4..fed5f6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -119,12 +119,9 @@ fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { if !quietly { let cache_dir = cache.cache_dir().display(); if cache_dir_found { - eprintln!("Successfully cleared cache at `{}`.", cache_dir); + eprintln!("Successfully cleared cache at `{cache_dir}`."); } else { - eprintln!( - "Cache directory not found at `{}`, nothing to do.", - cache_dir - ); + eprintln!("Cache directory not found at `{cache_dir}`, nothing to do."); } } } @@ -143,17 +140,17 @@ fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { /// Show file paths fn show_paths(config: &Config) { let config_dir = get_config_dir().map_or_else( - |e| format!("[Error: {}]", e), + |e| format!("[Error: {e}]"), |(mut path, source)| { path.push(""); // Trailing path separator match path.to_str() { - Some(path) => format!("{} ({})", path, source), + Some(path) => format!("{path} ({source})"), None => "[Invalid]".to_string(), } }, ); let config_path = get_config_path().map_or_else( - |e| format!("[Error: {}]", e), + |e| format!("[Error: {e}]"), |(path, _)| path.display().to_string(), ); let cache_dir = config.directories.cache_dir.to_string(); @@ -167,11 +164,11 @@ fn show_paths(config: &Config) { Some(ref path_with_source) => path_with_source.to_string(), None => "[None]".to_string(), }; - println!("Config dir: {}", config_dir); - println!("Config path: {}", config_path); - println!("Cache dir: {}", cache_dir); - println!("Pages dir: {}", pages_dir); - println!("Custom pages dir: {}", custom_pages_dir); + println!("Config dir: {config_dir}"); + println!("Config path: {config_path}"); + println!("Cache dir: {cache_dir}"); + println!("Pages dir: {pages_dir}"); + println!("Custom pages dir: {custom_pages_dir}"); } /// Create seed config file and exit diff --git a/src/output.rs b/src/output.rs index e09481e..357b988 100644 --- a/src/output.rs +++ b/src/output.rs @@ -51,7 +51,7 @@ pub fn print_page( // Print the raw markdown of the file. for line in reader.lines() { let line = line.context("Error while reading from a page")?; - writeln!(handle, "{}", line).context("Could not write to stdout")?; + writeln!(handle, "{line}").context("Could not write to stdout")?; } } else { // Closure that processes a page snippet and writes it to stdout diff --git a/src/utils.rs b/src/utils.rs index 879733a..1649281 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -9,18 +9,13 @@ pub fn print_warning(enable_styles: bool, message: &str) { /// Print an anyhow error to stderr. If `enable_styles` is true, then a red /// message will be printed. pub fn print_error(enable_styles: bool, error: &anyhow::Error) { - print_msg( - enable_styles, - &format!("{:?}", error), - "Error: ", - Color::Red, - ); + print_msg(enable_styles, &format!("{error:?}"), "Error: ", Color::Red); } fn print_msg(enable_styles: bool, message: &str, prefix: &'static str, color: Color) { if enable_styles { eprintln!("{}{}", color.paint(prefix), color.paint(message)); } else { - eprintln!("{}", message); + eprintln!("{message}"); } } diff --git a/tests/lib.rs b/tests/lib.rs index 230b2f2..07092b0 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -55,7 +55,7 @@ impl TestEnv { /// Write `content` to "config.toml" in the `config_dir` directory fn write_config(&self, content: impl AsRef) { let config_file_name = self.config_dir.path().join("config.toml"); - println!("Config path: {:?}", config_file_name); + println!("Config path: {config_file_name:?}"); let mut config_file = File::create(&config_file_name).unwrap(); config_file.write_all(content.as_ref().as_bytes()).unwrap(); @@ -76,7 +76,7 @@ impl TestEnv { .join(os); create_dir_all(&dir).unwrap(); - let mut file = File::create(&dir.join(format!("{}.md", name))).unwrap(); + let mut file = File::create(dir.join(format!("{name}.md"))).unwrap(); file.write_all(contents.as_bytes()).unwrap(); } @@ -84,7 +84,7 @@ impl TestEnv { fn add_page_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(&dir.join(format!("{}.page", name))).unwrap(); + let mut file = File::create(dir.join(format!("{name}.page"))).unwrap(); file.write_all(contents.as_bytes()).unwrap(); } @@ -92,7 +92,7 @@ impl TestEnv { fn add_patch_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(&dir.join(format!("{}.patch", name))).unwrap(); + let mut file = File::create(dir.join(format!("{name}.patch"))).unwrap(); file.write_all(contents.as_bytes()).unwrap(); } @@ -120,7 +120,7 @@ impl TestEnv { build = build.arg("--no-default-features"); } if !self.features.is_empty() { - build = build.arg(&format!("--feature {}", self.features.join(","))); + build = build.arg(format!("--feature {}", self.features.join(","))); } let run = build.run().unwrap(); let mut cmd = run.command(); @@ -426,7 +426,7 @@ fn _test_correct_rendering( // Create input file let file_path = testenv.input_dir.path().join(filename); - println!("Testfile path: {:?}", file_path); + println!("Testfile path: {file_path:?}"); let mut file = File::create(&file_path).unwrap(); file.write_all(input_file.as_bytes()).unwrap(); @@ -501,7 +501,7 @@ fn test_correct_rendering_with_config() { // Setup config file // TODO should be config::CONFIG_FILE_NAME let config_file_path = testenv.config_dir.path().join("config.toml"); - println!("Config path: {:?}", config_file_path); + println!("Config path: {config_file_path:?}"); let mut config_file = File::create(&config_file_path).unwrap(); config_file @@ -510,7 +510,7 @@ fn test_correct_rendering_with_config() { // Create input file let file_path = testenv.input_dir.path().join("inkscape-v2.md"); - println!("Testfile path: {:?}", file_path); + println!("Testfile path: {file_path:?}"); let mut file = File::create(&file_path).unwrap(); file.write_all(include_bytes!("inkscape-v2.md")).unwrap(); @@ -620,7 +620,7 @@ fn test_autoupdate_cache() { 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(); + let mut config_file = File::create(config_file_path).unwrap(); config_file .write_all(b"[updates]\nauto_update = true\nauto_update_interval_hours = 24") .unwrap(); From 0c8cb42664ed1c27df5c41ca82b88d3f9a32687f Mon Sep 17 00:00:00 2001 From: Blair Noctis <4474501+bnoctis@users.noreply.github.com> Date: Sat, 11 Feb 2023 06:28:45 +0800 Subject: [PATCH 083/196] Docs: Add Debian to packaged list (#315) --- docs/src/installing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/installing.md b/docs/src/installing.md index 61c1fcf..c2d6067 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -15,6 +15,7 @@ autocompletions](#autocompletion). Tealdeer has been added to a few package managers: - Arch Linux: [`tealdeer`](https://archlinux.org/packages/community/x86_64/tealdeer/) +- Debian: [`tealdeer`](https://tracker.debian.org/tealdeer) - Fedora: [`tealdeer`](https://src.fedoraproject.org/rpms/rust-tealdeer) - FreeBSD: [`sysutils/tealdeer`](https://www.freshports.org/sysutils/tealdeer/) - Funtoo: [`app-misc/tealdeer`](https://github.com/funtoo/core-kit/tree/1.4-release/app-misc/tealdeer) From 72362769deb7124b344724022af64da0599cfe30 Mon Sep 17 00:00:00 2001 From: qknogxxb <117920064+qknogxxb@users.noreply.github.com> Date: Mon, 13 Feb 2023 01:45:53 +0800 Subject: [PATCH 084/196] Line iterator: Drop empty line without allocating (#314) Co-authored-by: Niklas Mohrin --- src/line_iterator.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/line_iterator.rs b/src/line_iterator.rs index 4d0eab6..a02b1be 100644 --- a/src/line_iterator.rs +++ b/src/line_iterator.rs @@ -1,6 +1,6 @@ //! Code to split a `BufRead` instance into an iterator of `LineType`s. -use std::io::BufRead; +use std::io::{BufRead, Read}; use log::warn; @@ -64,9 +64,10 @@ impl Iterator for LineIterator { self.format = TldrFormat::V1; } else { // It's the new format! Drop next line. - // (Hmm, is there a way to do this without an allocation?) - let mut devnull = String::new(); - if let Err(e) = self.reader.read_line(&mut devnull) { + if let Err(e) = Read::bytes(&mut self.reader) + .find(|b| matches!(b, Ok(b'\n') | Err(_))) + .transpose() + { warn!("Could not read line from reader: {:?}", e); return None; } From 2fa1994c762135d0d66a5f83d894290bb60c53ae Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 01:23:08 +0200 Subject: [PATCH 085/196] CHANGELOG: Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baccbf0..b50e687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ probably the option to override the cache directory through the config file. The `TEALDEER_CACHE_DIR` env variable is now deprecated. A note to packagers: Shell completions have been moved to the `completion/` -subdirectory! Packaging scripst might need to be updated. +subdirectory! Packaging scripts might need to be updated. Changes: From b07a6728f3c2af471c63bcde7ba5a014c3c4a2ae Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 01:23:52 +0200 Subject: [PATCH 086/196] Docs: Remove note about OpenSSL OpenSSL is not used anymore since version 1.5.0. --- docs/src/installing.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/src/installing.md b/docs/src/installing.md index c2d6067..8aa2e19 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -40,10 +40,6 @@ Build and install the tool via cargo... $ cargo install tealdeer -*(Note: You might need to install OpenSSL development headers, otherwise you get -a "failed to run custom build command for openssl-sys" error message. The -package is called `libssl-dev` on Ubuntu.)* - ## Build From Source Debug build with logging enabled: @@ -60,7 +56,7 @@ To enable the log output, set the `RUST_LOG` env variable: ## Autocompletion -Shell completion scripts are located in the folder `completion`. +Shell completion scripts are located in the folder `completion`. Just copy them to their designated location: - *Bash*: `cp completion/bash_tealdeer /usr/share/bash-completion/completions/tldr` From 74d1ade88414e543e1d7ec969edf7f725f7af152 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 01:26:17 +0200 Subject: [PATCH 087/196] Docs: Mention building with bundled roots --- docs/src/installing.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/src/installing.md b/docs/src/installing.md index 8aa2e19..d6b2a9a 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -42,17 +42,19 @@ Build and install the tool via cargo... ## Build From Source -Debug build with logging enabled: - - $ cargo build --features logging - -Release build without logging: +Release build: $ cargo build --release -To enable the log output, set the `RUST_LOG` env variable: +Release build with bundled CA roots: - $ export RUST_LOG=tldr=debug + $ cargo build --release --no-default-features --features webpki-roots + +Debug build with logging support: + + $ cargo build --features logging + +(To enable logging at runtime, export the `RUST_LOG=tldr=debug` env variable.) ## Autocompletion From c9ec88354a51ce7af561853720d2b48c31bfee94 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 01:28:42 +0200 Subject: [PATCH 088/196] Docs: Remove section about overriding cache dir The env var `TEALDEER_CACHE_DIR` is deprecated. The new way to configure the cache dir is documented in the "[directories]" section. --- docs/src/config.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/src/config.md b/docs/src/config.md index 020687e..ece2706 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -52,11 +52,3 @@ auto_update = true The directory where the configuration file resides may be overwritten by the environment variable `TEALDEER_CONFIG_DIR`. Remember to use an absolute path. Variable expansion will not be performed on the path. - -## Override Cache Directory - -Similarly, the cache directory where the pages are downloaded to, also follows -OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`. The path -can be overwritten using the environment variable `TEALDEER_CACHE_DIR`. -Remember to use an absolute path. Variable expansion will not be performed on -the path. From fb755ba8dc497b62df4672af2654103bccdb7331 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 2 Oct 2022 01:30:40 +0200 Subject: [PATCH 089/196] Docs: Consistent capitalization of tealdeer Capitalize at the start of a sentence, lowercase otherwise. --- CHANGELOG.md | 2 +- README.md | 2 +- docs/src/config_style.md | 4 ++-- docs/src/config_updates.md | 2 +- docs/src/installing.md | 2 +- docs/src/intro.md | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b50e687..e26c474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,7 +107,7 @@ The highlights: Note that the MSRV (Minimal Supported Rust Version) of the project [changed][i190]: -> When publishing a Tealdeer release, the Rust version required to build it +> When publishing a tealdeer release, the Rust version required to build it > should be stable for at least a month. Changes: diff --git a/README.md b/README.md index 1746860..fb38ea6 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ To run lints: ## MSRV (Minimally Supported Rust Version) -When publishing a Tealdeer release, the Rust version required to build it +When publishing a tealdeer release, the Rust version required to build it should be stable for at least a month. diff --git a/docs/src/config_style.md b/docs/src/config_style.md index 527e3e5..190df4c 100644 --- a/docs/src/config_style.md +++ b/docs/src/config_style.md @@ -28,13 +28,13 @@ Colors can be specified in one of three ways: foreground = "green" -- 256 color ANSI code (*Tealdeer v1.5.0+*) +- 256 color ANSI code (*tealdeer v1.5.0+*) Example: foreground = { ansi = 4 } -- 24-bit RGB color (*Tealdeer v1.5.0+*) +- 24-bit RGB color (*tealdeer v1.5.0+*) Example: diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index 5eb8f95..f010cc6 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -2,7 +2,7 @@ ## Automatic updates -tealdeer can refresh the cache automatically when it is outdated. This +Tealdeer can refresh the cache automatically when it is outdated. This behavior can be configured in the `updates` section and is disabled by default. diff --git a/docs/src/installing.md b/docs/src/installing.md index d6b2a9a..1163a14 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -1,6 +1,6 @@ # Installing -There are a few different ways to install Tealdeer: +There are a few different ways to install tealdeer: - Through [package managers](#package-managers) - Through [static binaries](#static-binaries-linux) diff --git a/docs/src/intro.md b/docs/src/intro.md index 09106b0..ca9f8cc 100644 --- a/docs/src/intro.md +++ b/docs/src/intro.md @@ -6,7 +6,7 @@ and community-driven man pages. ![Screenshot](screenshot-default.png) -This documentation shows how to install, use and configure Tealdeer. +This documentation shows how to install, use and configure tealdeer. ## Links From 94d56c01a787f574fc380c5fb9fcced767efccea Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 14 Feb 2023 18:21:07 +0100 Subject: [PATCH 090/196] Allow building with native-tls (#303) Right now we only support building with Rustls. However, there are quite a few architectures that aren't yet supported by "ring" (the crypto library used by Rustls), for example MIPS, PowerPC or SPARC. To offer an alternative, I added the "native-tls" feature that can be used instead of "native-roots". When used, the native TLS stack is used instead of Rustls (i.e. SChannel on Windows, Secure Transport on macOS and OpenSSL otherwise). --- Cargo.lock | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 13 ++++++- src/main.rs | 10 ++++- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 755b774..972c24e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,6 +348,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -542,6 +557,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "idna" version = "0.3.0" @@ -703,6 +731,24 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk-context" version = "0.1.1" @@ -740,12 +786,51 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +[[package]] +name = "openssl" +version = "0.10.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "os_str_bytes" version = "6.4.1" @@ -780,6 +865,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "predicates" version = "2.1.4" @@ -920,10 +1011,12 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -934,6 +1027,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", + "tokio-native-tls", "tokio-rustls", "tower-service", "url", @@ -1261,6 +1355,16 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -1365,6 +1469,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 6522fd0..e3223a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,9 +46,20 @@ filetime = "0.2.10" [features] default = ["native-roots"] +logging = ["env_logger"] + +# Reqwest (the HTTP client library) can handle TLS connections in three +# different modes: +# +# - Rustls with native roots +# - Rustls with WebPK roots +# - Native TLS (SChannel on Windows, Secure Transport on macOS and OpenSSL otherwise) +# +# Exactly one of the three variants must be selected. By default, Rustls with +# native roots is enabled. native-roots = ["reqwest/rustls-tls-native-roots"] webpki-roots = ["reqwest/rustls-tls-webpki-roots"] -logging = ["env_logger"] +native-tls = ["reqwest/native-tls"] [profile.release] lto = true diff --git a/src/main.rs b/src/main.rs index fed5f6e..08afe20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,10 +18,16 @@ #[cfg(any( all(feature = "native-roots", feature = "webpki-roots"), - not(any(feature = "native-roots", feature = "webpki-roots")), + all(feature = "native-roots", feature = "native-tls"), + all(feature = "webpki-roots", feature = "native-tls"), + not(any( + feature = "native-roots", + feature = "webpki-roots", + feature = "native-tls" + )), ))] compile_error!( - "exactly one of feature \"native-roots\" and feature \"webpki-roots\" must be enabled" + "exactly one of the features \"native-roots\", \"webpki-roots\" or \"native-tls\" must be enabled" ); use std::{env, process}; From 8c6754ae78e48b91b343cdafa9918919c160b332 Mon Sep 17 00:00:00 2001 From: qknogxxb <117920064+qknogxxb@users.noreply.github.com> Date: Thu, 6 Jul 2023 05:33:39 +0800 Subject: [PATCH 091/196] Line iterator: Improve test functions (#316) --- src/line_iterator.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/line_iterator.rs b/src/line_iterator.rs index a02b1be..75a56bd 100644 --- a/src/line_iterator.rs +++ b/src/line_iterator.rs @@ -96,21 +96,27 @@ mod test { #[test] fn test_first_line_old_format() { - let input = "# The Title\n\n"; + let input = "# The Title\n> Description\n"; let mut lines = LineIterator::new(input.as_bytes()); let title = lines.next().unwrap(); assert_eq!(title, LineType::Title("The Title".to_string())); - let empty = lines.next().unwrap(); - assert_eq!(empty, LineType::Empty); + let description = lines.next().unwrap(); + assert_eq!( + description, + LineType::Description("Description".to_string()) + ); } #[test] fn test_first_line_new_format() { - let input = "The Title\n=========\n\n"; + let input = "The Title\n=========\n> Description\n"; let mut lines = LineIterator::new(input.as_bytes()); let title = lines.next().unwrap(); assert_eq!(title, LineType::Title("The Title".to_string())); - let empty = lines.next().unwrap(); - assert_eq!(empty, LineType::Empty); + let description = lines.next().unwrap(); + assert_eq!( + description, + LineType::Description("Description".to_string()) + ); } } From 45b3db6dc4a28c06077ed666c828da9e699cbd08 Mon Sep 17 00:00:00 2001 From: Adam Henley Date: Fri, 7 Jul 2023 02:20:46 +1200 Subject: [PATCH 092/196] Guard Fish completion when cache is empty (#331) Signed-off-by: Adam Henley --- completion/fish_tealdeer | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index 601b114..dcb41c3 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -20,7 +20,9 @@ complete -c tldr -l seed-config -d 'Create a basic config.' -f complete -c tldr -l color -d 'Controls when to use color.' -xa 'always auto never' function __tealdeer_entries - tldr --list | string replace -a -i -r "\,\s" "\n" + if set entries (tldr --list 2>/dev/null) + string replace -a -i -r "\,\s" "\n" $entries + end end complete -f -c tldr -a '(__tealdeer_entries)' From de9cf431a8dd4ac827244953f70166c5dc2cf489 Mon Sep 17 00:00:00 2001 From: Iliia Maleki <53195438+iliya-malecki@users.noreply.github.com> Date: Thu, 6 Jul 2023 16:22:50 +0200 Subject: [PATCH 093/196] Completions: Add checks for wrong `tldr --list` output (#327) --- completion/bash_tealdeer | 5 +++-- completion/zsh_tealdeer | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/completion/bash_tealdeer b/completion/bash_tealdeer index 507e956..1fc0655 100644 --- a/completion/bash_tealdeer +++ b/completion/bash_tealdeer @@ -27,8 +27,9 @@ _tealdeer() COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) return fi - - COMPREPLY=( $(compgen -W '$( tldr -l | tr -d , )' -- "${cur}") ) + if tldrlist=$(tldr -l 2>/dev/null); then + COMPREPLY=( $(compgen -W '$( echo "$tldrlist" | tr -d , )' -- "${cur}") ) + fi } complete -F _tealdeer tldr diff --git a/completion/zsh_tealdeer b/completion/zsh_tealdeer index 99c12be..0d08745 100644 --- a/completion/zsh_tealdeer +++ b/completion/zsh_tealdeer @@ -2,8 +2,9 @@ _applications() { local -a commands - commands=(${(uonzf)"$(tldr --list 2>/dev/null)"//:/\\:}) - _describe -t commands 'command' commands + if commands=(${(uonzf)"$(tldr --list 2>/dev/null)"//:/\\:}); then + _describe -t commands 'command' commands + fi } _tealdeer() { From 7bd5ac566483d1beeeb7bdbf5f6c0909c086c08e Mon Sep 17 00:00:00 2001 From: "K.B.Dharun Krishna" Date: Fri, 7 Jul 2023 03:20:14 +0530 Subject: [PATCH 094/196] Update CI workflows (#324) --- .github/workflows/ci.yml | 72 ++++++++++++---------------------- .github/workflows/gh-pages.yml | 4 +- .github/workflows/release.yml | 54 +++++++++++++------------ 3 files changed, 56 insertions(+), 74 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f53a47..7bb9bf4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,79 +14,59 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - rust: ['1.62', stable] + toolchain: [stable, 1.62.1] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ matrix.rust }} - profile: minimal - default: true + toolchain: ${{ matrix.toolchain }} - name: Build with default features - uses: actions-rs/cargo@v1 - with: - command: build + run: cargo build - name: Build with logging and webpki roots - uses: actions-rs/cargo@v1 - with: - command: build - args: --features logging,webpki-roots --no-default-features + run: cargo build --features logging,webpki-roots --no-default-features - name: Run tests - uses: actions-rs/cargo@v1 - with: - command: test + run: cargo test clippy: name: run clippy lints runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - default: true - components: clippy - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --features logging + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy + - name: run clippy lints + run: cargo clippy --features logging fmt: name: run rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - default: true - components: rustfmt - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt + - name: run rustfmt + run: cargo fmt --all -- --check docs: name: build docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 with: mdbook-version: '0.4.4' - - uses: actions-rs/toolchain@v1 + - name: Setup toolchain + uses: dtolnay/rust-toolchain@master with: - toolchain: stable - profile: minimal - default: true + toolchain: stable - name: Build - uses: actions-rs/cargo@v1 - with: - command: build + run: cargo build - name: Ensure that docs can be built run: cd docs && mdbook build - name: Generate usage string diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index c32ec71..dafba80 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -7,9 +7,9 @@ on: jobs: deploy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e42acc..3795fc3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,9 +5,9 @@ on: jobs: create-release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Create release for tag if: startsWith(github.ref, 'refs/tags/') run: | @@ -18,12 +18,12 @@ jobs: upload-completions: needs: - create-release - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: target: ["bash", "fish", "zsh"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | @@ -34,12 +34,12 @@ jobs: upload-license: needs: - create-release - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: target: ["MIT", "APACHE"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | @@ -48,7 +48,7 @@ jobs: upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }}.txt build-linux: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: include: @@ -63,42 +63,44 @@ jobs: - arch: "arm" libc: "musleabihf" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - name: Build in Docker run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" build-macos: - runs-on: macos-11 + runs-on: macos-latest steps: - - uses: actions/checkout@v2 - - name: Build - uses: actions-rs/cargo@v1 + - uses: actions/checkout@v3 + - name: Setup toolchain + uses: dtolnay/rust-toolchain@master with: - command: build - args: --release --target x86_64-apple-darwin --no-default-features --features webpki-roots - - uses: actions/upload-artifact@v2 + toolchain: stable + - name: Build + run: cargo build --release --target x86_64-apple-darwin --no-default-features --features webpki-roots + - uses: actions/upload-artifact@v3 with: name: "tealdeer-macos-x86_64" path: "target/x86_64-apple-darwin/release/tldr" build-windows: - runs-on: windows-2022 + runs-on: windows-latest steps: - - uses: actions/checkout@v2 - - name: Build - uses: actions-rs/cargo@v1 + - uses: actions/checkout@v3 + - name: Setup toolchain + uses: dtolnay/rust-toolchain@master with: - command: build - args: --release --target x86_64-pc-windows-msvc - - uses: actions/upload-artifact@v2 + toolchain: stable + - name: Build + run: cargo build --release --target x86_64-pc-windows-msvc + - uses: actions/upload-artifact@v3 with: name: "tealdeer-windows-x86_64-msvc" path: "target/x86_64-pc-windows-msvc/release/tldr.exe" @@ -109,7 +111,7 @@ jobs: - build-linux - build-macos - build-windows - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: target: @@ -121,8 +123,8 @@ jobs: - macos-x86_64 - windows-x86_64-msvc steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v2 + - uses: actions/checkout@v3 + - uses: actions/download-artifact@v3 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | From 4d2fc26dbea7229b37e08ca2ba0689a69925abb7 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Mon, 10 Jul 2023 18:22:20 +0200 Subject: [PATCH 095/196] Include `completion/*` in published crate (#333) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e3223a3..aedc55f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" version = "1.6.1" -include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png"] +include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.62" edition = "2021" From 1764cee1bd0b857889cea9feaa79d52aeb697e3f Mon Sep 17 00:00:00 2001 From: Andrea Frigido Date: Sun, 13 Aug 2023 21:13:06 +0200 Subject: [PATCH 096/196] Cargo.toml: Update license field following SPDX 2.1 license expression standard (#336) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index aedc55f..2953457 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = [ ] description = "Fetch and show tldr help pages for many CLI commands. Full featured offline client with caching support." homepage = "https://github.com/dbrgn/tealdeer/" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" name = "tealdeer" readme = "README.md" repository = "https://github.com/dbrgn/tealdeer/" From 9e1489bbc549dc86f8efe47d924512d48add10ed Mon Sep 17 00:00:00 2001 From: JJ Style Date: Sun, 27 Aug 2023 21:52:20 +0000 Subject: [PATCH 097/196] Allow querying multiple platforms (#300) --- docs/src/usage.txt | 33 +++++------ src/cache.rs | 36 +++++++----- src/cli.rs | 5 +- src/main.rs | 15 +++-- tests/lib.rs | 138 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+), 36 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 09edc5e..74b3b2e 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -9,21 +9,22 @@ ARGS: ... The command to show (e.g. `tar` or `git log`) OPTIONS: - -l, --list List all commands in the cache - -f, --render Render a specific markdown file - -p, --platform Override the operating system [possible values: linux, macos, - windows, sunos, osx, android] - -L, --language Override the language - -u, --update Update the local cache - --no-auto-update If auto update is configured, disable it for this run - -c, --clear-cache Clear the local cache - --pager Use a pager to page output - -r, --raw Display the raw markdown instead of rendering it - -q, --quiet Suppress informational messages - --show-paths Show file and directory paths used by tealdeer - --seed-config Create a basic config - --color Control whether to use color [possible values: always, auto, never] - -v, --version Print the version - -h, --help Print help information + -l, --list List all commands in the cache + -f, --render Render a specific markdown file + -p, --platform Override the operating system [possible values: linux, macos, + windows, sunos, osx, android] + -L, --language Override the language + -u, --update Update the local cache + --no-auto-update If auto update is configured, disable it for this run + -c, --clear-cache Clear the local cache + --pager Use a pager to page output + -r, --raw Display the raw markdown instead of rendering it + -q, --quiet Suppress informational messages + --show-paths Show file and directory paths used by tealdeer + --seed-config Create a basic config + --color Control whether to use color [possible values: always, auto, + never] + -v, --version Print the version + -h, --help Print help information To view the user documentation, please visit https://dbrgn.github.io/tealdeer/. diff --git a/src/cache.rs b/src/cache.rs index b0d1fce..aa64f5e 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -20,7 +20,6 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; #[derive(Debug)] pub struct Cache { - platform: PlatformType, cache_dir: PathBuf, } @@ -86,12 +85,11 @@ pub enum CacheFreshness { } impl Cache { - pub fn new

(platform: PlatformType, cache_dir: P) -> Self + pub fn new

(cache_dir: P) -> Self where P: Into, { Self { - platform, cache_dir: cache_dir.into(), } } @@ -211,8 +209,8 @@ impl Cache { } /// Return the platform directory. - fn get_platform_dir(&self) -> &'static str { - match self.platform { + fn get_platform_dir(platform: PlatformType) -> &'static str { + match platform { PlatformType::Linux => "linux", PlatformType::OsX => "osx", PlatformType::SunOs => "sunos", @@ -247,6 +245,7 @@ impl Cache { name: &str, languages: &[String], custom_pages_dir: Option<&Path>, + platforms: &[PlatformType], ) -> Option { let page_filename = format!("{name}.md"); let patch_filename = format!("{name}.patch"); @@ -275,12 +274,14 @@ impl Cache { let patch_path = Self::find_patch(&patch_filename, custom_pages_dir); - // Try to find a platform specific path next, append custom patch to it. - let platform_dir = self.get_platform_dir(); - if let Some(page) = - Self::find_page_for_platform(&page_filename, &pages_dir, platform_dir, &lang_dirs) - { - return Some(PageLookupResult::with_page(page).with_optional_patch(patch_path)); + // Try to find a platform specific path next, in the order supplied by the user, and append custom patch to it. + for &platform in platforms { + let platform_dir = Cache::get_platform_dir(platform); + if let Some(page) = + Self::find_page_for_platform(&page_filename, &pages_dir, platform_dir, &lang_dirs) + { + return Some(PageLookupResult::with_page(page).with_optional_patch(patch_path)); + } } // Did not find platform specific results, fall back to "common" @@ -289,10 +290,17 @@ impl Cache { } /// Return the available pages. - pub fn list_pages(&self, custom_pages_dir: Option<&Path>) -> Vec { + pub fn list_pages( + &self, + custom_pages_dir: Option<&Path>, + platforms: &[PlatformType], + ) -> Vec { // Determine platforms directory and platform let platforms_dir = self.pages_dir().join("pages"); - let platform_dir = self.get_platform_dir(); + let platform_dirs: Vec<&'static str> = platforms + .iter() + .map(|&p| Self::get_platform_dir(p)) + .collect(); // Closure that allows the WalkDir instance to traverse platform // specific and common page directories, but not others. @@ -303,7 +311,7 @@ impl Cache { None => return false, }; if file_type.is_dir() { - return file_name == "common" || file_name == platform_dir; + return file_name == "common" || platform_dirs.contains(&file_name); } else if file_type.is_file() { return true; } diff --git a/src/cli.rs b/src/cli.rs index 8646cac..ed71ef8 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; -use clap::{AppSettings, ArgGroup, Parser}; +use clap::{AppSettings, ArgAction, ArgGroup, Parser}; use crate::types::{ColorOptions, PlatformType}; @@ -39,9 +39,10 @@ pub(crate) struct Args { #[clap( short = 'p', long = "platform", + action = ArgAction::Append, possible_values = ["linux", "macos", "windows", "sunos", "osx", "android"], )] - pub platform: Option, + pub platforms: Option>, /// Override the language #[clap(short = 'L', long = "language")] diff --git a/src/main.rs b/src/main.rs index 08afe20..15110e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -283,8 +283,11 @@ fn main() { create_config_and_exit(enable_styles); } - // Specify target OS - let platform: PlatformType = args.platform.unwrap_or_else(PlatformType::current); + let fallback_platforms: &[PlatformType] = &[PlatformType::current()]; + let platforms = args + .platforms + .as_ref() + .map_or(fallback_platforms, Vec::as_slice); // If a local file was passed in, render it and exit if let Some(file) = args.render { @@ -298,7 +301,7 @@ fn main() { } // Instantiate cache. This will not yet create the cache directory! - let cache = Cache::new(platform, &config.directories.cache_dir.path); + let cache = Cache::new(&config.directories.cache_dir.path); // Clear cache, pass through if args.clear_cache { @@ -328,7 +331,10 @@ fn main() { .custom_pages_dir .as_ref() .map(PathWithSource::path); - println!("{}", cache.list_pages(custom_pages_dir).join("\n")); + println!( + "{}", + cache.list_pages(custom_pages_dir, platforms).join("\n") + ); process::exit(0); } @@ -353,6 +359,7 @@ fn main() { .custom_pages_dir .as_ref() .map(PathWithSource::path), + platforms, ) { if let Err(ref e) = print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) diff --git a/tests/lib.rs b/tests/lib.rs index 07092b0..0afac46 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -562,6 +562,71 @@ fn test_pager_flag_enable() { .success(); } +#[test] +fn test_multiple_platform_command_search() { + let testenv = TestEnv::new(); + testenv.add_os_entry("linux", "linux-only", "this command only exists for linux"); + testenv.add_os_entry( + "linux", + "windows-and-linux", + "# windows-and-linux \n\n > linux version", + ); + testenv.add_os_entry( + "windows", + "windows-and-linux", + "# windows-and-linux \n\n > windows version", + ); + + testenv + .command() + .args(["--platform", "windows", "--platform", "linux", "linux-only"]) + .assert() + .success(); + + // test order of platforms supplied if preserved + testenv + .command() + .args([ + "--platform", + "windows", + "--platform", + "linux", + "windows-and-linux", + ]) + .assert() + .success() + .stdout(contains("windows version")); + + testenv + .command() + .args([ + "--platform", + "linux", + "--platform", + "windows", + "windows-and-linux", + ]) + .assert() + .success() + .stdout(contains("linux version")); +} + +#[test] +fn test_multiple_platform_command_search_not_found() { + let testenv = TestEnv::new(); + testenv.add_os_entry( + "windows", + "windows-only", + "this command only exists for Windows", + ); + + testenv + .command() + .args(["--platform", "macos", "--platform", "linux", "windows-only"]) + .assert() + .stderr(contains("Page `windows-only` not found in cache.")); +} + #[test] fn test_list_flag_rendering() { let testenv = TestEnv::new(); @@ -604,6 +669,79 @@ fn test_list_flag_rendering() { .stdout("bar\nbaz\nfaz\nfiz\nfoo\nqux\n"); } +#[test] +fn test_multi_platform_list_flag_rendering() { + let testenv = TestEnv::new(); + + // set custom pages directory + testenv.write_config(format!( + "[directories]\ncustom_pages_dir = '{}'", + testenv.custom_pages_dir.path().to_str().unwrap() + )); + + testenv.add_entry("common", ""); + + testenv + .command() + .args(["--list"]) + .assert() + .success() + .stdout("common\n"); + + testenv + .command() + .args(["--platform", "linux", "--list"]) + .assert() + .success() + .stdout("common\n"); + + testenv + .command() + .args(["--platform", "windows", "--list"]) + .assert() + .success() + .stdout("common\n"); + + testenv.add_os_entry("linux", "rm", ""); + testenv.add_os_entry("linux", "ls", ""); + testenv.add_os_entry("windows", "del", ""); + testenv.add_os_entry("windows", "dir", ""); + testenv.add_os_entry("linux", "winux", ""); + testenv.add_os_entry("windows", "winux", ""); + + // test `--list` for `--platform linux` by itself + testenv + .command() + .args(["--platform", "linux", "--list"]) + .assert() + .success() + .stdout("common\nls\nrm\nwinux\n"); + + // test `--list` for `--platform windows` by itself + testenv + .command() + .args(["--platform", "windows", "--list"]) + .assert() + .success() + .stdout("common\ndel\ndir\nwinux\n"); + + // test `--list` for `--platform linux --platform windows` + testenv + .command() + .args(["--platform", "linux", "--platform", "windows", "--list"]) + .assert() + .success() + .stdout("common\ndel\ndir\nls\nrm\nwinux\n"); + + // test `--list` for `--platform windows --platform linux` + testenv + .command() + .args(["--platform", "linux", "--platform", "windows", "--list"]) + .assert() + .success() + .stdout("common\ndel\ndir\nls\nrm\nwinux\n"); +} + #[test] fn test_autoupdate_cache() { let testenv = TestEnv::new(); From a82bc4b8d2b0356372521e0b2133dad8650eb7cf Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Mon, 2 Oct 2023 21:06:09 +0200 Subject: [PATCH 098/196] Add "Tips and Tricks" chapter to user manual (#342) --- docs/src/SUMMARY.md | 1 + docs/src/tips_and_tricks.md | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 docs/src/tips_and_tricks.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 8d1a634..2d5c716 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -10,3 +10,4 @@ - [Section: \[style\]](./config_style.md) - [Section: \[updates\]](./config_updates.md) - [Section: \[directories\]](./config_directories.md) +- [Tips and Tricks](./tips_and_tricks.md) diff --git a/docs/src/tips_and_tricks.md b/docs/src/tips_and_tricks.md new file mode 100644 index 0000000..99a49c7 --- /dev/null +++ b/docs/src/tips_and_tricks.md @@ -0,0 +1,52 @@ +# Tips and Tricks + +This page features some example use cases of Tealdeer. + +## Showing a random page on shell start + +To display a randomly selected page, you can invoke `tldr` twice: One time to +select a page and a second time to display this page. To randomly select a page, +we use `shuf` from the GNU coreutils: + +```bash +tldr --quiet $(tldr --quiet --list | shuf -n1) +``` + +You can also add the above command to your `.bashrc` (or similar shell +configuration file) to display a random page every time you start a new shell +session. + +## Displaying all pages with their summary + +If you want to extend the output of `tldr --list` with the first line summary of +each page, you can run the following Python script: + +```python +#!/usr/bin/env python3 + +import subprocess + +commands = subprocess.run( + ["tldr", "--quiet", "--list"], + capture_output=True, + encoding="utf-8", +).stdout.splitlines() + +for command in commands: + output = subprocess.run( + ["tldr", "--quiet", command], + capture_output=True, + encoding="utf-8", + ).stdout + description = output.lstrip().split("\n\n")[0] + description = " ".join(description.split()) + print(f"{command} => {description}") +``` + +Note that there are a lot of pages and the script will run Tealdeer once for +every page, so the script may take a couple of seconds to finish. + +## Extending this chapter + +If you have an interesting setup with Tealdeer, feel free to share your +configuration on [our Github repository](https://github.com/dbrgn/tealdeer). From efbdebb4261aef8f6d5e26c27070550ef5ac60af Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sat, 21 Oct 2023 14:51:16 +0200 Subject: [PATCH 099/196] Update Github actions badge (#346) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb38ea6..2203b40 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,6 @@ Thanks to @severen for coming up with the name "tealdeer"! [github-actions]: https://github.com/dbrgn/tealdeer/actions?query=branch%3Amain -[github-actions-badge]: https://github.com/dbrgn/tealdeer/workflows/CI/badge.svg +[github-actions-badge]: https://github.com/dbrgn/tealdeer/actions/workflows/ci.yml/badge.svg?branch=main [crates-io]: https://crates.io/crates/tealdeer [crates-io-badge]: https://img.shields.io/crates/v/tealdeer.svg From 5bdcd6ae9c71caae12b6a3b63e9dc5b8cffb15b5 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Tue, 21 Nov 2023 19:34:22 +0800 Subject: [PATCH 100/196] Update Arch Linux package URL in installing.md (#348) The old URL returns 404 now. --- docs/src/installing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/installing.md b/docs/src/installing.md index 1163a14..9d60898 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -14,7 +14,7 @@ autocompletions](#autocompletion). Tealdeer has been added to a few package managers: -- Arch Linux: [`tealdeer`](https://archlinux.org/packages/community/x86_64/tealdeer/) +- Arch Linux: [`tealdeer`](https://archlinux.org/packages/extra/x86_64/tealdeer/) - Debian: [`tealdeer`](https://tracker.debian.org/tealdeer) - Fedora: [`tealdeer`](https://src.fedoraproject.org/rpms/rust-tealdeer) - FreeBSD: [`sysutils/tealdeer`](https://www.freshports.org/sysutils/tealdeer/) From d04e671c46434813a22d26b9f2f5adb166eaf31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20Fr=C3=B6hlich?= Date: Wed, 17 Jan 2024 23:30:03 +0100 Subject: [PATCH 101/196] Add release build target "linux-aarch64-musl" for platform "linux/arm64" (#351) --- .github/workflows/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3795fc3..52aadc6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,6 +54,8 @@ jobs: include: - arch: "x86_64" libc: "musl" + - arch: "aarch64" + libc: "musl" - arch: "i686" libc: "musl" - arch: "armv7" @@ -116,6 +118,7 @@ jobs: matrix: target: - linux-x86_64-musl + - linux-aarch64-musl - linux-i686-musl - linux-armv7-musleabihf - linux-arm-musleabi From 2e731d7d17b33f917b58587eacf552c44c54e80d Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 11 Feb 2024 15:20:11 +0100 Subject: [PATCH 102/196] Bump MSRV to 1.64 (#352) --- .github/workflows/ci.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bb9bf4..017a390 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - toolchain: [stable, 1.62.1] + toolchain: [stable, 1.64.0] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 diff --git a/Cargo.toml b/Cargo.toml index 2953457..5f9d019 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" version = "1.6.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] -rust-version = "1.62" +rust-version = "1.64" edition = "2021" [[bin]] From ad69985e42418f609600b32a925e256749580389 Mon Sep 17 00:00:00 2001 From: Zacchary Dempsey-Plante Date: Sun, 11 Feb 2024 15:58:06 -0500 Subject: [PATCH 103/196] Update the Nix package link in the documentation (#353) --- docs/src/installing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/installing.md b/docs/src/installing.md index 9d60898..5e51afa 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -22,7 +22,7 @@ Tealdeer has been added to a few package managers: - Homebrew: [`tealdeer`](https://formulae.brew.sh/formula/tealdeer) - MacPorts: [`tealdeer`](https://ports.macports.org/port/tealdeer/) - NetBSD: [`sysutils/tealdeer`](https://pkgsrc.se/sysutils/tealdeer) -- Nix: [`tealdeer`](https://nixos.org/nixos/packages.html#tealdeer) +- Nix: [`tealdeer`](https://search.nixos.org/packages?query=tealdeer) - openSUSE: [`tealdeer`](https://software.opensuse.org/package/tealdeer?search_term=tealdeer) - Scoop: [`tealdeer`](https://github.com/ScoopInstaller/Main/blob/master/bucket/tealdeer.json) - Solus: [`tealdeer`](https://packages.getsol.us/shannon/t/tealdeer/) From 17c08f026180204a47d7a1914c36de61e94ff991 Mon Sep 17 00:00:00 2001 From: Zacchary Dempsey-Plante Date: Thu, 15 Feb 2024 14:27:56 -0500 Subject: [PATCH 104/196] Change custom page files to use a `.md` extension (#322) * Change custom page files to use a `.md` extension. * Add a breaking change warning to the documentation for the usage of custom pages. * Add a temporary check for old custom pages to assist in the migration to the new naming convention. Co-authored-by: Danilo Bargen --- RELEASING.md | 3 + docs/src/usage_custom_pages.md | 23 ++++-- src/cache.rs | 75 ++++++++++++++++--- src/main.rs | 2 +- ...inkscape-v2.patch => inkscape-v2.patch.md} | 0 tests/lib.rs | 20 ++--- 6 files changed, 94 insertions(+), 29 deletions(-) rename tests/{inkscape-v2.patch => inkscape-v2.patch.md} (100%) diff --git a/RELEASING.md b/RELEASING.md index 6eb868c..16cb4e2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -14,6 +14,9 @@ Update version numbers: $ vim Cargo.toml $ cargo update -p tealdeer +For release 1.7.0: Remove this note and uncomment warning in +`docs/src/usage_custom_pages.md`. + Update docs: $ cargo run -- --help > docs/src/usage.txt diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md index d3d1e81..87344d7 100644 --- a/docs/src/usage_custom_pages.md +++ b/docs/src/usage_custom_pages.md @@ -1,5 +1,16 @@ # Custom Pages and Patches + + Tealdeer allows creating new custom pages, overriding existing pages as well as extending existing pages. @@ -15,28 +26,28 @@ file](config_directories.html). To document internal command line tools, or if you want to replace an existing tldr page with one that's better suited for you, place a file with the name -`.page` in the custom pages directory. When calling `tldr `, +`.page.md` in the custom pages directory. When calling `tldr `, your custom page will be shown instead of the upstream version in the cache. Path: - $CUSTOM_PAGES_DIR/.page + $CUSTOM_PAGES_DIR/.page.md Example: - ~/.local/share/tealdeer/pages/ufw.page + ~/.local/share/tealdeer/pages/ufw.page.md ## Custom Patches Sometimes you don't want to fully replace an existing upstream page, but just want to extend it with your own examples that you frequently need. In this -case, use a file called `.patch`, it will be appended to existing +case, use a file called `.patch.md`, it will be appended to existing pages. Path: - $CUSTOM_PAGES_DIR/.patch + $CUSTOM_PAGES_DIR/.patch.md Example: - ~/.local/share/tealdeer/pages/ufw.patch + ~/.local/share/tealdeer/pages/ufw.patch.md diff --git a/src/cache.rs b/src/cache.rs index aa64f5e..48be75e 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -13,7 +13,7 @@ use reqwest::{blocking::Client, Proxy}; use walkdir::{DirEntry, WalkDir}; use zip::ZipArchive; -use crate::types::PlatformType; +use crate::{types::PlatformType, utils::print_warning}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; @@ -21,6 +21,7 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; #[derive(Debug)] pub struct Cache { cache_dir: PathBuf, + enable_styles: bool, } #[derive(Debug)] @@ -85,12 +86,13 @@ pub enum CacheFreshness { } impl Cache { - pub fn new

(cache_dir: P) -> Self + pub fn new

(cache_dir: P, enable_styles: bool) -> Self where P: Into, { Self { cache_dir: cache_dir.into(), + enable_styles, } } @@ -232,7 +234,7 @@ impl Cache { .find(|path| path.exists() && path.is_file()) } - /// Look up custom patch (.patch). If it exists, store it in a variable. + /// Look up custom patch (.patch.md). If it exists, store it in a variable. fn find_patch(patch_name: &str, custom_pages_dir: Option<&Path>) -> Option { custom_pages_dir .map(|custom_dir| custom_dir.join(patch_name)) @@ -248,8 +250,8 @@ impl Cache { platforms: &[PlatformType], ) -> Option { let page_filename = format!("{name}.md"); - let patch_filename = format!("{name}.patch"); - let custom_filename = format!("{name}.page"); + let patch_filename = format!("{name}.patch.md"); + let custom_filename = format!("{name}.page.md"); // Determine directory paths let pages_dir = self.pages_dir(); @@ -264,8 +266,11 @@ impl Cache { }) .collect(); - // Look up custom page (.page). If it exists, return it directly + // Look up custom page (.page.md). If it exists, return it directly if let Some(config_dir) = custom_pages_dir { + // TODO: Remove this check 1 year after version 1.7.0 was released + self.check_for_old_custom_pages(config_dir); + let custom_page = config_dir.join(custom_filename); if custom_page.exists() && custom_page.is_file() { return Some(PageLookupResult::with_page(custom_page)); @@ -326,6 +331,15 @@ impl Cache { .map(str::to_string) }; + let to_stem_custom = |entry: DirEntry| -> Option { + entry + .path() + .file_name() + .and_then(OsStr::to_str) + .and_then(|s| s.strip_suffix(".page.md")) + .map(str::to_string) + }; + // Recursively walk through common and (if applicable) platform specific directory let mut pages = WalkDir::new(platforms_dir) .min_depth(1) // Skip root directory @@ -344,8 +358,12 @@ impl Cache { if let Some(custom_pages_dir) = custom_pages_dir { let is_page = |entry: &DirEntry| -> bool { - let extension = entry.path().extension().unwrap_or_default(); - entry.file_type().is_file() && extension == "page" + entry.file_type().is_file() + && entry + .path() + .file_name() + .and_then(OsStr::to_str) + .map_or(false, |file_name| file_name.ends_with(".page.md")) }; let custom_pages = WalkDir::new(custom_pages_dir) @@ -354,7 +372,7 @@ impl Cache { .into_iter() .filter_entry(is_page) .filter_map(Result::ok) - .filter_map(to_stem); + .filter_map(to_stem_custom); pages.extend(custom_pages); } @@ -395,6 +413,39 @@ impl Cache { Ok(true) } + + /// Check for old custom pages (without .md suffix) and print a warning. + fn check_for_old_custom_pages(&self, custom_pages_dir: &Path) { + let old_custom_pages_exist = WalkDir::new(custom_pages_dir) + .min_depth(1) + .max_depth(1) + .into_iter() + .filter_entry(|entry| entry.file_type().is_file()) + .any(|entry| { + if let Ok(entry) = entry { + let extension = entry.path().extension(); + if let Some(extension) = extension { + extension == "page" || extension == "patch" + } else { + false + } + } else { + false + } + }); + if old_custom_pages_exist { + print_warning( + self.enable_styles, + &format!( + "Custom pages using the old naming convention were found in {}.\n\ + Please rename them to follow the new convention:\n\ + - `.page` → `.page.md`\n\ + - `.patch` → `.patch.md`", + custom_pages_dir.display() + ), + ); + } + } } /// Unit Tests for cache module @@ -411,8 +462,8 @@ mod tests { fn test_reader_with_patch() { // Write test files let dir = tempfile::tempdir().unwrap(); - let page_path = dir.path().join("test.page"); - let patch_path = dir.path().join("test.patch"); + let page_path = dir.path().join("test.page.md"); + let patch_path = dir.path().join("test.patch.md"); { let mut f1 = File::create(&page_path).unwrap(); f1.write_all(b"Hello\n").unwrap(); @@ -435,7 +486,7 @@ mod tests { fn test_reader_without_patch() { // Write test file let dir = tempfile::tempdir().unwrap(); - let page_path = dir.path().join("test.page"); + let page_path = dir.path().join("test.page.md"); { let mut f = File::create(&page_path).unwrap(); f.write_all(b"Hello\n").unwrap(); diff --git a/src/main.rs b/src/main.rs index 15110e6..66da7a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -301,7 +301,7 @@ fn main() { } // Instantiate cache. This will not yet create the cache directory! - let cache = Cache::new(&config.directories.cache_dir.path); + let cache = Cache::new(&config.directories.cache_dir.path, enable_styles); // Clear cache, pass through if args.clear_cache { diff --git a/tests/inkscape-v2.patch b/tests/inkscape-v2.patch.md similarity index 100% rename from tests/inkscape-v2.patch rename to tests/inkscape-v2.patch.md diff --git a/tests/lib.rs b/tests/lib.rs index 0afac46..fa8d19c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -84,7 +84,7 @@ impl TestEnv { fn add_page_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(dir.join(format!("{name}.page"))).unwrap(); + let mut file = File::create(dir.join(format!("{name}.page.md"))).unwrap(); file.write_all(contents.as_bytes()).unwrap(); } @@ -92,7 +92,7 @@ impl TestEnv { fn add_patch_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(dir.join(format!("{name}.patch"))).unwrap(); + let mut file = File::create(dir.join(format!("{name}.patch.md"))).unwrap(); file.write_all(contents.as_bytes()).unwrap(); } @@ -798,7 +798,7 @@ fn test_autoupdate_cache() { check_cache_updated(false); } -/// End-end test to ensure .page files overwrite pages in cache_dir +/// End-end test to ensure .page.md files overwrite pages in cache_dir #[test] fn test_custom_page_overwrites() { let testenv = TestEnv::new(); @@ -811,7 +811,7 @@ fn test_custom_page_overwrites() { // Add file that should be ignored to the cache dir testenv.add_entry("inkscape-v2", ""); - // Add .page file to custome_pages_dir + // Add .page.md file to custom_pages_dir testenv.add_page_entry("inkscape-v2", include_str!("inkscape-v2.md")); // Load expected output @@ -825,7 +825,7 @@ fn test_custom_page_overwrites() { .stdout(diff(expected)); } -/// End-End test to ensure that .patch files are appended to pages in the cache_dir +/// End-End test to ensure that .patch.md files are appended to pages in the cache_dir #[test] fn test_custom_patch_appends_to_common() { let testenv = TestEnv::new(); @@ -838,8 +838,8 @@ fn test_custom_patch_appends_to_common() { // Add page to the cache dir testenv.add_entry("inkscape-v2", include_str!("inkscape-v2.md")); - // Add .page file to custome_pages_dir - testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch")); + // Add .page.md file to custom_pages_dir + testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch.md")); // Load expected output let expected = include_str!("inkscape-patched-no-color.expected"); @@ -852,7 +852,7 @@ fn test_custom_patch_appends_to_common() { .stdout(diff(expected)); } -/// End-End test to ensure that .patch files are not appended to .page files in the custom_pages_dir +/// End-End test to ensure that .patch.md files are not appended to .page.md files in the custom_pages_dir /// Maybe this interaction should change but I put this test here for the coverage #[test] fn test_custom_patch_does_not_append_to_custom() { @@ -868,8 +868,8 @@ fn test_custom_patch_does_not_append_to_custom() { // Add page to the cache dir testenv.add_page_entry("inkscape-v2", include_str!("inkscape-v2.md")); - // Add .page file to custome_pages_dir - testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch")); + // Add .page.md file to custom_pages_dir + testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch.md")); // Load expected output let expected = include_str!("inkscape-default-no-color.expected"); From c8f2408373f3aeb329e1d4aea8010a400d22d579 Mon Sep 17 00:00:00 2001 From: Linus Walker <85013114+Walker-00@users.noreply.github.com> Date: Mon, 4 Mar 2024 00:05:09 +0630 Subject: [PATCH 105/196] Performance optimization with cargo flags (#355) --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 5f9d019..a49d924 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,4 +62,7 @@ webpki-roots = ["reqwest/rustls-tls-webpki-roots"] native-tls = ["reqwest/native-tls"] [profile.release] +strip = true +opt-level = 3 lto = true +codegen-units = 1 From ee6d2418f1b0b049d1b8b224b554af77dc9cc65e Mon Sep 17 00:00:00 2001 From: "K.B.Dharun Krishna" Date: Wed, 10 Apr 2024 19:35:51 +0530 Subject: [PATCH 106/196] Add BSD platform support and update workflows (#354) --- .github/dependabot.yml | 6 ++++++ .github/workflows/ci.yml | 8 ++++---- .github/workflows/gh-pages.yml | 2 +- .github/workflows/release.yml | 22 +++++++++++----------- completion/bash_tealdeer | 2 +- completion/fish_tealdeer | 2 +- completion/zsh_tealdeer | 3 +++ docs/src/usage.txt | 2 +- src/cache.rs | 3 +++ src/cli.rs | 2 +- src/types.rs | 34 ++++++++++++++++++++++++++-------- 11 files changed, 58 insertions(+), 28 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8ac6b8c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 017a390..d8e33b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: toolchain: [stable, 1.64.0] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} @@ -32,7 +32,7 @@ jobs: name: run clippy lints runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -44,7 +44,7 @@ jobs: name: run rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -56,7 +56,7 @@ jobs: name: build docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 with: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index dafba80..f4370ab 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -9,7 +9,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52aadc6..a3ae0fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ jobs: create-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Create release for tag if: startsWith(github.ref, 'refs/tags/') run: | @@ -23,7 +23,7 @@ jobs: matrix: target: ["bash", "fish", "zsh"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | @@ -39,7 +39,7 @@ jobs: matrix: target: ["MIT", "APACHE"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | @@ -65,14 +65,14 @@ jobs: - arch: "arm" libc: "musleabihf" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - name: Build in Docker run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" @@ -80,14 +80,14 @@ jobs: build-macos: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: toolchain: stable - name: Build run: cargo build --release --target x86_64-apple-darwin --no-default-features --features webpki-roots - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: "tealdeer-macos-x86_64" path: "target/x86_64-apple-darwin/release/tldr" @@ -95,14 +95,14 @@ jobs: build-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: toolchain: stable - name: Build run: cargo build --release --target x86_64-pc-windows-msvc - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: "tealdeer-windows-x86_64-msvc" path: "target/x86_64-pc-windows-msvc/release/tldr.exe" @@ -126,8 +126,8 @@ jobs: - macos-x86_64 - windows-x86_64-msvc steps: - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | diff --git a/completion/bash_tealdeer b/completion/bash_tealdeer index 1fc0655..d5420b6 100644 --- a/completion/bash_tealdeer +++ b/completion/bash_tealdeer @@ -14,7 +14,7 @@ _tealdeer() return ;; -p|--platform) - COMPREPLY=( $(compgen -W 'linux macos sunos windows android' -- "${cur}") ) + COMPREPLY=( $(compgen -W 'linux macos sunos windows android freebsd netbsd openbsd' -- "${cur}") ) return ;; --color) diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index dcb41c3..eb35e87 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -7,7 +7,7 @@ complete -c tldr -s h -l help -d 'Print the help message.' -f complete -c tldr -s v -l version -d 'Show version information.' -f complete -c tldr -s l -l list -d 'List all commands in the cache.' -f complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r -complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows android' +complete -c tldr -s p -l platform -d 'Override the operating system.' -xa 'linux macos sunos windows android freebsd netbsd openbsd' complete -c tldr -s L -l language -d 'Override the language' -x complete -c tldr -s u -l update -d 'Update the local cache.' -f complete -c tldr -l no-auto-update -d 'If auto update is configured, disable it for this run.' -f diff --git a/completion/zsh_tealdeer b/completion/zsh_tealdeer index 0d08745..fbab749 100644 --- a/completion/zsh_tealdeer +++ b/completion/zsh_tealdeer @@ -21,6 +21,9 @@ _tealdeer() { sunos windows android + freebsd + netbsd + openbsd ))' "($I -L --language)"{-L,--language}"[Override the language settings]:lang" "($I -u --update)"{-u,--update}"[Update the local cache]" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 74b3b2e..5ab6fd9 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -12,7 +12,7 @@ OPTIONS: -l, --list List all commands in the cache -f, --render Render a specific markdown file -p, --platform Override the operating system [possible values: linux, macos, - windows, sunos, osx, android] + windows, sunos, osx, android, freebsd, netbsd, openbsd] -L, --language Override the language -u, --update Update the local cache --no-auto-update If auto update is configured, disable it for this run diff --git a/src/cache.rs b/src/cache.rs index 48be75e..8fccb62 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -218,6 +218,9 @@ impl Cache { PlatformType::SunOs => "sunos", PlatformType::Windows => "windows", PlatformType::Android => "android", + PlatformType::FreeBsd => "freebsd", + PlatformType::NetBsd => "netbsd", + PlatformType::OpenBsd => "openbsd", } } diff --git a/src/cli.rs b/src/cli.rs index ed71ef8..3825245 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -40,7 +40,7 @@ pub(crate) struct Args { short = 'p', long = "platform", action = ArgAction::Append, - possible_values = ["linux", "macos", "windows", "sunos", "osx", "android"], + possible_values = ["linux", "macos", "windows", "sunos", "osx", "android", "freebsd", "netbsd", "openbsd"], )] pub platforms: Option>, diff --git a/src/types.rs b/src/types.rs index f3318a9..2de2d2b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -14,6 +14,9 @@ pub enum PlatformType { SunOs, Windows, Android, + FreeBsd, + NetBsd, + OpenBsd, } impl fmt::Display for PlatformType { @@ -24,6 +27,9 @@ impl fmt::Display for PlatformType { Self::SunOs => write!(f, "SunOS"), Self::Windows => write!(f, "Windows"), Self::Android => write!(f, "Android"), + Self::FreeBsd => write!(f, "FreeBSD"), + Self::NetBsd => write!(f, "NetBSD"), + Self::OpenBsd => write!(f, "OpenBSD"), } } } @@ -38,8 +44,11 @@ impl str::FromStr for PlatformType { "sunos" => Ok(Self::SunOs), "windows" => Ok(Self::Windows), "android" => Ok(Self::Android), + "freebsd" => Ok(Self::FreeBsd), + "netbsd" => Ok(Self::NetBsd), + "openbsd" => Ok(Self::OpenBsd), other => Err(anyhow!( - "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows, android", + "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows, android, freebsd, netbsd, openbsd", other )), } @@ -52,13 +61,7 @@ impl PlatformType { Self::Linux } - #[cfg(any( - target_os = "macos", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "dragonfly" - ))] + #[cfg(any(target_os = "macos", target_os = "dragonfly"))] pub fn current() -> Self { Self::OsX } @@ -73,6 +76,21 @@ impl PlatformType { Self::Android } + #[cfg(any(target_os = "freebsd"))] + pub fn current() -> Self { + Self::FreeBsd + } + + #[cfg(any(target_os = "netbsd"))] + pub fn current() -> Self { + Self::NetBsd + } + + #[cfg(any(target_os = "openbsd"))] + pub fn current() -> Self { + Self::OpenBsd + } + #[cfg(not(any( target_os = "linux", target_os = "macos", From 7633e465419a9fa5cc87e5e25bbdf06f7d1a7aca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:50:44 +0200 Subject: [PATCH 107/196] Bump peaceiris/actions-gh-pages from 3 to 4 (#359) Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 3 to 4. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f4370ab..89010b4 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -19,7 +19,7 @@ jobs: - run: cd docs && mdbook build - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/book From 9957dcea74c6f708132e6a3af51dc0f909411000 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:51:53 +0200 Subject: [PATCH 108/196] Bump peaceiris/actions-mdbook from 1 to 2 (#360) Bumps [peaceiris/actions-mdbook](https://github.com/peaceiris/actions-mdbook) from 1 to 2. - [Release notes](https://github.com/peaceiris/actions-mdbook/releases) - [Changelog](https://github.com/peaceiris/actions-mdbook/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-mdbook/compare/v1...v2) --- updated-dependencies: - dependency-name: peaceiris/actions-mdbook dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/gh-pages.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8e33b9..b81754f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup mdBook - uses: peaceiris/actions-mdbook@v1 + uses: peaceiris/actions-mdbook@v2 with: mdbook-version: '0.4.4' - name: Setup toolchain diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 89010b4..e965e29 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup mdBook - uses: peaceiris/actions-mdbook@v1 + uses: peaceiris/actions-mdbook@v2 with: mdbook-version: '0.4.4' From 3a1423210544343d430d20804ffa9567d69e73bc Mon Sep 17 00:00:00 2001 From: Adam Henley Date: Fri, 7 Jun 2024 03:17:20 +1200 Subject: [PATCH 109/196] Generate docs only upon release (#362) Signed-off-by: Adam Henley --- .github/workflows/gh-pages.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index e965e29..55d016b 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -2,8 +2,8 @@ name: github pages on: push: - branches: - - main + tags: + - "v*" # push events matching `v` followed by anything, e.g. v1.0, v20.15.10 jobs: deploy: From de1684edb6a50d3fc0b9e2583df51862350a3d68 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 10 Jun 2024 21:33:29 +0200 Subject: [PATCH 110/196] Update to clap v4 --- Cargo.lock | 393 +++++++++++++++++++++++++++++++++++---------- Cargo.toml | 2 +- docs/src/usage.txt | 45 +++--- src/cli.rs | 61 +++---- src/main.rs | 8 +- src/types.rs | 62 +++---- 6 files changed, 387 insertions(+), 184 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 972c24e..13c88ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,55 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.68" @@ -78,6 +127,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "bstr" version = "1.1.0" @@ -128,42 +183,49 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.23" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "indexmap", - "once_cell", - "strsim", - "termcolor", - "textwrap", + "terminal_size", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "combine" @@ -280,6 +342,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -458,9 +530,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -623,10 +695,16 @@ checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ "hermit-abi 0.2.6", "io-lifetimes", - "rustix", + "rustix 0.36.5", "windows-sys 0.42.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -679,9 +757,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linux-raw-sys" @@ -689,6 +767,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.17" @@ -792,7 +876,7 @@ version = "0.10.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -809,7 +893,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -831,19 +915,13 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "pager" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2599211a5c97fbbb1061d3dc751fa15f404927e4846e07c643287d6d1f462880" dependencies = [ - "errno", + "errno 0.2.8", "libc", ] @@ -901,44 +979,20 @@ dependencies = [ "termtree", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -949,7 +1003,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1059,14 +1113,27 @@ version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" dependencies = [ - "bitflags", - "errno", + "bitflags 1.3.2", + "errno 0.2.8", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.1.4", "windows-sys 0.42.0", ] +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.4.2", + "errno 0.3.9", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" version = "0.20.7" @@ -1141,7 +1208,7 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1175,7 +1242,7 @@ checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1226,12 +1293,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "syn" version = "1.0.107" @@ -1243,6 +1304,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tealdeer" version = "1.6.1" @@ -1291,18 +1363,22 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.34", + "windows-sys 0.48.0", +] + [[package]] name = "termtree" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.38" @@ -1320,7 +1396,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1469,18 +1545,18 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "wait-timeout" version = "0.2.0" @@ -1538,7 +1614,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -1572,7 +1648,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1662,21 +1738,82 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.0", "windows_aarch64_msvc 0.42.0", "windows_i686_gnu 0.42.0", "windows_i686_msvc 0.42.0", "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.0", "windows_x86_64_msvc 0.42.0", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -1689,6 +1826,18 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -1701,6 +1850,24 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -1713,6 +1880,18 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -1725,12 +1904,36 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -1743,6 +1946,18 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index a49d924..a1b61b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ path = "src/main.rs" anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" -clap = { version = "3", features = ["std", "derive", "suggestions", "color"], default-features = false } +clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.10", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking"], default-features = false } diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 5ab6fd9..7e823c4 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,30 +1,27 @@ -tealdeer 1.6.1 +tealdeer 1.6.1: A fast TLDR client Danilo Bargen , Niklas Mohrin -A fast TLDR client -USAGE: - tldr [OPTIONS] [COMMAND]... +Usage: tldr [OPTIONS] [COMMAND]... -ARGS: - ... The command to show (e.g. `tar` or `git log`) +Arguments: + [COMMAND]... The command to show (e.g. `tar` or `git log`) -OPTIONS: - -l, --list List all commands in the cache - -f, --render Render a specific markdown file - -p, --platform Override the operating system [possible values: linux, macos, - windows, sunos, osx, android, freebsd, netbsd, openbsd] - -L, --language Override the language - -u, --update Update the local cache - --no-auto-update If auto update is configured, disable it for this run - -c, --clear-cache Clear the local cache - --pager Use a pager to page output - -r, --raw Display the raw markdown instead of rendering it - -q, --quiet Suppress informational messages - --show-paths Show file and directory paths used by tealdeer - --seed-config Create a basic config - --color Control whether to use color [possible values: always, auto, - never] - -v, --version Print the version - -h, --help Print help information +Options: + -l, --list List all commands in the cache + -f, --render Render a specific markdown file + -p, --platform Override the operating system [possible values: linux, macos, sunos, + windows, android, freebsd, netbsd, openbsd] + -L, --language Override the language + -u, --update Update the local cache + --no-auto-update If auto update is configured, disable it for this run + -c, --clear-cache Clear the local cache + --pager Use a pager to page output + -r, --raw Display the raw markdown instead of rendering it + -q, --quiet Suppress informational messages + --show-paths Show file and directory paths used by tealdeer + --seed-config Create a basic config + --color Control whether to use color [possible values: always, auto, never] + -v, --version Print the version + -h, --help Print help To view the user documentation, please visit https://dbrgn.github.io/tealdeer/. diff --git a/src/cli.rs b/src/cli.rs index 3825245..fd6c987 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,32 +2,38 @@ use std::path::PathBuf; -use clap::{AppSettings, ArgAction, ArgGroup, Parser}; +use clap::{arg, builder::ArgAction, command, ArgGroup, Parser}; use crate::types::{ColorOptions, PlatformType}; // Note: flag names are specified explicitly in clap attributes // to improve readability and allow contributors to grep names like "clear-cache" #[derive(Parser, Debug)] -#[clap(about = "A fast TLDR client", author, version)] -#[clap( - after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/." +#[command( + about = "A fast TLDR client", + version, + disable_version_flag = true, + author, + help_template = "{before-help}{name} {version}: {about-with-newline}{author-with-newline} +{usage-heading} {usage} + +{all-args}{after-help}", + after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/.", + arg_required_else_help = true, + help_expected = true, + group = ArgGroup::new("command_or_file").args(&["command", "render"]), )] -#[clap(setting = AppSettings::DeriveDisplayOrder)] -#[clap(arg_required_else_help(true))] -#[clap(disable_colored_help(true))] -#[clap(group = ArgGroup::new("command_or_file").args(&["command", "render"]))] -pub(crate) struct Args { +pub(crate) struct Cli { /// The command to show (e.g. `tar` or `git log`) - #[clap(min_values = 1)] + #[arg(num_args(1..))] pub command: Vec, /// List all commands in the cache - #[clap(short = 'l', long = "list")] + #[arg(short = 'l', long = "list")] pub list: bool, /// Render a specific markdown file - #[clap( + #[arg( short = 'f', long = "render", value_name = "FILE", @@ -36,61 +42,56 @@ pub(crate) struct Args { pub render: Option, /// Override the operating system - #[clap( + #[arg( short = 'p', long = "platform", action = ArgAction::Append, - possible_values = ["linux", "macos", "windows", "sunos", "osx", "android", "freebsd", "netbsd", "openbsd"], )] pub platforms: Option>, /// Override the language - #[clap(short = 'L', long = "language")] + #[arg(short = 'L', long = "language")] pub language: Option, /// Update the local cache - #[clap(short = 'u', long = "update")] + #[arg(short = 'u', long = "update")] pub update: bool, /// If auto update is configured, disable it for this run - #[clap(long = "no-auto-update", requires = "command_or_file")] + #[arg(long = "no-auto-update", requires = "command_or_file")] pub no_auto_update: bool, /// Clear the local cache - #[clap(short = 'c', long = "clear-cache")] + #[arg(short = 'c', long = "clear-cache")] pub clear_cache: bool, /// Use a pager to page output - #[clap(long = "pager", requires = "command_or_file")] + #[arg(long = "pager", requires = "command_or_file")] pub pager: bool, /// Display the raw markdown instead of rendering it - #[clap(short = 'r', long = "--raw", requires = "command_or_file")] + #[arg(short = 'r', long = "raw", requires = "command_or_file")] pub raw: bool, /// Suppress informational messages - #[clap(short = 'q', long = "quiet")] + #[arg(short = 'q', long = "quiet")] pub quiet: bool, /// Show file and directory paths used by tealdeer - #[clap(long = "show-paths")] + #[arg(long = "show-paths")] pub show_paths: bool, /// Create a basic config - #[clap(long = "seed-config")] + #[arg(long = "seed-config")] pub seed_config: bool, /// Control whether to use color - #[clap( - long = "color", - value_name = "WHEN", - possible_values = ["always", "auto", "never"] - )] + #[arg(long = "color", value_name = "WHEN")] pub color: Option, /// Print the version // Note: We override the version flag because clap uses `-V` by default, // while TLDR specification requires `-v` to be used. - #[clap(short = 'v', long = "version")] - pub version: bool, + #[arg(short = 'v', long = "version", action = ArgAction::Version)] + pub version: (), } diff --git a/src/main.rs b/src/main.rs index 66da7a1..4de0038 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,7 +48,7 @@ mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, - cli::Args, + cli::Cli, config::{get_config_dir, get_config_path, make_default_config, Config, PathWithSource}, extensions::Dedup, output::print_page, @@ -65,7 +65,7 @@ const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; /// The cache should be updated if it was explicitly requested, /// or if an automatic update is due and allowed. -fn should_update_cache(cache: &Cache, args: &Args, config: &Config) -> bool { +fn should_update_cache(cache: &Cache, args: &Cli, config: &Config) -> bool { args.update || (!args.no_auto_update && config.updates.auto_update @@ -81,7 +81,7 @@ enum CheckCacheResult { } /// Check the cache for freshness. If it's stale or missing, show a warning. -fn check_cache(cache: &Cache, args: &Args, enable_styles: bool) -> CheckCacheResult { +fn check_cache(cache: &Cache, args: &Cli, enable_styles: bool) -> CheckCacheResult { match cache.freshness() { CacheFreshness::Fresh => CheckCacheResult::CacheFound, CacheFreshness::Stale(_) if args.quiet => CheckCacheResult::CacheFound, @@ -243,7 +243,7 @@ fn main() { init_log(); // Parse arguments - let args = Args::parse(); + let args = Cli::parse(); // Determine the usage of styles #[cfg(target_os = "windows")] diff --git a/src/types.rs b/src/types.rs index 2de2d2b..06a8e64 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,7 +2,6 @@ use std::{fmt, str}; -use anyhow::{anyhow, Result}; use serde_derive::{Deserialize, Serialize}; #[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)] @@ -11,8 +10,8 @@ use serde_derive::{Deserialize, Serialize}; pub enum PlatformType { Linux, OsX, - SunOs, Windows, + SunOs, Android, FreeBsd, NetBsd, @@ -24,8 +23,8 @@ impl fmt::Display for PlatformType { match self { Self::Linux => write!(f, "Linux"), Self::OsX => write!(f, "macOS / BSD"), - Self::SunOs => write!(f, "SunOS"), Self::Windows => write!(f, "Windows"), + Self::SunOs => write!(f, "SunOS"), Self::Android => write!(f, "Android"), Self::FreeBsd => write!(f, "FreeBSD"), Self::NetBsd => write!(f, "NetBSD"), @@ -34,23 +33,30 @@ impl fmt::Display for PlatformType { } } -impl str::FromStr for PlatformType { - type Err = anyhow::Error; +impl clap::ValueEnum for PlatformType { + fn value_variants<'a>() -> &'a [Self] { + &[ + Self::Linux, + Self::OsX, + Self::SunOs, + Self::Windows, + Self::Android, + Self::FreeBsd, + Self::NetBsd, + Self::OpenBsd, + ] + } - fn from_str(s: &str) -> Result { - match s { - "linux" => Ok(Self::Linux), - "osx" | "macos" => Ok(Self::OsX), - "sunos" => Ok(Self::SunOs), - "windows" => Ok(Self::Windows), - "android" => Ok(Self::Android), - "freebsd" => Ok(Self::FreeBsd), - "netbsd" => Ok(Self::NetBsd), - "openbsd" => Ok(Self::OpenBsd), - other => Err(anyhow!( - "Unknown OS: {}. Possible values: linux, macos, osx, sunos, windows, android, freebsd, netbsd, openbsd", - other - )), + fn to_possible_value<'a>(&self) -> Option { + match self { + Self::Linux => Some(clap::builder::PossibleValue::new("linux")), + Self::OsX => Some(clap::builder::PossibleValue::new("macos").alias("osx")), + Self::Windows => Some(clap::builder::PossibleValue::new("windows")), + Self::SunOs => Some(clap::builder::PossibleValue::new("sunos")), + Self::Android => Some(clap::builder::PossibleValue::new("android")), + Self::FreeBsd => Some(clap::builder::PossibleValue::new("freebsd")), + Self::NetBsd => Some(clap::builder::PossibleValue::new("netbsd")), + Self::OpenBsd => Some(clap::builder::PossibleValue::new("openbsd")), } } } @@ -106,7 +112,7 @@ impl PlatformType { } } -#[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize)] +#[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize, clap::ValueEnum)] #[serde(rename_all = "lowercase")] pub enum ColorOptions { Always, @@ -114,22 +120,6 @@ pub enum ColorOptions { Never, } -impl str::FromStr for ColorOptions { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - "always" => Ok(Self::Always), - "auto" => Ok(Self::Auto), - "never" => Ok(Self::Never), - other => Err(anyhow!( - "Unknown color option: {}. Possible values: always, auto, never", - other - )), - } - } -} - impl Default for ColorOptions { fn default() -> Self { Self::Auto From 86293c8723710355c4b341d4a74c5f04216fc429 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 10 Jun 2024 23:25:18 +0200 Subject: [PATCH 111/196] Bump MSRV to 1.75 --- .github/workflows/ci.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b81754f..6b32aa9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - toolchain: [stable, 1.64.0] + toolchain: [stable, 1.75.0] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 diff --git a/Cargo.toml b/Cargo.toml index a1b61b5..21656ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/dbrgn/tealdeer/" documentation = "https://dbrgn.github.io/tealdeer/" version = "1.6.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] -rust-version = "1.64" +rust-version = "1.75" edition = "2021" [[bin]] From 64f3fbbbc688da3ac4700ca80552efa67fc121c8 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 10 Jun 2024 23:28:22 +0200 Subject: [PATCH 112/196] Apply clippy suggestions --- src/cache.rs | 5 ++--- src/types.rs | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 8fccb62..f5e604c 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -314,9 +314,8 @@ impl Cache { // 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, + let Some(file_name) = entry.file_name().to_str() else { + return false; }; if file_type.is_dir() { return file_name == "common" || platform_dirs.contains(&file_name); diff --git a/src/types.rs b/src/types.rs index 06a8e64..8a111a6 100644 --- a/src/types.rs +++ b/src/types.rs @@ -82,17 +82,17 @@ impl PlatformType { Self::Android } - #[cfg(any(target_os = "freebsd"))] + #[cfg(target_os = "freebsd")] pub fn current() -> Self { Self::FreeBsd } - #[cfg(any(target_os = "netbsd"))] + #[cfg(target_os = "netbsd")] pub fn current() -> Self { Self::NetBsd } - #[cfg(any(target_os = "openbsd"))] + #[cfg(target_os = "openbsd")] pub fn current() -> Self { Self::OpenBsd } From 64f90a625eeb5cba9cf669bbd68ff9c4305bbfab Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 17 Jun 2024 00:50:41 +0200 Subject: [PATCH 113/196] CI: Create release builds for Apple silicon (ARM) --- .github/workflows/release.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3ae0fc..eda277e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,18 +79,24 @@ jobs: build-macos: runs-on: macos-latest + strategy: + matrix: + include: + - arch: "x86_64" + - arch: "aarch64" steps: - uses: actions/checkout@v4 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: toolchain: stable + targets: "${{ matrix.arch }}-apple-darwin" - name: Build - run: cargo build --release --target x86_64-apple-darwin --no-default-features --features webpki-roots + run: cargo build --release --target ${{ matrix.arch }}-apple-darwin --no-default-features --features webpki-roots - uses: actions/upload-artifact@v4 with: - name: "tealdeer-macos-x86_64" - path: "target/x86_64-apple-darwin/release/tldr" + name: "tealdeer-macos-${{ matrix.arch }}" + path: "target/${{ matrix.arch }}-apple-darwin/release/tldr" build-windows: runs-on: windows-latest @@ -124,6 +130,7 @@ jobs: - linux-arm-musleabi - linux-arm-musleabihf - macos-x86_64 + - macos-aarch64 - windows-x86_64-msvc steps: - uses: actions/checkout@v4 From 706c1408a7139a41e842a9e640bc041559950310 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 17 Jun 2024 01:02:20 +0200 Subject: [PATCH 114/196] CI: Don't publish docs for 0.x test releases --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 55d016b..83a132b 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -3,7 +3,7 @@ name: github pages on: push: tags: - - "v*" # push events matching `v` followed by anything, e.g. v1.0, v20.15.10 + - "v[1-9]*" # push events matching `v` followed by anything larger than 0, e.g. v1.0, v20.15.10 jobs: deploy: From 7620a673061169424ac4c9d27c7e8c385fa1561c Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 17 Jun 2024 01:07:29 +0200 Subject: [PATCH 115/196] CI: Set name for every workflow --- .github/workflows/ci.yml | 3 +-- .github/workflows/gh-pages.yml | 3 +-- .github/workflows/release.yml | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b81754f..aabc3f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,4 @@ +name: CI on: push: branches: @@ -6,8 +7,6 @@ on: schedule: - cron: '30 3 * * 2' -name: CI - jobs: test: name: run tests diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 83a132b..26fff6e 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -1,5 +1,4 @@ -name: github pages - +name: GitHub Pages on: push: tags: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eda277e..2c36ad5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +name: Release on: push: tags: From f3d74850a8a22816a39061137c3bf61148414a5f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 6 Aug 2024 23:46:40 +0200 Subject: [PATCH 116/196] Make clippy happy (#373) --- src/cache.rs | 4 ++-- src/line_iterator.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index f5e604c..a4496ad 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -77,7 +77,7 @@ impl PageLookupResult { } pub enum CacheFreshness { - /// The cache is still fresh (less than MAX_CACHE_AGE old) + /// The cache is still fresh (less than `MAX_CACHE_AGE` old) Fresh, /// The cache is stale and should be updated Stale(Duration), @@ -184,7 +184,7 @@ impl Cache { // Extract archive into pages dir archive - .extract(&self.pages_dir()) + .extract(self.pages_dir()) .context("Could not unpack compressed data")?; Ok(()) diff --git a/src/line_iterator.rs b/src/line_iterator.rs index 75a56bd..2e11378 100644 --- a/src/line_iterator.rs +++ b/src/line_iterator.rs @@ -12,7 +12,7 @@ pub enum TldrFormat { Undecided, /// The original format V1, - /// The new format (see https://github.com/tldr-pages/tldr/pull/958) + /// The new format (see ) V2, } From 65495da5a59f056b3df2affce8d016db08a46309 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 22:54:03 +0200 Subject: [PATCH 117/196] Run cargo update --- Cargo.lock | 1011 +++++++++++++++++++++++++--------------------------- 1 file changed, 482 insertions(+), 529 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13c88ee..e7f99ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -10,18 +19,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -34,33 +43,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -68,15 +77,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app_dirs2" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a8d2d8dbda5fca0a522259fb88e4f55d2b10ad39f5f03adeebf85031eba501" +checksum = "a7e7b35733e3a8c1ccb90385088dd5b6eaa61325cb4d1ad56e683b5224ff352e" dependencies = [ "jni", "ndk-context", @@ -86,13 +95,15 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.7" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3d466004a8b4cb1bc34044240a2fd29d17607e2e3bd613eb44fd48e8100da3" +checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" dependencies = [ + "anstyle", "bstr", "doc-comment", - "predicates", + "libc", + "predicates 3.1.2", "predicates-core", "predicates-tree", "wait-timeout", @@ -111,15 +122,30 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bitflags" @@ -129,45 +155,44 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bstr" -version = "1.1.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "once_cell", "regex-automata", "serde", ] [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.3.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.0.78" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" [[package]] name = "cesu8" @@ -183,9 +208,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.7" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" dependencies = [ "clap_builder", "clap_derive", @@ -193,9 +218,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -205,33 +230,33 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -239,9 +264,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -249,27 +274,24 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "difflib" @@ -277,26 +299,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "doc-comment" version = "0.3.3" @@ -305,24 +307,24 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -331,6 +333,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.2.8" @@ -364,9 +372,9 @@ dependencies = [ [[package]] name = "escargot" -version = "0.5.7" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" +checksum = "c000f23e9d459aef148b7267e02b03b94a0aaacf4ec64c65612f67e02f525fb6" dependencies = [ "log", "once_cell", @@ -376,30 +384,27 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "filetime" -version = "0.2.19" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.42.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -437,51 +442,51 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", @@ -494,9 +499,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -504,10 +509,16 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.15" +name = "gimli" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -524,9 +535,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -545,18 +556,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -565,9 +573,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -576,15 +584,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -594,9 +602,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -618,10 +626,11 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", "rustls", @@ -644,9 +653,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -654,56 +663,36 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ - "autocfg", + "equivalent", "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" -dependencies = [ - "libc", - "windows-sys 0.42.0", -] - [[package]] name = "ipnet" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.2.6", - "io-lifetimes", - "rustix 0.36.5", - "windows-sys 0.42.0", + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -716,22 +705,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" -version = "0.19.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", + "cfg-if", "combine", "jni-sys", "log", "thiserror", "walkdir", + "windows-sys 0.45.0", ] [[package]] @@ -742,19 +733,13 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.155" @@ -762,10 +747,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "linux-raw-sys" -version = "0.1.4" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" @@ -775,53 +765,49 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.17" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.5" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", - "log", "wasi", - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -847,36 +833,35 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "num_cpus" -version = "1.15.0" +name = "object" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ - "hermit-abi 0.2.6", - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.44" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -887,13 +872,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn", ] [[package]] @@ -904,11 +889,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.79" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -927,15 +911,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -945,15 +929,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "predicates" -version = "2.1.4" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54fc5dc63ed3bbf19494623db4f3af16842c0d975818e469022d09e53f0aa05" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", @@ -964,16 +948,27 @@ dependencies = [ ] [[package]] -name = "predicates-core" -version = "1.0.5" +name = "predicates" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.7" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", @@ -981,9 +976,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -999,61 +994,47 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.7.0" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64", "bytes", @@ -1080,6 +1061,8 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -1094,32 +1077,24 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.20" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", + "getrandom", "libc", - "once_cell", "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "rustix" -version = "0.36.5" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" -dependencies = [ - "bitflags 1.3.2", - "errno 0.2.8", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.42.0", -] +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" @@ -1127,30 +1102,30 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno 0.3.9", "libc", - "linux-raw-sys 0.4.14", + "linux-raw-sys", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.20.7" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -1160,18 +1135,28 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64", ] [[package]] -name = "ryu" -version = "1.0.12" +name = "rustls-webpki" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1184,19 +1169,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.52.0", ] [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -1204,11 +1188,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -1217,9 +1201,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -1227,31 +1211,32 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.151" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.151" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn", ] [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1270,34 +1255,34 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "socket2" -version = "0.4.7" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "syn" -version = "1.0.107" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", @@ -1305,14 +1290,30 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.66" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -1329,7 +1330,7 @@ dependencies = [ "filetime", "log", "pager", - "predicates", + "predicates 2.1.5", "reqwest", "serde", "serde_derive", @@ -1342,23 +1343,22 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -1369,73 +1369,71 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.34", + "rustix", "windows-sys 0.48.0", ] [[package]] name = "termtree" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.23.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", - "num_cpus", "pin-project-lite", "socket2", - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -1443,34 +1441,32 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -1483,62 +1479,61 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.3.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -1568,22 +1563,20 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", - "winapi", "winapi-util", ] [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -1595,9 +1588,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1605,24 +1598,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.107", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -1632,9 +1625,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1642,51 +1635,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "winapi" @@ -1706,11 +1686,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1721,30 +1701,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.0", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm 0.42.0", - "windows_x86_64_msvc 0.42.0", + "windows-targets 0.42.2", ] [[package]] @@ -1762,7 +1723,31 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -1782,25 +1767,25 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -1810,21 +1795,15 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -1834,21 +1813,15 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -1858,27 +1831,21 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -1888,21 +1855,15 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -1912,15 +1873,15 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -1930,21 +1891,15 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -1954,27 +1909,25 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] name = "xdg" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6" -dependencies = [ - "dirs", -] +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "yansi" @@ -1984,9 +1937,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zip" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "byteorder", "crc32fast", From 13f2c4c7147c80afe23e838286c3e945ec3b5db7 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 22:54:58 +0200 Subject: [PATCH 118/196] =?UTF-8?q?Upgrade=20env=5Flogger:=200.10=20?= =?UTF-8?q?=E2=86=92=200.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 42 ++++++++++++++++-------------------------- Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7f99ff..cf9c5c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,16 +321,26 @@ dependencies = [ ] [[package]] -name = "env_logger" -version = "0.10.2" +name = "env_filter" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ - "humantime", - "is-terminal", "log", "regex", - "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", ] [[package]] @@ -677,17 +687,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" -[[package]] -name = "is-terminal" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1354,15 +1353,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "terminal_size" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 21656ac..be5d527 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } atty = "0.2" clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } -env_logger = { version = "0.10", optional = true } +env_logger = { version = "0.11", optional = true } log = "0.4" reqwest = { version = "0.11.3", features = ["blocking"], default-features = false } serde = "1.0.21" From 13a3d58c8bb2aca58877733e0fd4ebb88d794b7f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 22:57:32 +0200 Subject: [PATCH 119/196] =?UTF-8?q?Upgrade=20predicates:=202.1.5=20?= =?UTF-8?q?=E2=86=92=203.1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 36 +++++------------------------------- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf9c5c4..33db786 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,7 +103,7 @@ dependencies = [ "bstr", "doc-comment", "libc", - "predicates 3.1.2", + "predicates", "predicates-core", "predicates-tree", "wait-timeout", @@ -305,12 +305,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - [[package]] name = "encoding_rs" version = "0.8.34" @@ -693,15 +687,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.11" @@ -932,20 +917,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools", - "normalize-line-endings", - "predicates-core", - "regex", -] - [[package]] name = "predicates" version = "3.1.2" @@ -954,7 +925,10 @@ checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" dependencies = [ "anstyle", "difflib", + "float-cmp", + "normalize-line-endings", "predicates-core", + "regex", ] [[package]] @@ -1329,7 +1303,7 @@ dependencies = [ "filetime", "log", "pager", - "predicates 2.1.5", + "predicates", "reqwest", "serde", "serde_derive", diff --git a/Cargo.toml b/Cargo.toml index be5d527..3c8d881 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ pager = "0.16" [dev-dependencies] assert_cmd = "2.0.1" escargot = "0.5" -predicates = "2.0.2" +predicates = "3.1.2" tempfile = "3.1.0" filetime = "0.2.10" From 9096d536b1749093a57918c9a02ea6bc8d82541f Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 22:59:58 +0200 Subject: [PATCH 120/196] =?UTF-8?q?Upgrade=20reqwest:=200.11.27=20?= =?UTF-8?q?=E2=86=92=200.12.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 427 ++++++++++++++++++++++++++++++++++------------------- Cargo.toml | 2 +- 2 files changed, 275 insertions(+), 154 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33db786..ef9ac51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,15 +143,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -305,15 +299,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_filter" version = "0.1.2" @@ -337,12 +322,6 @@ dependencies = [ "log", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - [[package]] name = "errno" version = "0.2.8" @@ -460,6 +439,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -494,6 +474,7 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -518,31 +499,6 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - [[package]] name = "heck" version = "0.5.0" @@ -566,9 +522,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -577,12 +533,24 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", "pin-project-lite", ] @@ -592,12 +560,6 @@ version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" @@ -606,53 +568,76 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", - "h2", "http", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http", "hyper", + "hyper-util", "rustls", + "rustls-native-certs", + "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", + "webpki-roots", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -665,16 +650,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" -dependencies = [ - "equivalent", - "hashbrown", -] - [[package]] name = "ipnet" version = "2.9.0" @@ -736,7 +711,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", "redox_syscall", ] @@ -845,7 +820,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -899,6 +874,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -917,6 +912,15 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "predicates" version = "3.1.2" @@ -956,6 +960,54 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +dependencies = [ + "bytes", + "rand", + "ring", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" version = "1.0.36" @@ -965,13 +1017,43 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -1005,21 +1087,22 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64", "bytes", - "encoding_rs", + "futures-channel", "futures-core", "futures-util", - "h2", "http", "http-body", + "http-body-util", "hyper", "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", @@ -1028,14 +1111,15 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", "rustls", "rustls-native-certs", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -1069,13 +1153,19 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno 0.3.9", "libc", "linux-raw-sys", @@ -1084,44 +1174,55 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ - "log", + "once_cell", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", "rustls-pemfile", + "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64", + "rustls-pki-types", ] [[package]] -name = "rustls-webpki" -version = "0.101.7" +name = "rustls-pki-types" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + +[[package]] +name = "rustls-webpki" +version = "0.102.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] @@ -1149,23 +1250,13 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -1235,6 +1326,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "socket2" version = "0.5.7" @@ -1251,6 +1348,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.74" @@ -1264,30 +1367,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] name = "tealdeer" @@ -1405,24 +1487,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", + "rustls-pki-types", "tokio", ] @@ -1435,6 +1505,27 @@ dependencies = [ "serde", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -1628,9 +1719,12 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "winapi" @@ -1879,9 +1973,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if", "windows-sys 0.48.0", @@ -1899,6 +1993,33 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index 3c8d881..5c8eb87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ atty = "0.2" clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.11", optional = true } log = "0.4" -reqwest = { version = "0.11.3", features = ["blocking"], default-features = false } +reqwest = { version = "0.12.5", features = ["blocking"], default-features = false } serde = "1.0.21" serde_derive = "1.0.21" toml = "0.5.1" From 60855cedcf64503b2f046992efd5e937ffe070b9 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 23:01:49 +0200 Subject: [PATCH 121/196] =?UTF-8?q?Upgrade=20toml:=200.5.11=20=E2=86=92=20?= =?UTF-8?q?0.8.19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef9ac51..e5f9400 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.2.8" @@ -499,6 +505,12 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "heck" version = "0.5.0" @@ -650,6 +662,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -1305,6 +1327,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1498,11 +1529,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.11" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -1971,6 +2027,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 5c8eb87..5ffe274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ log = "0.4" reqwest = { version = "0.12.5", features = ["blocking"], default-features = false } serde = "1.0.21" serde_derive = "1.0.21" -toml = "0.5.1" +toml = "0.8.19" walkdir = "2.0.1" yansi = "0.5" zip = { version = "0.6", default-features = false, features = ["deflate"] } From 4f51ba090f0324683e8130c6e2c3d1ff0a4f72d3 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 12 Aug 2024 23:09:55 +0200 Subject: [PATCH 122/196] =?UTF-8?q?Upgrade=20zip:=200.6.6=20=E2=86=92=202.?= =?UTF-8?q?1.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5f9400..ab96b58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,6 +93,15 @@ dependencies = [ "xdg", ] +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "assert_cmd" version = "2.0.16" @@ -287,12 +296,34 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "difflib" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -744,6 +775,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" version = "0.4.22" @@ -1348,6 +1385,12 @@ dependencies = [ "serde", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.9" @@ -2087,12 +2130,31 @@ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" -version = "0.6.6" +version = "2.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "40dd8c92efc296286ce1fbd16657c5dbefff44f1b4ca01cc5f517d8b7b3d3e2e" dependencies = [ - "byteorder", + "arbitrary", "crc32fast", "crossbeam-utils", + "displaydoc", "flate2", + "indexmap", + "memchr", + "thiserror", + "zopfli", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", ] diff --git a/Cargo.toml b/Cargo.toml index 5ffe274..e795725 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ serde_derive = "1.0.21" toml = "0.8.19" walkdir = "2.0.1" yansi = "0.5" -zip = { version = "0.6", default-features = false, features = ["deflate"] } +zip = { version = "2.1.6", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] pager = "0.16" From 7c245040b9df46e9577c16a43166380efe6dc025 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Tue, 13 Aug 2024 00:14:19 +0200 Subject: [PATCH 123/196] Command line help: Add hint about platform overrides (#375) - Rename PLATFORMS to PLATFORM - Add hint about specifying platform multiple times --- docs/src/usage.txt | 33 +++++++++++++++++---------------- src/cli.rs | 3 ++- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 7e823c4..b1e7e35 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -7,21 +7,22 @@ Arguments: [COMMAND]... The command to show (e.g. `tar` or `git log`) Options: - -l, --list List all commands in the cache - -f, --render Render a specific markdown file - -p, --platform Override the operating system [possible values: linux, macos, sunos, - windows, android, freebsd, netbsd, openbsd] - -L, --language Override the language - -u, --update Update the local cache - --no-auto-update If auto update is configured, disable it for this run - -c, --clear-cache Clear the local cache - --pager Use a pager to page output - -r, --raw Display the raw markdown instead of rendering it - -q, --quiet Suppress informational messages - --show-paths Show file and directory paths used by tealdeer - --seed-config Create a basic config - --color Control whether to use color [possible values: always, auto, never] - -v, --version Print the version - -h, --help Print help + -l, --list List all commands in the cache + -f, --render Render a specific markdown file + -p, --platform Override the operating system, can be specified multiple times in order + of preference [possible values: linux, macos, sunos, windows, android, + freebsd, netbsd, openbsd] + -L, --language Override the language + -u, --update Update the local cache + --no-auto-update If auto update is configured, disable it for this run + -c, --clear-cache Clear the local cache + --pager Use a pager to page output + -r, --raw Display the raw markdown instead of rendering it + -q, --quiet Suppress informational messages + --show-paths Show file and directory paths used by tealdeer + --seed-config Create a basic config + --color Control whether to use color [possible values: always, auto, never] + -v, --version Print the version + -h, --help Print help To view the user documentation, please visit https://dbrgn.github.io/tealdeer/. diff --git a/src/cli.rs b/src/cli.rs index fd6c987..77acf6b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -41,10 +41,11 @@ pub(crate) struct Cli { )] pub render: Option, - /// Override the operating system + /// Override the operating system, can be specified multiple times in order of preference #[arg( short = 'p', long = "platform", + value_name = "PLATFORM", action = ArgAction::Append, )] pub platforms: Option>, From fc6d64415225fe9ee43213c5903b9912d71b89b2 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Mon, 30 Sep 2024 11:27:19 +0200 Subject: [PATCH 124/196] Update all URLs to point to new GitHub organization (#379) See https://github.com/tealdeer-rs/tealdeer/issues/376 for details. --- .github/workflows/release.yml | 2 +- CHANGELOG.md | 156 +++++++++++++++++----------------- Cargo.toml | 6 +- README.md | 12 +-- benchmarks/Dockerfile | 2 +- completion/fish_tealdeer | 2 +- docs/src/installing.md | 2 +- docs/src/intro.md | 2 +- docs/src/tips_and_tricks.md | 2 +- docs/src/usage.txt | 2 +- src/cli.rs | 2 +- src/main.rs | 2 +- 12 files changed, 96 insertions(+), 96 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c36ad5..e5ccdf9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: run: | source ./scripts/upload-asset.sh # Create: - create_release ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} "Tealdeer version ${GITHUB_REF#refs/*/v}.\n\nFor the full changelog, see https://github.com/dbrgn/tealdeer/blob/main/CHANGELOG.md.\n\nBinaries were generated automatically in CI, and are therefore unsigned. For a fully trusted release, please build from source." + create_release ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} "Tealdeer version ${GITHUB_REF#refs/*/v}.\n\nFor the full changelog, see https://github.com/tealdeer-rs/tealdeer/blob/main/CHANGELOG.md.\n\nBinaries were generated automatically in CI, and are therefore unsigned. For a fully trusted release, please build from source." upload-completions: needs: diff --git a/CHANGELOG.md b/CHANGELOG.md index e26c474..7e7c720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,7 +88,7 @@ The highlights: - **Custom pages and patches**: You can now create your own local-only tldr pages. But not just that, you can also extend existing upstream pages with your own examples. For more details, see - [the docs](https://dbrgn.github.io/tealdeer/usage_custom_pages.html). + [the docs](https://tealdeer-rs.github.io/tealdeer/usage_custom_pages.html). - **Change argument parsing from docopt to clap**: We replaced docopt.rs as argument parsing library with clap v3, resulting in almost 1 MiB smaller binaries and a 22% speed increase when rendering a tldr page. @@ -99,7 +99,7 @@ The highlights: `-p/--platform` and implemented transparent lowercasing of the page names. - **Docs**: The README based documentation has reached its limits. There are now new mdbook based docs over at - [dbrgn.github.io/tealdeer/](https://dbrgn.github.io/tealdeer/), we hope these + [tealdeer-rs.github.io/tealdeer/](https://tealdeer-rs.github.io/tealdeer/), we hope these make using tealdeer easier. Of course, documentation improvements are welcome! Also, if you're confused about how to use a certain feature, feel free to open an issue, this way we can improve the docs. @@ -133,8 +133,8 @@ Changes: - [deprecated] The `--config-path` command is deprecated, use `--show-paths` instead ([#162][i162]) - [deprecated] The `-o/--os` command is deprecated, use `-p/--platform` instead ([#217][i217]) - [deprecated] The `-m/--markdown` command is deprecated, use `-r/--raw` instead ([#108][i108]) -- [docs] New docs at [dbrgn.github.io/tealdeer/](https://dbrgn.github.io/tealdeer/) -- [docs] Add comparative benchmarks with hyperfine ([#163][i163], [README](https://github.com/dbrgn/tealdeer#goals)) +- [docs] New docs at [tealdeer-rs.github.io/tealdeer/](https://tealdeer-rs.github.io/tealdeer/) +- [docs] Add comparative benchmarks with hyperfine ([#163][i163], [README](https://github.com/tealdeer-rs/tealdeer#goals)) - [chore] Download tldr pages archive from their website, not from GitHub ([#213][i213]) - [chore] Bump MSRV to 1.54 and change MSRV policy ([#190][i190]) - [chore] The `master` branch was renamed to `main` @@ -345,78 +345,78 @@ Thanks! [@tveness]: https://github.com/tveness [@Voultapher]: https://github.com/Voultapher -[v1.0.0]: https://github.com/dbrgn/tealdeer/compare/v0.4.0...v1.0.0 -[v1.1.0]: https://github.com/dbrgn/tealdeer/compare/v1.0.0...v1.1.0 -[v1.2.0]: https://github.com/dbrgn/tealdeer/compare/v1.1.0...v1.2.0 -[v1.3.0]: https://github.com/dbrgn/tealdeer/compare/v1.2.0...v1.3.0 -[v1.4.0]: https://github.com/dbrgn/tealdeer/compare/v1.3.0...v1.4.0 -[v1.4.1]: https://github.com/dbrgn/tealdeer/compare/v1.4.0...v1.4.1 -[v1.5.0]: https://github.com/dbrgn/tealdeer/compare/v1.4.1...v1.5.0 -[v1.6.0]: https://github.com/dbrgn/tealdeer/compare/v1.5.0...v1.6.0 -[v1.6.1]: https://github.com/dbrgn/tealdeer/compare/v1.6.0...v1.6.1 +[v1.0.0]: https://github.com/tealdeer-rs/tealdeer/compare/v0.4.0...v1.0.0 +[v1.1.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.0.0...v1.1.0 +[v1.2.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.1.0...v1.2.0 +[v1.3.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.2.0...v1.3.0 +[v1.4.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.3.0...v1.4.0 +[v1.4.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.4.0...v1.4.1 +[v1.5.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.4.1...v1.5.0 +[v1.6.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.5.0...v1.6.0 +[v1.6.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.0...v1.6.1 -[i34]: https://github.com/dbrgn/tealdeer/issues/34 -[i43]: https://github.com/dbrgn/tealdeer/issues/43 -[i44]: https://github.com/dbrgn/tealdeer/issues/44 -[i47]: https://github.com/dbrgn/tealdeer/issues/47 -[i48]: https://github.com/dbrgn/tealdeer/issues/48 -[i57]: https://github.com/dbrgn/tealdeer/issues/57 -[i58]: https://github.com/dbrgn/tealdeer/issues/58 -[i61]: https://github.com/dbrgn/tealdeer/issues/61 -[i68]: https://github.com/dbrgn/tealdeer/issues/68 -[i69]: https://github.com/dbrgn/tealdeer/issues/69 -[i71]: https://github.com/dbrgn/tealdeer/issues/71 -[i75]: https://github.com/dbrgn/tealdeer/issues/75 -[i77]: https://github.com/dbrgn/tealdeer/issues/77 -[i84]: https://github.com/dbrgn/tealdeer/issues/84 -[i86]: https://github.com/dbrgn/tealdeer/issues/86 -[i87]: https://github.com/dbrgn/tealdeer/issues/87 -[i89]: https://github.com/dbrgn/tealdeer/issues/89 -[i95]: https://github.com/dbrgn/tealdeer/issues/95 -[i97]: https://github.com/dbrgn/tealdeer/issues/97 -[i99]: https://github.com/dbrgn/tealdeer/issues/99 -[i108]: https://github.com/dbrgn/tealdeer/pull/108 -[i111]: https://github.com/dbrgn/tealdeer/issues/111 -[i112]: https://github.com/dbrgn/tealdeer/issues/112 -[i113]: https://github.com/dbrgn/tealdeer/issues/113 -[i115]: https://github.com/dbrgn/tealdeer/issues/115 -[i125]: https://github.com/dbrgn/tealdeer/pull/125 -[i138]: https://github.com/dbrgn/tealdeer/issues/138 -[i142]: https://github.com/dbrgn/tealdeer/pull/142 -[i148]: https://github.com/dbrgn/tealdeer/pull/148 -[i157]: https://github.com/dbrgn/tealdeer/pull/157 -[i161]: https://github.com/dbrgn/tealdeer/pull/161 -[i162]: https://github.com/dbrgn/tealdeer/pull/162 -[i163]: https://github.com/dbrgn/tealdeer/pull/163 -[i168]: https://github.com/dbrgn/tealdeer/pull/168 -[i171]: https://github.com/dbrgn/tealdeer/pull/171 -[i174]: https://github.com/dbrgn/tealdeer/pull/174 -[i176]: https://github.com/dbrgn/tealdeer/pull/176 -[i187]: https://github.com/dbrgn/tealdeer/pull/187 -[i190]: https://github.com/dbrgn/tealdeer/issues/190 -[i197]: https://github.com/dbrgn/tealdeer/pull/197 -[i210]: https://github.com/dbrgn/tealdeer/pull/210 -[i213]: https://github.com/dbrgn/tealdeer/pull/213 -[i215]: https://github.com/dbrgn/tealdeer/pull/215 -[i217]: https://github.com/dbrgn/tealdeer/pull/217 -[i227]: https://github.com/dbrgn/tealdeer/pull/227 -[#231]: https://github.com/dbrgn/tealdeer/pull/231 -[i240]: https://github.com/dbrgn/tealdeer/pull/240 -[#247]: https://github.com/dbrgn/tealdeer/pull/247 -[#249]: https://github.com/dbrgn/tealdeer/pull/249 -[#253]: https://github.com/dbrgn/tealdeer/pull/253 -[#254]: https://github.com/dbrgn/tealdeer/pull/254 -[#257]: https://github.com/dbrgn/tealdeer/pull/257 -[#259]: https://github.com/dbrgn/tealdeer/pull/259 -[#262]: https://github.com/dbrgn/tealdeer/pull/262 -[#271]: https://github.com/dbrgn/tealdeer/pull/271 -[#272]: https://github.com/dbrgn/tealdeer/pull/272 -[#274]: https://github.com/dbrgn/tealdeer/pull/274 -[#276]: https://github.com/dbrgn/tealdeer/pull/276 -[#284]: https://github.com/dbrgn/tealdeer/pull/284 -[#285]: https://github.com/dbrgn/tealdeer/pull/285 -[#287]: https://github.com/dbrgn/tealdeer/pull/287 -[#290]: https://github.com/dbrgn/tealdeer/pull/290 -[#291]: https://github.com/dbrgn/tealdeer/pull/291 -[#297]: https://github.com/dbrgn/tealdeer/pull/297 -[#299]: https://github.com/dbrgn/tealdeer/pull/299 +[i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 +[i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 +[i44]: https://github.com/tealdeer-rs/tealdeer/issues/44 +[i47]: https://github.com/tealdeer-rs/tealdeer/issues/47 +[i48]: https://github.com/tealdeer-rs/tealdeer/issues/48 +[i57]: https://github.com/tealdeer-rs/tealdeer/issues/57 +[i58]: https://github.com/tealdeer-rs/tealdeer/issues/58 +[i61]: https://github.com/tealdeer-rs/tealdeer/issues/61 +[i68]: https://github.com/tealdeer-rs/tealdeer/issues/68 +[i69]: https://github.com/tealdeer-rs/tealdeer/issues/69 +[i71]: https://github.com/tealdeer-rs/tealdeer/issues/71 +[i75]: https://github.com/tealdeer-rs/tealdeer/issues/75 +[i77]: https://github.com/tealdeer-rs/tealdeer/issues/77 +[i84]: https://github.com/tealdeer-rs/tealdeer/issues/84 +[i86]: https://github.com/tealdeer-rs/tealdeer/issues/86 +[i87]: https://github.com/tealdeer-rs/tealdeer/issues/87 +[i89]: https://github.com/tealdeer-rs/tealdeer/issues/89 +[i95]: https://github.com/tealdeer-rs/tealdeer/issues/95 +[i97]: https://github.com/tealdeer-rs/tealdeer/issues/97 +[i99]: https://github.com/tealdeer-rs/tealdeer/issues/99 +[i108]: https://github.com/tealdeer-rs/tealdeer/pull/108 +[i111]: https://github.com/tealdeer-rs/tealdeer/issues/111 +[i112]: https://github.com/tealdeer-rs/tealdeer/issues/112 +[i113]: https://github.com/tealdeer-rs/tealdeer/issues/113 +[i115]: https://github.com/tealdeer-rs/tealdeer/issues/115 +[i125]: https://github.com/tealdeer-rs/tealdeer/pull/125 +[i138]: https://github.com/tealdeer-rs/tealdeer/issues/138 +[i142]: https://github.com/tealdeer-rs/tealdeer/pull/142 +[i148]: https://github.com/tealdeer-rs/tealdeer/pull/148 +[i157]: https://github.com/tealdeer-rs/tealdeer/pull/157 +[i161]: https://github.com/tealdeer-rs/tealdeer/pull/161 +[i162]: https://github.com/tealdeer-rs/tealdeer/pull/162 +[i163]: https://github.com/tealdeer-rs/tealdeer/pull/163 +[i168]: https://github.com/tealdeer-rs/tealdeer/pull/168 +[i171]: https://github.com/tealdeer-rs/tealdeer/pull/171 +[i174]: https://github.com/tealdeer-rs/tealdeer/pull/174 +[i176]: https://github.com/tealdeer-rs/tealdeer/pull/176 +[i187]: https://github.com/tealdeer-rs/tealdeer/pull/187 +[i190]: https://github.com/tealdeer-rs/tealdeer/issues/190 +[i197]: https://github.com/tealdeer-rs/tealdeer/pull/197 +[i210]: https://github.com/tealdeer-rs/tealdeer/pull/210 +[i213]: https://github.com/tealdeer-rs/tealdeer/pull/213 +[i215]: https://github.com/tealdeer-rs/tealdeer/pull/215 +[i217]: https://github.com/tealdeer-rs/tealdeer/pull/217 +[i227]: https://github.com/tealdeer-rs/tealdeer/pull/227 +[#231]: https://github.com/tealdeer-rs/tealdeer/pull/231 +[i240]: https://github.com/tealdeer-rs/tealdeer/pull/240 +[#247]: https://github.com/tealdeer-rs/tealdeer/pull/247 +[#249]: https://github.com/tealdeer-rs/tealdeer/pull/249 +[#253]: https://github.com/tealdeer-rs/tealdeer/pull/253 +[#254]: https://github.com/tealdeer-rs/tealdeer/pull/254 +[#257]: https://github.com/tealdeer-rs/tealdeer/pull/257 +[#259]: https://github.com/tealdeer-rs/tealdeer/pull/259 +[#262]: https://github.com/tealdeer-rs/tealdeer/pull/262 +[#271]: https://github.com/tealdeer-rs/tealdeer/pull/271 +[#272]: https://github.com/tealdeer-rs/tealdeer/pull/272 +[#274]: https://github.com/tealdeer-rs/tealdeer/pull/274 +[#276]: https://github.com/tealdeer-rs/tealdeer/pull/276 +[#284]: https://github.com/tealdeer-rs/tealdeer/pull/284 +[#285]: https://github.com/tealdeer-rs/tealdeer/pull/285 +[#287]: https://github.com/tealdeer-rs/tealdeer/pull/287 +[#290]: https://github.com/tealdeer-rs/tealdeer/pull/290 +[#291]: https://github.com/tealdeer-rs/tealdeer/pull/291 +[#297]: https://github.com/tealdeer-rs/tealdeer/pull/297 +[#299]: https://github.com/tealdeer-rs/tealdeer/pull/299 diff --git a/Cargo.toml b/Cargo.toml index e795725..bc44343 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,12 @@ authors = [ "Niklas Mohrin ", ] description = "Fetch and show tldr help pages for many CLI commands. Full featured offline client with caching support." -homepage = "https://github.com/dbrgn/tealdeer/" +homepage = "https://github.com/tealdeer-rs/tealdeer/" license = "MIT OR Apache-2.0" name = "tealdeer" readme = "README.md" -repository = "https://github.com/dbrgn/tealdeer/" -documentation = "https://dbrgn.github.io/tealdeer/" +repository = "https://github.com/tealdeer-rs/tealdeer/" +documentation = "https://tealdeer-rs.github.io/tealdeer/" version = "1.6.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.75" diff --git a/README.md b/README.md index 2203b40..230dfa8 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ Rust: Simplified, example based and community-driven man pages. If you pronounce "tldr" in English, it sounds somewhat like "tealdeer". Hence the project name :) In case you're in a hurry and just want to quickly try tealdeer, you can find static -binaries on the [GitHub releases page](https://github.com/dbrgn/tealdeer/releases/)! +binaries on the [GitHub releases page](https://github.com/tealdeer-rs/tealdeer/releases/)! ## Docs (Installing, Usage, Configuration) -User documentation is available at ! +User documentation is available at ! The docs are generated using [mdbook](https://rust-lang.github.io/mdBook/index.html). They can be edited through the markdown files in the `docs/src/` directory. @@ -120,13 +120,13 @@ Thanks to @severen for coming up with the name "tealdeer"! [outfieldr-gh]: https://gitlab.com/ve-nt/outfieldr [python-gh]: https://github.com/tldr-pages/tldr-python-client -[benchmark-dockerfile]: https://github.com/dbrgn/tealdeer/blob/main/benchmarks/Dockerfile +[benchmark-dockerfile]: https://github.com/tealdeer-rs/tealdeer/blob/main/benchmarks/Dockerfile [client-spec]: https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md [hyperfine-gh]: https://github.com/sharkdp/hyperfine -[outfieldr-comment-tls]: https://github.com/dbrgn/tealdeer/issues/129#issuecomment-833596765 +[outfieldr-comment-tls]: https://github.com/tealdeer-rs/tealdeer/issues/129#issuecomment-833596765 -[github-actions]: https://github.com/dbrgn/tealdeer/actions?query=branch%3Amain -[github-actions-badge]: https://github.com/dbrgn/tealdeer/actions/workflows/ci.yml/badge.svg?branch=main +[github-actions]: https://github.com/tealdeer-rs/tealdeer/actions?query=branch%3Amain +[github-actions-badge]: https://github.com/tealdeer-rs/tealdeer/actions/workflows/ci.yml/badge.svg?branch=main [crates-io]: https://crates.io/crates/tealdeer [crates-io-badge]: https://img.shields.io/crates/v/tealdeer.svg diff --git a/benchmarks/Dockerfile b/benchmarks/Dockerfile index d717eba..2a36fe0 100644 --- a/benchmarks/Dockerfile +++ b/benchmarks/Dockerfile @@ -18,7 +18,7 @@ FROM rust AS tealdeer-builder WORKDIR /build -RUN git clone https://github.com/dbrgn/tealdeer.git \ +RUN git clone https://github.com/tealdeer-rs/tealdeer.git \ && cd tealdeer \ && cargo build --release \ && mkdir /build-outputs \ diff --git a/completion/fish_tealdeer b/completion/fish_tealdeer index eb35e87..528be44 100644 --- a/completion/fish_tealdeer +++ b/completion/fish_tealdeer @@ -1,6 +1,6 @@ # # Completions for the tealdeer implementation of tldr -# https://github.com/dbrgn/tealdeer/ +# https://github.com/tealdeer-rs/tealdeer/ # complete -c tldr -s h -l help -d 'Print the help message.' -f diff --git a/docs/src/installing.md b/docs/src/installing.md index 5e51afa..71c8398 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -31,7 +31,7 @@ Tealdeer has been added to a few package managers: ## Static Binaries (Linux) Static binary builds (currently for Linux only) are available on the -[GitHub releases page](https://github.com/dbrgn/tealdeer/releases). +[GitHub releases page](https://github.com/tealdeer-rs/tealdeer/releases). Simply download the binary for your platform and run it! ## Through `cargo install` diff --git a/docs/src/intro.md b/docs/src/intro.md index ca9f8cc..a90ecec 100644 --- a/docs/src/intro.md +++ b/docs/src/intro.md @@ -10,5 +10,5 @@ This documentation shows how to install, use and configure tealdeer. ## Links -- [GitHub Project Page](https://github.com/dbrgn/tealdeer) +- [GitHub Project Page](https://github.com/tealdeer-rs/tealdeer) - [TLDR Pages Project](https://tldr.sh/) diff --git a/docs/src/tips_and_tricks.md b/docs/src/tips_and_tricks.md index 99a49c7..29f7216 100644 --- a/docs/src/tips_and_tricks.md +++ b/docs/src/tips_and_tricks.md @@ -49,4 +49,4 @@ every page, so the script may take a couple of seconds to finish. ## Extending this chapter If you have an interesting setup with Tealdeer, feel free to share your -configuration on [our Github repository](https://github.com/dbrgn/tealdeer). +configuration on [our Github repository](https://github.com/tealdeer-rs/tealdeer). diff --git a/docs/src/usage.txt b/docs/src/usage.txt index b1e7e35..11b7ebe 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -25,4 +25,4 @@ Options: -v, --version Print the version -h, --help Print help -To view the user documentation, please visit https://dbrgn.github.io/tealdeer/. +To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/. diff --git a/src/cli.rs b/src/cli.rs index 77acf6b..e671507 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -18,7 +18,7 @@ use crate::types::{ColorOptions, PlatformType}; {usage-heading} {usage} {all-args}{after-help}", - after_help = "To view the user documentation, please visit https://dbrgn.github.io/tealdeer/.", + after_help = "To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.", arg_required_else_help = true, help_expected = true, group = ArgGroup::new("command_or_file").args(&["command", "render"]), diff --git a/src/main.rs b/src/main.rs index 4de0038..479eb4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -110,7 +110,7 @@ fn check_cache(cache: &Cache, args: &Cli, enable_styles: bool) -> CheckCacheResu println!("The path to your config file can be looked up with `tldr --show-paths`."); println!("To create an initial config file, use `tldr --seed-config`.\n"); println!("You can find more tips and tricks in our docs:\n"); - println!(" https://dbrgn.github.io/tealdeer/config_updates.html"); + println!(" https://tealdeer-rs.github.io/tealdeer/config_updates.html"); CheckCacheResult::CacheMissing } } From ec2daa495c3ece2f4aa783daa9bee535e3228029 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 2 Oct 2024 22:32:17 +0200 Subject: [PATCH 125/196] Replace `atty` with `std::io::IsTerminal` (#380) --- Cargo.lock | 23 +---------------------- Cargo.toml | 1 - src/main.rs | 9 ++++++--- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab96b58..64744a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,17 +118,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.3.0" @@ -548,15 +537,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.9" @@ -814,7 +794,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -1452,7 +1432,6 @@ dependencies = [ "anyhow", "app_dirs2", "assert_cmd", - "atty", "clap", "env_logger", "escargot", diff --git a/Cargo.toml b/Cargo.toml index bc44343..cf374ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ path = "src/main.rs" [dependencies] anyhow = "1" app_dirs = { version = "2", package = "app_dirs2" } -atty = "0.2" clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.11", optional = true } log = "0.4" diff --git a/src/main.rs b/src/main.rs index 479eb4e..9dede44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,10 +30,13 @@ compile_error!( "exactly one of the features \"native-roots\", \"webpki-roots\" or \"native-tls\" must be enabled" ); -use std::{env, process}; +use std::{ + env, + io::{self, IsTerminal}, + process, +}; use app_dirs::AppInfo; -use atty::Stream; use clap::Parser; mod cache; @@ -258,7 +261,7 @@ fn main() { // * NO_COLOR env var isn't set: https://no-color.org/ // * The output stream is stdout (not being piped) ColorOptions::Auto => { - ansi_support && env::var_os("NO_COLOR").is_none() && atty::is(Stream::Stdout) + ansi_support && env::var_os("NO_COLOR").is_none() && io::stdout().is_terminal() } // Disable styling ColorOptions::Never => false, From 713f6f913c3f8b804a9b8ef58924383ec0181ad9 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 2 Oct 2024 22:44:22 +0200 Subject: [PATCH 126/196] Run cargo update (#381) --- Cargo.lock | 457 +++++++++++++++++++++++------------------------------ 1 file changed, 195 insertions(+), 262 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64744a2..cddbb31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "app_dirs2" @@ -120,23 +120,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -176,15 +176,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.10" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +dependencies = [ + "shlex", +] [[package]] name = "cesu8" @@ -200,9 +203,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.15" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" +checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" dependencies = [ "clap_builder", "clap_derive", @@ -210,9 +213,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" dependencies = [ "anstream", "anstyle", @@ -222,9 +225,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -393,15 +396,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -411,9 +414,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -521,15 +524,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -579,9 +582,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "humantime" @@ -610,9 +613,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http", @@ -645,9 +648,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -658,7 +661,6 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -675,9 +677,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -685,9 +687,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is_terminal_polyfill" @@ -725,18 +727,18 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libredox" @@ -781,11 +783,11 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -840,18 +842,21 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "openssl" @@ -913,26 +918,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -947,9 +932,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "ppv-lite86" @@ -1001,9 +992,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ "bytes", "pin-project-lite", @@ -1019,9 +1010,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ "bytes", "rand", @@ -1036,22 +1027,22 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" dependencies = [ "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1088,18 +1079,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1109,9 +1100,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1120,15 +1111,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64", "bytes", @@ -1168,7 +1159,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "windows-registry", ] [[package]] @@ -1200,9 +1191,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno 0.3.9", @@ -1213,9 +1204,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "ring", @@ -1227,9 +1218,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -1240,25 +1231,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -1282,11 +1272,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1304,9 +1294,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -1314,18 +1304,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.207" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1334,9 +1324,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -1346,9 +1336,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1365,6 +1355,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1410,9 +1406,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.74" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -1424,6 +1420,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "tealdeer" @@ -1451,9 +1450,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", @@ -1464,12 +1463,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -1480,18 +1479,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -1515,9 +1514,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -1572,9 +1571,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -1583,32 +1582,11 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -1637,21 +1615,21 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -1721,19 +1699,20 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -1746,9 +1725,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -1758,9 +1737,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1768,9 +1747,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -1781,15 +1760,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -1797,9 +1776,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -1835,6 +1814,36 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -1844,15 +1853,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -1886,21 +1886,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -1923,12 +1908,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -1941,12 +1920,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -1959,12 +1932,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1983,12 +1950,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -2001,12 +1962,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -2019,12 +1974,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -2037,12 +1986,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -2051,23 +1994,13 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "xdg" version = "2.5.2" @@ -2109,9 +2042,9 @@ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" -version = "2.1.6" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40dd8c92efc296286ce1fbd16657c5dbefff44f1b4ca01cc5f517d8b7b3d3e2e" +checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" dependencies = [ "arbitrary", "crc32fast", From d44613cf59445b910a75b7df489466f1948b5d44 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 2 Oct 2024 21:21:31 +0200 Subject: [PATCH 127/196] Release v1.7.0 --- CHANGELOG.md | 104 +++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- RELEASING.md | 5 +- docs/src/usage.txt | 2 +- docs/src/usage_custom_pages.md | 3 - 6 files changed, 108 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e7c720..a8b1419 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,78 @@ Possible log types: - `[chore]` for maintenance work. +### [v1.7.0][v1.7.0] (2024-10-02) + +It's been 24 months since the last release, time for tealdeer 1.7.0! Thanks to +16 individual contributors, a few nice changes and features are included in +this release. + +One change is that you can **query multiple platforms at once**. For example: + + tldr --platform openbsd --platform linux df + +This will show the `df` page for OpenBSD (if available), followed by Linux (if +available), with fallback to the current platform on which tealdeer runs. + +What's that `openbsd` thing up there? Yes, there's now **support for the BSD +platforms `freebsd`, `netbsd` and `openbsd`**. + +And since we're already talking about platform support: Our **binary releases +now include builds for ARM64 (aka `aarch64`) on macOS (Apple Silicon, M1/M2/M3) +and Linux**. _(Keep in mind that binary releases are generated in CI and are +unsigned. For a trusted build, please compile from source.)_ + +There's also a breaking change for the folks using [custom pages and +patches](https://tealdeer-rs.github.io/tealdeer/usage_custom_pages.html): These +files now use a `.md` extension. Old files will continue to work, but will +result a deprecation warning being printed when used. + +On a personal note, this will be the last release from me +([Danilo](https://github.com/dbrgn/)) as primary maintainer of tealdeer. For +details, see [#376](https://github.com/tealdeer-rs/tealdeer/issues/376). + +Changes: + +- [added] Allow querying multiple platforms ([#300]) +- [added] Add BSD platform support ([#354]) +- [added] Allow building with native-tls in addition to rustls ([#303]) +- [changed] Change custom page files to use a `.md` file extension ([#322]) +- [changed] Update to clap v4 for doing command line parsing ([#298]) +- [changed] Performance optimization in LineIterator ([#314]) +- [changed] Performance optimizations by tweaking Cargo flags ([#355]) +- [changed] Include completions in published crate ([#333]) +- [changed] Minimal supported Rust version is now 1.75 ([#298]) +- [fixed] Fix bash/zsh/fish completions when cache is empty ([#327], [#331]) +- [docs] Publish docs only when tagging a release ([#362]) +- [docs] List Scoop and Debian packages ([#305], [#315]) +- [docs] Add "Tips and Tricks" chapter to user manual ([#342]) +- [docs] Various docs improvements ([#293]) +- [chore] Improvements to CI workflows ([#324]) +- [chore] Update Cargo.toml license field following SPDX 2.1 ([#336]) +- [chore] Dependency updates + +Contributors to this version: + +- [Adam Henley][@adamazing] +- [Andrea Frigido][@frisoft] +- [Blair Noctis][@nc7s] +- [Danilo Bargen][@dbrgn] +- [Felix Yan][@felixonmars] +- [Iliia Maleki][@iliya-malecki] +- [JJ Style][@jj-style] +- [K.B.Dharun Krishna][@kbdharun] +- [Linus Walker][@Walker-00] +- [Mohit Raj][@agrmohit] +- [Nicolai Fröhlich][@nifr] +- [Niklas Mohrin][@niklasmohrin] +- [@qknogxxb][@qknogxxb] +- [@tveness][@tveness] +- [Y.D.X.][@YDX-2147483647] +- [Zacchary Dempsey-Plante][@zedseven] + +Thanks! + + ### [v1.6.1][v1.6.1] (2022-10-24) Changes: @@ -296,7 +368,10 @@ Thanks! - First crates.io release + [@0ndorio]: https://github.com/0ndorio +[@adamazing]: https://github.com/adamazing +[@agrmohit]: https://github.com/agrmohit [@aldanor]: https://github.com/aldanor [@Atul9]: https://github.com/Atul9 [@BachoSeven]: https://github.com/BachoSeven @@ -314,15 +389,20 @@ Thanks! [@Delapouite]: https://github.com/Delapouite [@dmaahs2017]: https://github.com/dmaahs2017 [@equal-l2]: https://github.com/equal-l2 +[@felixonmars]: https://github.com/felixonmars +[@frisoft]: https://github.com/frisoft [@gagarine]: https://github.com/gagarine [@hgaiser]: https://github.com/hgaiser [@ilai-deutel]: https://github.com/ilai-deutel +[@iliya-malecki]: https://github.com/iliya-malecki [@invakid404]: https://github.com/invakid404 [@james2doyle]: https://github.com/james2doyle [@jcgruenhage]: https://github.com/jcgruenhage [@jdvr]: https://github.com/jdvr [@jedahan]: https://github.com/jedahan [@jesdazrez]: https://github.com/jesdazrez +[@jj-style]: https://github.com/jj-style +[@kbdharun]: https://github.com/kbdharun [@kianmeng]: https://github.com/kianmeng [@kornelski]: https://github.com/kornelski [@korrat]: https://github.com/korrat @@ -333,10 +413,13 @@ Thanks! [@mucinoab]: https://github.com/mucinoab [@mystal]: https://github.com/mystal [@natpen]: https://github.com/natpen +[@nc7s]: https://github.com/nc7s [@newsch]: https://github.com/newsch +[@nifr]: https://github.com/nifr [@niklasmohrin]: https://github.com/niklasmohrin [@Olavhaasie]: https://github.com/Olavhaasie [@Plommonsorbet]: https://github.com/Plommonsorbet +[@qknogxxb]: https://github.com/qknogxxb [@rithvikvibhu]: https://github.com/rithvikvibhu [@SimplyDanny]: https://github.com/SimplyDanny [@sondr3]: https://github.com/sondr3 @@ -344,6 +427,9 @@ Thanks! [@tranzystorek-io]: https://github.com/tranzystorek-io [@tveness]: https://github.com/tveness [@Voultapher]: https://github.com/Voultapher +[@Walker-00]: https://github.com/Walker-00 +[@YDX-2147483647]: https://github.com/YDX-2147483647 +[@zedseven]: https://github.com/zedseven [v1.0.0]: https://github.com/tealdeer-rs/tealdeer/compare/v0.4.0...v1.0.0 [v1.1.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.0.0...v1.1.0 @@ -354,6 +440,7 @@ Thanks! [v1.5.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.4.1...v1.5.0 [v1.6.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.5.0...v1.6.0 [v1.6.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.0...v1.6.1 +[v1.7.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.7.0 [i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 [i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 @@ -418,5 +505,22 @@ Thanks! [#287]: https://github.com/tealdeer-rs/tealdeer/pull/287 [#290]: https://github.com/tealdeer-rs/tealdeer/pull/290 [#291]: https://github.com/tealdeer-rs/tealdeer/pull/291 +[#293]: https://github.com/tealdeer-rs/tealdeer/pull/293 [#297]: https://github.com/tealdeer-rs/tealdeer/pull/297 +[#298]: https://github.com/tealdeer-rs/tealdeer/pull/298 [#299]: https://github.com/tealdeer-rs/tealdeer/pull/299 +[#300]: https://github.com/tealdeer-rs/tealdeer/pull/300 +[#303]: https://github.com/tealdeer-rs/tealdeer/pull/303 +[#305]: https://github.com/tealdeer-rs/tealdeer/pull/305 +[#314]: https://github.com/tealdeer-rs/tealdeer/pull/314 +[#315]: https://github.com/tealdeer-rs/tealdeer/pull/315 +[#322]: https://github.com/tealdeer-rs/tealdeer/pull/322 +[#324]: https://github.com/tealdeer-rs/tealdeer/pull/324 +[#327]: https://github.com/tealdeer-rs/tealdeer/pull/327 +[#331]: https://github.com/tealdeer-rs/tealdeer/pull/331 +[#333]: https://github.com/tealdeer-rs/tealdeer/pull/333 +[#336]: https://github.com/tealdeer-rs/tealdeer/pull/336 +[#342]: https://github.com/tealdeer-rs/tealdeer/pull/342 +[#354]: https://github.com/tealdeer-rs/tealdeer/pull/354 +[#355]: https://github.com/tealdeer-rs/tealdeer/pull/355 +[#362]: https://github.com/tealdeer-rs/tealdeer/pull/362 diff --git a/Cargo.lock b/Cargo.lock index cddbb31..4a1c940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,7 +1426,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.6.1" +version = "1.7.0" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index cf374ad..954a52c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" -version = "1.6.1" +version = "1.7.0" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.75" edition = "2021" diff --git a/RELEASING.md b/RELEASING.md index 16cb4e2..f182519 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,16 +7,13 @@ Run linting: Set variables: $ export VERSION=X.Y.Z - $ export GPG_KEY=EA456E8BAF0109429583EED83578F667F2F3A5FA + $ export GPG_KEY=20EE002D778AE197EF7D0D2CB993FF98A90C9AB1 Update version numbers: $ vim Cargo.toml $ cargo update -p tealdeer -For release 1.7.0: Remove this note and uncomment warning in -`docs/src/usage_custom_pages.md`. - Update docs: $ cargo run -- --help > docs/src/usage.txt diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 11b7ebe..9307a40 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.6.1: A fast TLDR client +tealdeer 1.7.0: A fast TLDR client Danilo Bargen , Niklas Mohrin Usage: tldr [OPTIONS] [COMMAND]... diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md index 87344d7..d5d0f89 100644 --- a/docs/src/usage_custom_pages.md +++ b/docs/src/usage_custom_pages.md @@ -1,7 +1,5 @@ # Custom Pages and Patches - Tealdeer allows creating new custom pages, overriding existing pages as well as extending existing pages. From fb7492b0b555a7467b76321d915fa633a0432bc9 Mon Sep 17 00:00:00 2001 From: Blair Noctis <4474501+nc7s@users.noreply.github.com> Date: Thu, 14 Nov 2024 23:07:30 +0800 Subject: [PATCH 128/196] Upgrade yansi: 0.5.1 -> 1.0.1 (#389) - Adapt to `thing.paint(style)` API; was `style.paint(thing)` - Remove `yansi::Paint::enable_windows_ascii()` in style usage decision; removed in yansi commit b186eb5bfb, which introduced "automatic" support for Windows: "If support is not available, styling is disabled and no styling sequences are emitted", fitting the `Auto` option - Respect `--color=always` even if we know it won't work --------- Co-authored-by: Niklas Mohrin --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/config.rs | 2 +- src/main.rs | 14 +++++--------- src/output.rs | 11 ++++++----- src/utils.rs | 4 ++-- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a1c940..0208435 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2009,9 +2009,9 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" diff --git a/Cargo.toml b/Cargo.toml index 954a52c..d567831 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ serde = "1.0.21" serde_derive = "1.0.21" toml = "0.8.19" walkdir = "2.0.1" -yansi = "0.5" +yansi = "1" zip = { version = "2.1.6", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] diff --git a/src/config.rs b/src/config.rs index 98d4e46..454fbf5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -57,7 +57,7 @@ impl From for Color { RawColor::Cyan => Self::Cyan, RawColor::White => Self::White, RawColor::Ansi(num) => Self::Fixed(num), - RawColor::Rgb { r, g, b } => Self::RGB(r, g, b), + RawColor::Rgb { r, g, b } => Self::Rgb(r, g, b), } } } diff --git a/src/main.rs b/src/main.rs index 9dede44..5e6e739 100644 --- a/src/main.rs +++ b/src/main.rs @@ -249,20 +249,16 @@ fn main() { let args = Cli::parse(); // Determine the usage of styles - #[cfg(target_os = "windows")] - let ansi_support = yansi::Paint::enable_windows_ascii(); - #[cfg(not(target_os = "windows"))] - let ansi_support = true; let enable_styles = match args.color.unwrap_or_default() { // Attempt to use styling if instructed - ColorOptions::Always => true, + ColorOptions::Always => { + yansi::enable(); // disable yansi's automatic detection for ANSI support on Windows + true + } // Enable styling if: - // * There is `ansi_support` // * NO_COLOR env var isn't set: https://no-color.org/ // * The output stream is stdout (not being piped) - ColorOptions::Auto => { - ansi_support && env::var_os("NO_COLOR").is_none() && io::stdout().is_terminal() - } + ColorOptions::Auto => env::var_os("NO_COLOR").is_none() && io::stdout().is_terminal(), // Disable styling ColorOptions::Never => false, }; diff --git a/src/output.rs b/src/output.rs index 357b988..abef1db 100644 --- a/src/output.rs +++ b/src/output.rs @@ -3,6 +3,7 @@ use std::io::{self, BufRead, Write}; use anyhow::{Context, Result}; +use yansi::Paint; use crate::{ cache::PageLookupResult, @@ -86,11 +87,11 @@ fn print_snippet( use PageSnippet::*; match snip { - CommandName(s) => write!(writer, "{}", style.command_name.paint(s)), - Variable(s) => write!(writer, "{}", style.example_variable.paint(s)), - NormalCode(s) => write!(writer, "{}", style.example_code.paint(s)), - Description(s) => writeln!(writer, " {}", style.description.paint(s)), - Text(s) => writeln!(writer, " {}", style.example_text.paint(s)), + CommandName(s) => write!(writer, "{}", s.paint(style.command_name)), + Variable(s) => write!(writer, "{}", s.paint(style.example_variable)), + NormalCode(s) => write!(writer, "{}", s.paint(style.example_code)), + Description(s) => writeln!(writer, " {}", s.paint(style.description)), + Text(s) => writeln!(writer, " {}", s.paint(style.example_text)), Linebreak => writeln!(writer), } } diff --git a/src/utils.rs b/src/utils.rs index 1649281..f4d825a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use yansi::Color; +use yansi::{Color, Paint}; /// Print a warning to stderr. If `enable_styles` is true, then a yellow /// message will be printed. @@ -14,7 +14,7 @@ pub fn print_error(enable_styles: bool, error: &anyhow::Error) { fn print_msg(enable_styles: bool, message: &str, prefix: &'static str, color: Color) { if enable_styles { - eprintln!("{}{}", color.paint(prefix), color.paint(message)); + eprintln!("{}{}", prefix.paint(color), message.paint(color)); } else { eprintln!("{message}"); } From d719f21f7bf8354f6475fe23ee844bc17640d92a Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Thu, 14 Nov 2024 21:59:23 +0100 Subject: [PATCH 129/196] Bump futures-util (0.3.30 is yanked) --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0208435..4f00b34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,33 +473,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", From 1d9153e37e131ca56071213ba40ec01b16158ebf Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Thu, 14 Nov 2024 22:11:34 +0100 Subject: [PATCH 130/196] Release v1.7.1 --- CHANGELOG.md | 17 +++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/usage.txt | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b1419..04fdd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,21 @@ Possible log types: - `[docs]` for documentation changes. - `[chore]` for maintenance work. +### [v1.7.1][v1.7.1] (2024-11-14) + +This patch release updates the `yansi` dependency to version 1, so that the +previous versions of `yansi` can be removed from the package sets of Linux +distributions. This change should not impact the behavior of tealdeer. + +Changes: + +- [chore] Upgrade yansi: 0.5.1 -> 1.0.1 ([#389]) + +Contributors to this version: + +- [Blair Noctis][@nc7s] + +Thanks! ### [v1.7.0][v1.7.0] (2024-10-02) @@ -441,6 +456,7 @@ Thanks! [v1.6.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.5.0...v1.6.0 [v1.6.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.0...v1.6.1 [v1.7.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.7.0 +[v1.7.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.0...v1.7.1 [i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 [i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 @@ -524,3 +540,4 @@ Thanks! [#354]: https://github.com/tealdeer-rs/tealdeer/pull/354 [#355]: https://github.com/tealdeer-rs/tealdeer/pull/355 [#362]: https://github.com/tealdeer-rs/tealdeer/pull/362 +[#389]: https://github.com/tealdeer-rs/tealdeer/pull/389 diff --git a/Cargo.lock b/Cargo.lock index 4f00b34..ddb75c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,7 +1426,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.7.0" +version = "1.7.1" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index d567831..aa1f423 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" -version = "1.7.0" +version = "1.7.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.75" edition = "2021" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 9307a40..5129fbe 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.7.0: A fast TLDR client +tealdeer 1.7.1: A fast TLDR client Danilo Bargen , Niklas Mohrin Usage: tldr [OPTIONS] [COMMAND]... From ee5418b5a8791cbfb215bd819cbb5c2d4f633a46 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 19:07:40 +0100 Subject: [PATCH 131/196] Run `cargo clippy --fix` (Rust 1.83) (#397) --- src/formatter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/formatter.rs b/src/formatter.rs index d5e3b32..369efce 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -15,7 +15,7 @@ pub enum PageSnippet<'a> { Linebreak, } -impl<'a> PageSnippet<'a> { +impl PageSnippet<'_> { pub fn is_empty(&self) -> bool { use PageSnippet::*; From 6869837e79d74821126a2257b3100c1d7881145b Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 19:21:04 +0100 Subject: [PATCH 132/196] Run `cargo update -p url` to bump `idna` --- Cargo.lock | 282 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 260 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb75c7..62f83f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -666,13 +666,142 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -757,6 +886,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lockfree-object-pool" version = "0.1.6" @@ -1398,6 +1533,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "subtle" version = "2.6.1" @@ -1424,6 +1565,17 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tealdeer" version = "1.7.1" @@ -1497,6 +1649,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -1613,27 +1775,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "untrusted" version = "0.9.0" @@ -1642,15 +1789,27 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -2001,6 +2160,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xdg" version = "2.5.2" @@ -2013,6 +2184,30 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -2034,12 +2229,55 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zip" version = "2.2.0" From e3a06eefe3e06127335919f2bb3e436042466ad4 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 19:21:36 +0100 Subject: [PATCH 133/196] Run `cargo update -p hashbrown` --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62f83f3..184c204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,9 +530,9 @@ checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" From 0c55a4b82affc878298cb6fdb569547768e07c91 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 19:22:25 +0100 Subject: [PATCH 134/196] Run `cargo update --recursive -p rustls` --- Cargo.lock | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 184c204..008695c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,9 @@ checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.24" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] @@ -865,9 +865,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libredox" @@ -986,12 +986,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" @@ -1071,12 +1068,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -1339,9 +1330,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "once_cell", "ring", @@ -1375,9 +1366,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "rustls-webpki" From 909bad9c65ab0d67dc4cc2eba968cd4a7e8c0bca Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 22:48:37 +0100 Subject: [PATCH 135/196] Fix feature selection in integration tests --- tests/lib.rs | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/tests/lib.rs b/tests/lib.rs index fa8d19c..885989f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -97,14 +97,12 @@ impl TestEnv { } /// Disable default features. - #[allow(dead_code)] // Might be useful in the future fn no_default_features(mut self) -> Self { self.default_features = false; self } /// Add the specified feature. - #[allow(dead_code)] // Might be useful in the future fn with_feature>(mut self, feature: S) -> Self { self.features.push(feature.into()); self @@ -114,15 +112,16 @@ impl TestEnv { fn command(&self) -> Command { let mut build = escargot::CargoBuild::new() .bin("tldr") + .arg("--color=never") .current_release() .current_target(); if !self.default_features { - build = build.arg("--no-default-features"); + build = build.no_default_features(); } if !self.features.is_empty() { - build = build.arg(format!("--feature {}", self.features.join(","))); + build = build.features(self.features.join(" ")) } - let run = build.run().unwrap(); + let run = build.run().expect("Failed to build tealdeer for testing"); let mut cmd = run.command(); cmd.env(CACHE_DIR_ENV_VAR, self.cache_dir.path().to_str().unwrap()); cmd.env( @@ -133,6 +132,12 @@ impl TestEnv { } } +#[test] +#[should_panic] +fn test_cannot_build_without_tls_feature() { + let _ = TestEnv::new().no_default_features().command(); +} + #[test] fn test_missing_cache() { TestEnv::new() @@ -144,7 +149,7 @@ fn test_missing_cache() { } #[test] -fn test_update_cache() { +fn test_update_cache_default_features() { let testenv = TestEnv::new(); testenv @@ -164,6 +169,29 @@ fn test_update_cache() { testenv.command().args(["sl"]).assert().success(); } +#[test] +fn test_update_cache_rustls_webpki() { + let testenv = TestEnv::new() + .no_default_features() + .with_feature("webpki-roots"); + + testenv + .command() + .args(["sl"]) + .assert() + .failure() + .stderr(contains("Page cache not found. Please run `tldr --update`")); + + testenv + .command() + .args(["--update"]) + .assert() + .success() + .stderr(contains("Successfully updated cache.")); + + testenv.command().args(["sl"]).assert().success(); +} + #[test] fn test_quiet_cache() { let testenv = TestEnv::new(); From e85de336edf8f47ba7ceea964c331079f1a14b6e Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 22:50:53 +0100 Subject: [PATCH 136/196] Structure test fixtures like page cache --- tests/cache/pages.ja/common/apt.md | 37 +++ tests/cache/pages/common/git-checkout.md | 36 +++ tests/{ => cache/pages/common}/inkscape-v1.md | 0 tests/{ => cache/pages/common}/inkscape-v2.md | 0 .../pages/common/which.md} | 0 tests/chmod.ru.expected | 32 -- tests/chmod.ru.md | 32 -- tests/{ => custom-pages}/inkscape-v2.patch.md | 0 tests/lib.rs | 283 ++++++++---------- tests/rendered/apt.ja.expected | 37 +++ .../inkscape-default-no-color.expected | 0 .../{ => rendered}/inkscape-default.expected | 0 .../inkscape-patched-no-color.expected | 0 .../inkscape-with-config.expected | 0 14 files changed, 227 insertions(+), 230 deletions(-) create mode 100644 tests/cache/pages.ja/common/apt.md create mode 100644 tests/cache/pages/common/git-checkout.md rename tests/{ => cache/pages/common}/inkscape-v1.md (100%) rename tests/{ => cache/pages/common}/inkscape-v2.md (100%) rename tests/{which-markdown.expected => cache/pages/common/which.md} (100%) delete mode 100644 tests/chmod.ru.expected delete mode 100644 tests/chmod.ru.md rename tests/{ => custom-pages}/inkscape-v2.patch.md (100%) create mode 100644 tests/rendered/apt.ja.expected rename tests/{ => rendered}/inkscape-default-no-color.expected (100%) rename tests/{ => rendered}/inkscape-default.expected (100%) rename tests/{ => rendered}/inkscape-patched-no-color.expected (100%) rename tests/{ => rendered}/inkscape-with-config.expected (100%) diff --git a/tests/cache/pages.ja/common/apt.md b/tests/cache/pages.ja/common/apt.md new file mode 100644 index 0000000..fe16a3d --- /dev/null +++ b/tests/cache/pages.ja/common/apt.md @@ -0,0 +1,37 @@ +# apt + +> Debian系ディストリビューションで使われるパッケージ管理システムです。 +> Ubuntuのバージョンが16.04か、それ以降で対話モードを使う場合`apt-get`の代わりとして使用します。 +> 詳しくはこちら: + +- 利用可能なパーケージとバージョンのリストの更新(他の`apt`コマンドの前での実行を推奨): + +`sudo apt update` + +- 指定されたパッケージの検索: + +`apt search {{パッケージ}}` + +- パッケージの情報を出力: + +`apt show {{パッケージ}}` + +- パッケージのインストール、または利用可能な最新バージョンに更新: + +`sudo apt install {{パッケージ}}` + +- パッケージの削除(`sudo apt remove --purge`の場合設定ファイルも削除): + +`sudo apt remove {{パッケージ}}` + +- インストールされている全てのパッケージを最新のバージョンにアップグレード: + +`sudo apt upgrade` + +- インストールできるすべてのパッケージを表示: + +`apt list` + +- インストールされた全てのパッケージを表示(依存関係も表示): + +`apt list --installed` diff --git a/tests/cache/pages/common/git-checkout.md b/tests/cache/pages/common/git-checkout.md new file mode 100644 index 0000000..ca1bacc --- /dev/null +++ b/tests/cache/pages/common/git-checkout.md @@ -0,0 +1,36 @@ +# git checkout + +> Checkout a branch or paths to the working tree. +> More information: . + +- Create and switch to a new branch: + +`git checkout -b {{branch_name}}` + +- Create and switch to a new branch based on a specific reference (branch, remote/branch, tag are examples of valid references): + +`git checkout -b {{branch_name}} {{reference}}` + +- Switch to an existing local branch: + +`git checkout {{branch_name}}` + +- Switch to the previously checked out branch: + +`git checkout -` + +- Switch to an existing remote branch: + +`git checkout --track {{remote_name}}/{{branch_name}}` + +- Discard all unstaged changes in the current directory (see `git reset` for more undo-like commands): + +`git checkout .` + +- Discard unstaged changes to a given file: + +`git checkout {{path/to/file}}` + +- Replace a file in the current directory with the version of it committed in a given branch: + +`git checkout {{branch_name}} -- {{path/to/file}}` diff --git a/tests/inkscape-v1.md b/tests/cache/pages/common/inkscape-v1.md similarity index 100% rename from tests/inkscape-v1.md rename to tests/cache/pages/common/inkscape-v1.md diff --git a/tests/inkscape-v2.md b/tests/cache/pages/common/inkscape-v2.md similarity index 100% rename from tests/inkscape-v2.md rename to tests/cache/pages/common/inkscape-v2.md diff --git a/tests/which-markdown.expected b/tests/cache/pages/common/which.md similarity index 100% rename from tests/which-markdown.expected rename to tests/cache/pages/common/which.md diff --git a/tests/chmod.ru.expected b/tests/chmod.ru.expected deleted file mode 100644 index c7f92c2..0000000 --- a/tests/chmod.ru.expected +++ /dev/null @@ -1,32 +0,0 @@ - - Изменить права доступа файлу или папке. - Больше информации: . - - Дать [u]пользователю, который владеет файлом, права на его [x]исполнение: - - chmod u+x файл - - Дать права [u]пользователю права [r]чтения и [w]записи в файл/папку: - - chmod u+rw файл_или_папка - - Убрать права на [x]исполнение у [g]группы: - - chmod g-x файл - - Дать [a]всем пользователям права на [r]чтение и [x]исполенеие: - - chmod a+rx файл - - Дать [o]другим (не из группы владельцев файлом) такие же права как и у [g]группы: - - chmod o=g файл - - Убрать все права у [o]других: - - chmod o= файл - - Изменить права рекурсивно, дав [g]группе и [o]другим возможность [w]записи в папку: - - chmod -R g+w,o+w папка - diff --git a/tests/chmod.ru.md b/tests/chmod.ru.md deleted file mode 100644 index 4b92329..0000000 --- a/tests/chmod.ru.md +++ /dev/null @@ -1,32 +0,0 @@ -# chmod - -> Изменить права доступа файлу или папке. -> Больше информации: . - -- Дать [u]пользователю, который владеет файлом, права на его [x]исполнение: - -`chmod u+x {{файл}}` - -- Дать права [u]пользователю права [r]чтения и [w]записи в файл/папку: - -`chmod u+rw {{файл_или_папка}}` - -- Убрать права на [x]исполнение у [g]группы: - -`chmod g-x {{файл}}` - -- Дать [a]всем пользователям права на [r]чтение и [x]исполенеие: - -`chmod a+rx {{файл}}` - -- Дать [o]другим (не из группы владельцев файлом) такие же права как и у [g]группы: - -`chmod o=g {{файл}}` - -- Убрать все права у [o]других: - -`chmod o= {{файл}}` - -- Изменить права рекурсивно, дав [g]группе и [o]другим возможность [w]записи в папку: - -`chmod -R g+w,o+w {{папка}}` diff --git a/tests/inkscape-v2.patch.md b/tests/custom-pages/inkscape-v2.patch.md similarity index 100% rename from tests/inkscape-v2.patch.md rename to tests/custom-pages/inkscape-v2.patch.md diff --git a/tests/lib.rs b/tests/lib.rs index 885989f..99e736f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,8 +1,9 @@ //! Integration tests. use std::{ - fs::{create_dir_all, File}, - io::Write, + fs::{self, create_dir_all, File}, + io::{self, Write}, + path::{Path, PathBuf}, process::Command, time::{Duration, SystemTime}, }; @@ -23,7 +24,6 @@ struct TestEnv { pub cache_dir: TempDir, pub custom_pages_dir: TempDir, pub config_dir: TempDir, - pub input_dir: TempDir, pub default_features: bool, pub features: Vec, } @@ -43,10 +43,6 @@ impl TestEnv { .prefix(".tldr.test.custom-pages") .tempdir() .unwrap(), - input_dir: TempfileBuilder::new() - .prefix(".tldr.test.input") - .tempdir() - .unwrap(), default_features: true, features: vec![], } @@ -57,8 +53,7 @@ impl TestEnv { let config_file_name = self.config_dir.path().join("config.toml"); println!("Config path: {config_file_name:?}"); - let mut config_file = File::create(&config_file_name).unwrap(); - config_file.write_all(content.as_ref().as_bytes()).unwrap(); + fs::write(config_file_name, content.as_ref().as_bytes()).unwrap(); } /// Add entry for that environment to the "common" pages. @@ -130,6 +125,49 @@ impl TestEnv { ); cmd } + + fn install_default_cache(self) -> Self { + copy_recursively( + &PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "tests", "cache"]), + &self.cache_dir.path().join(TLDR_PAGES_DIR), + ) + .expect("Failed to copy the cache to the test environment"); + + self + } + + fn install_default_custom_pages(self) -> Self { + copy_recursively( + &PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "tests", "custom-pages"]), + self.custom_pages_dir.path(), + ) + .expect("Failed to copy the custom pages to the test environment"); + + self.write_custom_pages_config() + } + + fn write_custom_pages_config(self) -> Self { + self.write_config(format!( + "[directories]\ncustom_pages_dir = '{}'", + self.custom_pages_dir.path().to_str().unwrap() + )); + + self + } +} + +fn copy_recursively(source: &Path, destination: &Path) -> io::Result<()> { + if source.is_dir() { + fs::create_dir_all(destination)?; + for entry in fs::read_dir(source)? { + let entry = entry?; + copy_recursively(&entry.path(), &destination.join(entry.file_name()))?; + } + } else { + fs::copy(source, destination)?; + } + + Ok(()) } #[test] @@ -212,14 +250,7 @@ fn test_quiet_cache() { #[test] fn test_quiet_failures() { - let testenv = TestEnv::new(); - - testenv - .command() - .args(["--update", "-q"]) - .assert() - .success() - .stdout(is_empty()); + let testenv = TestEnv::new().install_default_cache(); testenv .command() @@ -231,14 +262,7 @@ fn test_quiet_failures() { #[test] fn test_quiet_old_cache() { - let testenv = TestEnv::new(); - - testenv - .command() - .args(["--update", "-q"]) - .assert() - .success() - .stdout(is_empty()); + let testenv = TestEnv::new().install_default_cache(); filetime::set_file_mtime( testenv.cache_dir.path().join(TLDR_PAGES_DIR), @@ -248,14 +272,14 @@ fn test_quiet_old_cache() { testenv .command() - .args(["tldr"]) + .args(["which"]) .assert() .success() .stderr(contains("The cache hasn't been updated for ")); testenv .command() - .args(["tldr", "--quiet"]) + .args(["which", "--quiet"]) .assert() .success() .stderr(contains("The cache hasn't been updated for ").not()); @@ -359,6 +383,8 @@ fn test_setup_seed_config() { .assert() .success() .stderr(contains("Successfully created seed config file here")); + + assert!(testenv.config_dir.path().join("config.toml").is_file()); } #[test] @@ -431,11 +457,9 @@ fn test_os_specific_page() { #[test] fn test_markdown_rendering() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().install_default_cache(); - testenv.add_entry("which", include_str!("which-markdown.expected")); - - let expected = include_str!("which-markdown.expected"); + let expected = include_str!("cache/pages/common/which.md"); testenv .command() .args(["--raw", "which"]) @@ -444,23 +468,13 @@ fn test_markdown_rendering() { .stdout(diff(expected)); } -fn _test_correct_rendering( - input_file: &str, - filename: &str, - expected: &'static str, - color_option: &str, -) { - let testenv = TestEnv::new(); - - // Create input file - let file_path = testenv.input_dir.path().join(filename); - println!("Testfile path: {file_path:?}"); - let mut file = File::create(&file_path).unwrap(); - file.write_all(input_file.as_bytes()).unwrap(); +fn _test_correct_rendering(page: &str, expected: &'static str, additional_args: &[&str]) { + let testenv = TestEnv::new().install_default_cache(); testenv .command() - .args(["--color", color_option, "-f", file_path.to_str().unwrap()]) + .args(additional_args) + .arg(page) .assert() .success() .stdout(diff(expected)); @@ -470,10 +484,9 @@ fn _test_correct_rendering( #[test] fn test_correct_rendering_v1() { _test_correct_rendering( - include_str!("inkscape-v1.md"), - "inkscape-v1.md", - include_str!("inkscape-default.expected"), - "always", + "inkscape-v1", + include_str!("rendered/inkscape-default.expected"), + &["--color", "always"], ); } @@ -481,10 +494,9 @@ fn test_correct_rendering_v1() { #[test] fn test_correct_rendering_v2() { _test_correct_rendering( - include_str!("inkscape-v2.md"), - "inkscape-v2.md", - include_str!("inkscape-default.expected"), - "always", + "inkscape-v2", + include_str!("rendered/inkscape-default.expected"), + &["--color", "always"], ); } @@ -493,10 +505,9 @@ fn test_correct_rendering_v2() { /// will not use styling since output is not stdout. fn test_rendering_color_auto() { _test_correct_rendering( - include_str!("inkscape-v2.md"), - "inkscape-v2.md", - include_str!("inkscape-default-no-color.expected"), - "auto", + "inkscape-v2", + include_str!("rendered/inkscape-default-no-color.expected"), + &["--color", "auto"], ); } @@ -504,51 +515,39 @@ fn test_rendering_color_auto() { /// An end-to-end integration test for direct file rendering with the `--color never` option. fn test_rendering_color_never() { _test_correct_rendering( - include_str!("inkscape-v2.md"), - "inkscape-v2.md", - include_str!("inkscape-default-no-color.expected"), - "never", + "inkscape-v2", + include_str!("rendered/inkscape-default-no-color.expected"), + &["--color", "never"], ); } #[test] fn test_rendering_i18n() { _test_correct_rendering( - include_str!("chmod.ru.md"), - "chmod.ru.md", - include_str!("chmod.ru.expected"), - "always", + "apt", + include_str!("rendered/apt.ja.expected"), + &["--color", "always", "--language", "ja"], ); } /// An end-to-end integration test for rendering with custom syntax config. #[test] fn test_correct_rendering_with_config() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().install_default_cache(); // Setup config file // TODO should be config::CONFIG_FILE_NAME - let config_file_path = testenv.config_dir.path().join("config.toml"); - println!("Config path: {config_file_path:?}"); + fs::write( + testenv.config_dir.path().join("config.toml"), + include_bytes!("config.toml"), + ) + .unwrap(); - let mut config_file = File::create(&config_file_path).unwrap(); - config_file - .write_all(include_bytes!("config.toml")) - .unwrap(); - - // Create input file - let file_path = testenv.input_dir.path().join("inkscape-v2.md"); - println!("Testfile path: {file_path:?}"); - - let mut file = File::create(&file_path).unwrap(); - file.write_all(include_bytes!("inkscape-v2.md")).unwrap(); - - // Load expected output - let expected = include_str!("inkscape-with-config.expected"); + let expected = include_str!("rendered/inkscape-with-config.expected"); testenv .command() - .args(["--color", "always", "-f", file_path.to_str().unwrap()]) + .args(["--color", "always", "inkscape-v2"]) .assert() .success() .stdout(diff(expected)); @@ -556,14 +555,7 @@ fn test_correct_rendering_with_config() { #[test] fn test_spaces_find_command() { - let testenv = TestEnv::new(); - - testenv - .command() - .args(["--update"]) - .assert() - .success() - .stderr(contains("Successfully updated cache.")); + let testenv = TestEnv::new().install_default_cache(); testenv .command() @@ -574,14 +566,7 @@ fn test_spaces_find_command() { #[test] fn test_pager_flag_enable() { - let testenv = TestEnv::new(); - - testenv - .command() - .args(["--update"]) - .assert() - .success() - .stderr(contains("Successfully updated cache.")); + let testenv = TestEnv::new().install_default_cache(); testenv .command() @@ -657,13 +642,7 @@ fn test_multiple_platform_command_search_not_found() { #[test] fn test_list_flag_rendering() { - let testenv = TestEnv::new(); - - // set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); + let testenv = TestEnv::new().write_custom_pages_config(); testenv .command() @@ -699,13 +678,7 @@ fn test_list_flag_rendering() { #[test] fn test_multi_platform_list_flag_rendering() { - let testenv = TestEnv::new(); - - // set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); + let testenv = TestEnv::new().write_custom_pages_config(); testenv.add_entry("common", ""); @@ -829,21 +802,18 @@ fn test_autoupdate_cache() { /// End-end test to ensure .page.md files overwrite pages in cache_dir #[test] fn test_custom_page_overwrites() { - let testenv = TestEnv::new(); - - // set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); + let testenv = TestEnv::new().write_custom_pages_config(); // Add file that should be ignored to the cache dir testenv.add_entry("inkscape-v2", ""); // Add .page.md file to custom_pages_dir - testenv.add_page_entry("inkscape-v2", include_str!("inkscape-v2.md")); + testenv.add_page_entry( + "inkscape-v2", + include_str!("cache/pages/common/inkscape-v2.md"), + ); // Load expected output - let expected = include_str!("inkscape-default-no-color.expected"); + let expected = include_str!("rendered/inkscape-default-no-color.expected"); testenv .command() @@ -856,21 +826,12 @@ fn test_custom_page_overwrites() { /// End-End test to ensure that .patch.md files are appended to pages in the cache_dir #[test] fn test_custom_patch_appends_to_common() { - let testenv = TestEnv::new(); - - // set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); - - // Add page to the cache dir - testenv.add_entry("inkscape-v2", include_str!("inkscape-v2.md")); - // Add .page.md file to custom_pages_dir - testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch.md")); + let testenv = TestEnv::new() + .install_default_cache() + .install_default_custom_pages(); // Load expected output - let expected = include_str!("inkscape-patched-no-color.expected"); + let expected = include_str!("rendered/inkscape-patched-no-color.expected"); testenv .command() @@ -884,23 +845,18 @@ fn test_custom_patch_appends_to_common() { /// Maybe this interaction should change but I put this test here for the coverage #[test] fn test_custom_patch_does_not_append_to_custom() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new() + .install_default_cache() + .install_default_custom_pages(); - // set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); - - testenv.add_entry("test", ""); - - // Add page to the cache dir - testenv.add_page_entry("inkscape-v2", include_str!("inkscape-v2.md")); - // Add .page.md file to custom_pages_dir - testenv.add_patch_entry("inkscape-v2", include_str!("inkscape-v2.patch.md")); + // In addition to the page in the cache, add the same page as a custom page. + testenv.add_page_entry( + "inkscape-v2", + include_str!("cache/pages/common/inkscape-v2.md"), + ); // Load expected output - let expected = include_str!("inkscape-default-no-color.expected"); + let expected = include_str!("rendered/inkscape-default-no-color.expected"); testenv .command() @@ -913,13 +869,7 @@ fn test_custom_patch_does_not_append_to_custom() { #[test] #[cfg(target_os = "windows")] fn test_pager_warning() { - let testenv = TestEnv::new(); - testenv - .command() - .args(["--update"]) - .assert() - .success() - .stderr(contains("Successfully updated cache.")); + let testenv = TestEnv::new().install_default_cache(); // Regular call should not show a "pager flag not available on windows" warning testenv @@ -960,15 +910,14 @@ fn test_lowercased_page_lookup() { /// Regression test for #219: It should be possible to combine `--raw` and `-f`. #[test] fn test_raw_render_file() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().install_default_cache(); - // Create input file - let file_path = testenv.input_dir.path().join("inkscape.md"); - let mut file = File::create(&file_path).unwrap(); - file.write_all(include_bytes!("inkscape-v1.md")).unwrap(); - - // Base args - let mut args = vec!["--color", "never", "-f", file_path.to_str().unwrap()]; + let path = testenv + .cache_dir + .path() + .join(TLDR_PAGES_DIR) + .join("pages/common/inkscape-v1.md"); + let mut args = vec!["--color", "never", "-f", &path.to_str().unwrap()]; // Default render testenv @@ -976,7 +925,9 @@ fn test_raw_render_file() { .args(&args) .assert() .success() - .stdout(diff(include_str!("inkscape-default-no-color.expected"))); + .stdout(diff(include_str!( + "rendered/inkscape-default-no-color.expected" + ))); // Raw render args.push("--raw"); @@ -985,5 +936,5 @@ fn test_raw_render_file() { .args(&args) .assert() .success() - .stdout(diff(include_str!("inkscape-v1.md"))); + .stdout(diff(include_str!("cache/pages/common/inkscape-v1.md"))); } diff --git a/tests/rendered/apt.ja.expected b/tests/rendered/apt.ja.expected new file mode 100644 index 0000000..22424e3 --- /dev/null +++ b/tests/rendered/apt.ja.expected @@ -0,0 +1,37 @@ + + Debian系ディストリビューションで使われるパッケージ管理システムです。 + Ubuntuのバージョンが16.04か、それ以降で対話モードを使う場合`apt-get`の代わりとして使用します。 + 詳しくはこちら: + + 利用可能なパーケージとバージョンのリストの更新(他の`apt`コマンドの前での実行を推奨): + + sudo apt update + + 指定されたパッケージの検索: + + apt search パッケージ + + パッケージの情報を出力: + + apt show パッケージ + + パッケージのインストール、または利用可能な最新バージョンに更新: + + sudo apt install パッケージ + + パッケージの削除(`sudo apt remove --purge`の場合設定ファイルも削除): + + sudo apt remove パッケージ + + インストールされている全てのパッケージを最新のバージョンにアップグレード: + + sudo apt upgrade + + インストールできるすべてのパッケージを表示: + + apt list + + インストールされた全てのパッケージを表示(依存関係も表示): + + apt list --installed + diff --git a/tests/inkscape-default-no-color.expected b/tests/rendered/inkscape-default-no-color.expected similarity index 100% rename from tests/inkscape-default-no-color.expected rename to tests/rendered/inkscape-default-no-color.expected diff --git a/tests/inkscape-default.expected b/tests/rendered/inkscape-default.expected similarity index 100% rename from tests/inkscape-default.expected rename to tests/rendered/inkscape-default.expected diff --git a/tests/inkscape-patched-no-color.expected b/tests/rendered/inkscape-patched-no-color.expected similarity index 100% rename from tests/inkscape-patched-no-color.expected rename to tests/rendered/inkscape-patched-no-color.expected diff --git a/tests/inkscape-with-config.expected b/tests/rendered/inkscape-with-config.expected similarity index 100% rename from tests/inkscape-with-config.expected rename to tests/rendered/inkscape-with-config.expected From fc19206029b14042b9fdac6ed03b92223c9d115f Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 1 Jan 2025 23:17:49 +0100 Subject: [PATCH 137/196] Add `ignore-online-tests` feature Since these tests require internet access, they are undesirable in reproducible builds [1] (and in general, I guess). The overall goal is to shrink this list to a minimum. At some point we might remove the feature again and ignore online tests by default. Before putting much thought into refactoring the remaining tests, we should wait until we have introduced the `updates.archive_url` option. Then, we could run a local webserver that serves a known file. Until then, having the feature already helps discourage using `--update` in tests that don't need it and allows for quicker test execution locally if wanted. - [1]: https://github.com/NixOS/nixpkgs/blob/edf04b75c13c2ac0e54df5ec5c543e300f76f1c9/pkgs/by-name/te/tealdeer/package.nix#L34-L44 --- Cargo.toml | 2 ++ tests/lib.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aa1f423..bd0d07a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,8 @@ native-roots = ["reqwest/rustls-tls-native-roots"] webpki-roots = ["reqwest/rustls-tls-webpki-roots"] native-tls = ["reqwest/native-tls"] +ignore-online-tests = [] + [profile.release] strip = true opt-level = 3 diff --git a/tests/lib.rs b/tests/lib.rs index 99e736f..fc99688 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -186,6 +186,7 @@ fn test_missing_cache() { .stderr(contains("Page cache not found. Please run `tldr --update`")); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_update_cache_default_features() { let testenv = TestEnv::new(); @@ -207,6 +208,7 @@ fn test_update_cache_default_features() { testenv.command().args(["sl"]).assert().success(); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_update_cache_rustls_webpki() { let testenv = TestEnv::new() @@ -230,6 +232,7 @@ fn test_update_cache_rustls_webpki() { testenv.command().args(["sl"]).assert().success(); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_quiet_cache() { let testenv = TestEnv::new(); @@ -285,6 +288,7 @@ fn test_quiet_old_cache() { .stderr(contains("The cache hasn't been updated for ").not()); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_create_cache_directory_path() { let testenv = TestEnv::new(); @@ -297,7 +301,7 @@ fn test_create_cache_directory_path() { assert!(!internal_cache_dir.exists()); command - .arg("-u") + .arg("--update") .assert() .success() .stderr(contains(format!( @@ -309,6 +313,7 @@ fn test_create_cache_directory_path() { assert!(internal_cache_dir.is_dir()); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_cache_location_not_a_directory() { let testenv = TestEnv::new(); @@ -320,7 +325,7 @@ fn test_cache_location_not_a_directory() { command.env(CACHE_DIR_ENV_VAR, internal_file.to_str().unwrap()); command - .arg("-u") + .arg("--update") .assert() .failure() .stderr(contains(format!( @@ -743,6 +748,7 @@ fn test_multi_platform_list_flag_rendering() { .stdout("common\ndel\ndir\nls\nrm\nwinux\n"); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_autoupdate_cache() { let testenv = TestEnv::new(); From e7b434d06ab039a5ade2a6ce62742cc935bee9a6 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Thu, 2 Jan 2025 00:00:29 +0100 Subject: [PATCH 138/196] Prefer config file over TEALDEER_CACHE_DIR in integration tests --- tests/lib.rs | 110 ++++++++++++----------- tests/{config.toml => style-config.toml} | 8 -- 2 files changed, 56 insertions(+), 62 deletions(-) rename tests/{config.toml => style-config.toml} (73%) diff --git a/tests/lib.rs b/tests/lib.rs index fc99688..a397285 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -15,9 +15,6 @@ use predicates::{ }; use tempfile::{Builder as TempfileBuilder, 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 { @@ -30,7 +27,7 @@ struct TestEnv { impl TestEnv { fn new() -> Self { - TestEnv { + let this = TestEnv { cache_dir: TempfileBuilder::new() .prefix(".tldr.test.cache") .tempdir() @@ -45,15 +42,29 @@ impl TestEnv { .unwrap(), default_features: true, features: vec![], - } + }; + + this.append_to_config(format!( + "directories.cache_dir = '{}'\n", + this.cache_dir.path().to_str().unwrap(), + )); + + this } - /// Write `content` to "config.toml" in the `config_dir` directory - fn write_config(&self, content: impl AsRef) { - let config_file_name = self.config_dir.path().join("config.toml"); - println!("Config path: {config_file_name:?}"); + fn append_to_config(&self, content: impl AsRef) { + File::options() + .create(true) + .append(true) + .open(self.config_dir.path().join("config.toml")) + .expect("Failed to open config file") + .write_all(content.as_ref().as_bytes()) + .expect("Failed to append to config file."); + } - fs::write(config_file_name, content.as_ref().as_bytes()).unwrap(); + fn remove_initial_config(self) -> Self { + let _ = fs::remove_file(self.config_dir.path().join("config.toml")); + self } /// Add entry for that environment to the "common" pages. @@ -71,24 +82,21 @@ impl TestEnv { .join(os); create_dir_all(&dir).unwrap(); - let mut file = File::create(dir.join(format!("{name}.md"))).unwrap(); - file.write_all(contents.as_bytes()).unwrap(); + fs::write(dir.join(format!("{name}.md")), contents.as_bytes()).unwrap(); } /// Add custom patch entry to the custom_pages_dir fn add_page_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(dir.join(format!("{name}.page.md"))).unwrap(); - file.write_all(contents.as_bytes()).unwrap(); + fs::write(dir.join(format!("{name}.page.md")), contents.as_bytes()).unwrap(); } /// Add custom patch entry to the custom_pages_dir fn add_patch_entry(&self, name: &str, contents: &str) { let dir = self.custom_pages_dir.path(); create_dir_all(dir).unwrap(); - let mut file = File::create(dir.join(format!("{name}.patch.md"))).unwrap(); - file.write_all(contents.as_bytes()).unwrap(); + fs::write(dir.join(format!("{name}.patch.md")), contents.as_bytes()).unwrap(); } /// Disable default features. @@ -118,7 +126,6 @@ impl TestEnv { } let run = build.run().expect("Failed to build tealdeer for testing"); let mut cmd = run.command(); - cmd.env(CACHE_DIR_ENV_VAR, self.cache_dir.path().to_str().unwrap()); cmd.env( "TEALDEER_CONFIG_DIR", self.config_dir.path().to_str().unwrap(), @@ -147,8 +154,8 @@ impl TestEnv { } fn write_custom_pages_config(self) -> Self { - self.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", + self.append_to_config(format!( + "directories.custom_pages_dir = '{}'\n", self.custom_pages_dir.path().to_str().unwrap() )); @@ -291,12 +298,15 @@ fn test_quiet_old_cache() { #[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_create_cache_directory_path() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().remove_initial_config(); let cache_dir = testenv.cache_dir.path(); let internal_cache_dir = cache_dir.join("internal"); + testenv.append_to_config(format!( + "directories.cache_dir = '{}'\n", + internal_cache_dir.to_str().unwrap() + )); let mut command = testenv.command(); - command.env(CACHE_DIR_ENV_VAR, internal_cache_dir.to_str().unwrap()); assert!(!internal_cache_dir.exists()); @@ -316,30 +326,30 @@ fn test_create_cache_directory_path() { #[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_cache_location_not_a_directory() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().remove_initial_config(); let cache_dir = testenv.cache_dir.path(); let internal_file = cache_dir.join("internal"); File::create(&internal_file).unwrap(); - let mut command = testenv.command(); - command.env(CACHE_DIR_ENV_VAR, internal_file.to_str().unwrap()); + testenv.append_to_config(format!( + "directories.cache_dir = '{}'\n", + internal_file.to_str().unwrap() + )); - command + testenv + .command() .arg("--update") .assert() .failure() .stderr(contains(format!( "Cache directory path `{}` is not a directory", internal_file.display(), - ))) - .stderr(contains( - "Warning: The $TEALDEER_CACHE_DIR env variable is deprecated", - )); + ))); } #[test] fn test_cache_location_source() { - let testenv = TestEnv::new(); + let testenv = TestEnv::new().remove_initial_config(); let default_cache_dir = testenv.cache_dir.path(); let tmp_cache_dir = TempfileBuilder::new() .prefix(".tldr.test.cache_dir") @@ -348,7 +358,6 @@ fn test_cache_location_source() { // Source: Default (OS convention) let mut command = testenv.command(); - command.env_remove(CACHE_DIR_ENV_VAR); command .arg("--show-paths") .assert() @@ -357,9 +366,8 @@ fn test_cache_location_source() { // Source: Config variable let mut command = testenv.command(); - command.env_remove(CACHE_DIR_ENV_VAR); - testenv.write_config(format!( - "[directories]\ncache_dir = '{}'", + testenv.append_to_config(format!( + "directories.cache_dir = '{}'\n", tmp_cache_dir.path().to_str().unwrap(), )); command @@ -370,7 +378,7 @@ fn test_cache_location_source() { // Source: Env var let mut command = testenv.command(); - command.env(CACHE_DIR_ENV_VAR, default_cache_dir.to_str().unwrap()); + command.env("TEALDEER_CACHE_DIR", default_cache_dir.to_str().unwrap()); command .arg("--show-paths") .assert() @@ -382,6 +390,15 @@ fn test_cache_location_source() { fn test_setup_seed_config() { let testenv = TestEnv::new(); + testenv + .command() + .args(["--seed-config"]) + .assert() + .failure() + .stderr(contains("A configuration file already exists")); + + let testenv = testenv.remove_initial_config(); + testenv .command() .args(["--seed-config"]) @@ -429,11 +446,7 @@ fn test_show_paths() { .unwrap(), ))); - // Set custom pages directory - testenv.write_config(format!( - "[directories]\ncustom_pages_dir = '{}'", - testenv.custom_pages_dir.path().to_str().unwrap() - )); + let testenv = testenv.write_custom_pages_config(); // Now ensure that this path is contained in the output testenv @@ -540,13 +553,7 @@ fn test_rendering_i18n() { fn test_correct_rendering_with_config() { let testenv = TestEnv::new().install_default_cache(); - // Setup config file - // TODO should be config::CONFIG_FILE_NAME - fs::write( - testenv.config_dir.path().join("config.toml"), - include_bytes!("config.toml"), - ) - .unwrap(); + testenv.append_to_config(include_str!("style-config.toml")); let expected = include_str!("rendered/inkscape-with-config.expected"); @@ -761,15 +768,10 @@ fn test_autoupdate_cache() { .failure() .stderr(contains("Page 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_PAGES_DIR); - // Activate automatic updates, set the auto-update interval to 24 hours - let mut config_file = File::create(config_file_path).unwrap(); - config_file - .write_all(b"[updates]\nauto_update = true\nauto_update_interval_hours = 24") - .unwrap(); - config_file.flush().unwrap(); + testenv + .append_to_config("updates.auto_update = true\nupdates.auto_update_interval_hours = 24\n"); // Helper function that runs `tldr --list` and asserts that the cache is automatically updated // or not, depending on the value of `expected`. diff --git a/tests/config.toml b/tests/style-config.toml similarity index 73% rename from tests/config.toml rename to tests/style-config.toml index 3b90d90..c68f2cc 100644 --- a/tests/config.toml +++ b/tests/style-config.toml @@ -19,11 +19,3 @@ underline = false underline = true bold = false italic = true - -[display] -use_pager = false -compact = false - -[updates] -auto_update = false -auto_update_interval_hours = 720 From dbab55a2b454b7fd0fa84f8e2cfda190d893124d Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Thu, 2 Jan 2025 23:41:09 +0100 Subject: [PATCH 139/196] Use only one test thread Otherwise the builds made by `TestEnv::command` will conflict with each other. This manifested itself on Windows with > linking with `link.exe` failed: exit code: 1104 > LINK : fatal error LNK1104: cannot open file '...' --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9274a0f..dee3fd8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - name: Build with logging and webpki roots run: cargo build --features logging,webpki-roots --no-default-features - name: Run tests - run: cargo test + run: cargo test -- --test-threads 1 clippy: name: run clippy lints From 00c777812569f2fc0d1e285289106ebb1b3da5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Kafka?= <6414091+MatejKafka@users.noreply.github.com> Date: Sun, 5 Jan 2025 00:17:44 +0100 Subject: [PATCH 140/196] Resolve paths in config [directories] relative to the config directory (#395) --- src/config.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 454fbf5..254b56d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -295,7 +295,7 @@ impl Config { /// /// For this, some values need to be converted to other types and some /// defaults need to be set (sometimes based on env variables). - fn from_raw(raw_config: RawConfig) -> Result { + fn from_raw(raw_config: RawConfig, relative_path_root: &Path) -> Result { let style = raw_config.style.into(); let display = raw_config.display.into(); let updates = raw_config.updates.into(); @@ -316,7 +316,9 @@ impl Config { } else if let Some(config_value) = raw_config.directories.cache_dir { // If the user explicitly configured a cache directory, use that. PathWithSource { - path: config_value, + // Resolve possible relative path. It would be nicer to clean up the path, but Rust stdlib + // does not give any method for that that does not need the paths to exist. + path: relative_path_root.join(config_value), source: PathSource::ConfigFile, } } else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) { @@ -333,7 +335,8 @@ impl Config { .directories .custom_pages_dir .map(|path| PathWithSource { - path, + // Resolve possible relative path. + path: relative_path_root.join(path), source: PathSource::ConfigFile, }) .or_else(|| { @@ -382,8 +385,12 @@ impl Config { RawConfig::new() }; - // Convert to config - let mut config = Self::from_raw(raw_config).context("Could not process raw config")?; + // Safe to unwrap, it's a file path, so it should have a directory component + let config_file_dir = config_file_path.parent().unwrap(); + + // Convert to config, resolve relative paths from the config file dir + let mut config = + Self::from_raw(raw_config, config_file_dir).context("Could not process raw config")?; // Potentially override styles if !enable_styles { @@ -474,3 +481,21 @@ fn test_serialize_deserialize() { let deserialized: RawConfig = toml::from_str(&serialized).unwrap(); assert_eq!(raw_config, deserialized); } + +#[test] +fn test_relative_path_resolution() { + let mut raw_config = RawConfig::new(); + raw_config.directories.cache_dir = Some("../cache".into()); + raw_config.directories.custom_pages_dir = Some("../custom_pages".into()); + + let config = Config::from_raw(raw_config, Path::new("/path/to/config")).unwrap(); + + assert_eq!( + config.directories.cache_dir.path(), + Path::new("/path/to/config/../cache") + ); + assert_eq!( + config.directories.custom_pages_dir.unwrap().path(), + Path::new("/path/to/config/../custom_pages") + ); +} From b9f116d629c2b9916991f5cd41b74cfac835b0fa Mon Sep 17 00:00:00 2001 From: Christoph Loy Date: Sun, 12 Jan 2025 11:50:32 +0100 Subject: [PATCH 141/196] Add `common` platform to CLI (#401) --- docs/src/usage.txt | 2 +- src/cache.rs | 13 ++++++------- src/main.rs | 24 +++++++++++++++++------- src/types.rs | 4 ++++ tests/lib.rs | 16 ++++++++++++++++ 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 5129fbe..b6af6c3 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -11,7 +11,7 @@ Options: -f, --render Render a specific markdown file -p, --platform Override the operating system, can be specified multiple times in order of preference [possible values: linux, macos, sunos, windows, android, - freebsd, netbsd, openbsd] + freebsd, netbsd, openbsd, common] -L, --language Override the language -u, --update Update the local cache --no-auto-update If auto update is configured, disable it for this run diff --git a/src/cache.rs b/src/cache.rs index a4496ad..d46d29b 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -221,6 +221,7 @@ impl Cache { PlatformType::FreeBsd => "freebsd", PlatformType::NetBsd => "netbsd", PlatformType::OpenBsd => "openbsd", + PlatformType::Common => "common", } } @@ -292,9 +293,7 @@ impl Cache { } } - // Did not find platform specific results, fall back to "common" - Self::find_page_for_platform(&page_filename, &pages_dir, "common", &lang_dirs) - .map(|page| PageLookupResult::with_page(page).with_optional_patch(patch_path)) + None } /// Return the available pages. @@ -311,14 +310,14 @@ impl Cache { .collect(); // Closure that allows the WalkDir instance to traverse platform - // specific and common page directories, but not others. + // relevant page directories, but not others. let should_walk = |entry: &DirEntry| -> bool { let file_type = entry.file_type(); let Some(file_name) = entry.file_name().to_str() else { return false; }; if file_type.is_dir() { - return file_name == "common" || platform_dirs.contains(&file_name); + return platform_dirs.contains(&file_name); } else if file_type.is_file() { return true; } @@ -342,7 +341,7 @@ impl Cache { .map(str::to_string) }; - // Recursively walk through common and (if applicable) platform specific directory + // Recursively walk through platform specific directory let mut pages = WalkDir::new(platforms_dir) .min_depth(1) // Skip root directory .into_iter() @@ -365,7 +364,7 @@ impl Cache { .path() .file_name() .and_then(OsStr::to_str) - .map_or(false, |file_name| file_name.ends_with(".page.md")) + .is_some_and(|file_name| file_name.ends_with(".page.md")) }; let custom_pages = WalkDir::new(custom_pages_dir) diff --git a/src/main.rs b/src/main.rs index 5e6e739..8540705 100644 --- a/src/main.rs +++ b/src/main.rs @@ -282,11 +282,7 @@ fn main() { create_config_and_exit(enable_styles); } - let fallback_platforms: &[PlatformType] = &[PlatformType::current()]; - let platforms = args - .platforms - .as_ref() - .map_or(fallback_platforms, Vec::as_slice); + let platforms = compute_platforms(args.platforms.as_ref()); // If a local file was passed in, render it and exit if let Some(file) = args.render { @@ -332,7 +328,7 @@ fn main() { .map(PathWithSource::path); println!( "{}", - cache.list_pages(custom_pages_dir, platforms).join("\n") + cache.list_pages(custom_pages_dir, &platforms).join("\n") ); process::exit(0); } @@ -358,7 +354,7 @@ fn main() { .custom_pages_dir .as_ref() .map(PathWithSource::path), - platforms, + &platforms, ) { if let Err(ref e) = print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) @@ -384,6 +380,20 @@ fn main() { } } +/// Returns the passed or default platform types and appends `PlatformType::Common` as fallback. +fn compute_platforms(platforms: Option<&Vec>) -> Vec { + match platforms { + Some(p) => { + let mut result = p.clone(); + if !result.contains(&PlatformType::Common) { + result.push(PlatformType::Common); + } + result + } + None => vec![PlatformType::current(), PlatformType::Common], + } +} + #[cfg(test)] mod test { use crate::get_languages; diff --git a/src/types.rs b/src/types.rs index 8a111a6..416d267 100644 --- a/src/types.rs +++ b/src/types.rs @@ -16,6 +16,7 @@ pub enum PlatformType { FreeBsd, NetBsd, OpenBsd, + Common, } impl fmt::Display for PlatformType { @@ -29,6 +30,7 @@ impl fmt::Display for PlatformType { Self::FreeBsd => write!(f, "FreeBSD"), Self::NetBsd => write!(f, "NetBSD"), Self::OpenBsd => write!(f, "OpenBSD"), + Self::Common => write!(f, "Common"), } } } @@ -44,6 +46,7 @@ impl clap::ValueEnum for PlatformType { Self::FreeBsd, Self::NetBsd, Self::OpenBsd, + Self::Common, ] } @@ -57,6 +60,7 @@ impl clap::ValueEnum for PlatformType { Self::FreeBsd => Some(clap::builder::PossibleValue::new("freebsd")), Self::NetBsd => Some(clap::builder::PossibleValue::new("netbsd")), Self::OpenBsd => Some(clap::builder::PossibleValue::new("openbsd")), + Self::Common => Some(clap::builder::PossibleValue::new("common")), } } } diff --git a/tests/lib.rs b/tests/lib.rs index a397285..feb82a0 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -652,6 +652,22 @@ fn test_multiple_platform_command_search_not_found() { .stderr(contains("Page `windows-only` not found in cache.")); } +#[test] +fn test_common_platform_is_used_as_fallback() { + let testenv = TestEnv::new(); + testenv.add_entry("in-common", "this command comes from common"); + + // No platform specified + testenv.command().args(["in-common"]).assert().success(); + + // Platform specified + testenv + .command() + .args(["--platform", "linux", "in-common"]) + .assert() + .success(); +} + #[test] fn test_list_flag_rendering() { let testenv = TestEnv::new().write_custom_pages_config(); From 09d44110f8be8fa175172e564d2a7145f59ef3de Mon Sep 17 00:00:00 2001 From: Christoph Loy Date: Sun, 12 Jan 2025 12:04:22 +0100 Subject: [PATCH 142/196] Add tests for osx/macos alias (#407) Co-authored-by: Niklas Mohrin --- tests/lib.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/lib.rs b/tests/lib.rs index feb82a0..63edca6 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -652,6 +652,34 @@ fn test_multiple_platform_command_search_not_found() { .stderr(contains("Page `windows-only` not found in cache.")); } +#[test] +fn test_macos_is_alias_for_osx() { + let testenv = TestEnv::new(); + testenv.add_os_entry("osx", "maconly", "this command only exists on mac"); + + testenv + .command() + .args(["--platform", "macos", "maconly"]) + .assert() + .success(); + testenv + .command() + .args(["--platform", "osx", "maconly"]) + .assert() + .success(); + + testenv + .command() + .args(["--platform", "macos", "--list"]) + .assert() + .stdout("maconly\n"); + testenv + .command() + .args(["--platform", "osx", "--list"]) + .assert() + .stdout("maconly\n"); +} + #[test] fn test_common_platform_is_used_as_fallback() { let testenv = TestEnv::new(); From 120e2a92c20c4a804f6e8b356f6f74b914c80efe Mon Sep 17 00:00:00 2001 From: Predrag Minic Date: Sun, 12 Jan 2025 03:24:02 -0800 Subject: [PATCH 143/196] Add configuration option for `archive_source` (#337) This allows for specifying a custom archive URL as an alternative approach to Custom Pages. Co-authored-by: Niklas Mohrin --- docs/src/config_updates.md | 8 ++++++++ src/cache.rs | 6 ++++-- src/config.rs | 11 ++++++++++- src/main.rs | 8 ++++---- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index f010cc6..2678d4c 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -24,3 +24,11 @@ is set to `false`. auto_update = true auto_update_interval_hours = 24 +### archive_source + +URL for the location of the tldr pages archive. By default the pages are +fetched from the latest `tldr-pages/tldr` GitHub release. + + [updates] + archive_source = https://my-company.example.com/tldr/ + diff --git a/src/cache.rs b/src/cache.rs index d46d29b..9d27011 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -163,11 +163,13 @@ impl Cache { } /// Update the pages cache from the specified URL. - pub fn update(&self, archive_url: &str) -> Result<()> { + pub fn update(&self, archive_source: &str) -> Result<()> { self.ensure_cache_dir_exists()?; + let archive_url = format!("{}/tldr.zip", archive_source); + // First, download the compressed data - let bytes: Vec = Self::download(archive_url)?; + let bytes: Vec = Self::download(&archive_url)?; // Decompress the response body into an `Archive` let mut archive = ZipArchive::new(Cursor::new(bytes)) diff --git a/src/config.rs b/src/config.rs index 254b56d..de86817 100644 --- a/src/config.rs +++ b/src/config.rs @@ -166,12 +166,18 @@ const fn default_auto_update_interval_hours() -> u64 { DEFAULT_UPDATE_INTERVAL_HOURS } +fn default_archive_source() -> String { + "https://github.com/tldr-pages/tldr/releases/latest/download/".to_owned() +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] struct RawUpdatesConfig { #[serde(default)] pub auto_update: bool, #[serde(default = "default_auto_update_interval_hours")] pub auto_update_interval_hours: u64, + #[serde(default = "default_archive_source")] + pub archive_source: String, } impl Default for RawUpdatesConfig { @@ -179,6 +185,7 @@ impl Default for RawUpdatesConfig { Self { auto_update: false, auto_update_interval_hours: DEFAULT_UPDATE_INTERVAL_HOURS, + archive_source: default_archive_source(), } } } @@ -190,6 +197,7 @@ impl From for UpdatesConfig { auto_update_interval: Duration::from_secs( raw_updates_config.auto_update_interval_hours * 3600, ), + archive_source: raw_updates_config.archive_source, } } } @@ -252,10 +260,11 @@ pub struct DisplayConfig { pub use_pager: bool, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct UpdatesConfig { pub auto_update: bool, pub auto_update_interval: Duration, + pub archive_source: String, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/main.rs b/src/main.rs index 8540705..32b693b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,6 @@ const APP_INFO: AppInfo = AppInfo { name: NAME, author: NAME, }; -const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; /// The cache should be updated if it was explicitly requested, /// or if an automatic update is due and allowed. @@ -136,8 +135,8 @@ fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { } /// Update the cache -fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { - cache.update(ARCHIVE_URL).unwrap_or_else(|e| { +fn update_cache(cache: &Cache, archive_source: &str, quietly: bool, enable_styles: bool) { + cache.update(archive_source).unwrap_or_else(|e| { print_error(enable_styles, &e.context("Could not update cache")); process::exit(1); }); @@ -305,7 +304,8 @@ fn main() { // Cache update, pass through let cache_updated = if should_update_cache(&cache, &args, &config) { - update_cache(&cache, args.quiet, enable_styles); + let archive_source = config.updates.archive_source.as_str(); + update_cache(&cache, archive_source, args.quiet, enable_styles); true } else { false From 09ef7f534ee0d4077e8ae04f2dffcb0cc5b27622 Mon Sep 17 00:00:00 2001 From: Erick Guan <297343+erickguan@users.noreply.github.com> Date: Wed, 26 Feb 2025 00:27:44 +0100 Subject: [PATCH 144/196] Allow configuring TLS backend (#386) --- .github/workflows/ci.yml | 7 +++- Cargo.lock | 17 +++++--- Cargo.toml | 24 +++++------ docs/src/config_updates.md | 18 +++++++++ docs/src/installing.md | 2 +- src/cache.rs | 60 +++++++++++++++++++++++----- src/config.rs | 81 +++++++++++++++++++++++++++++++++++--- src/main.rs | 23 ++++++----- tests/lib.rs | 43 +++++++++++++++++++- 9 files changed, 228 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dee3fd8..03ee177 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,11 @@ jobs: toolchain: ${{ matrix.toolchain }} - name: Build with default features run: cargo build - - name: Build with logging and webpki roots - run: cargo build --features logging,webpki-roots --no-default-features + - name: Build with logging and Rustls with webpki roots + run: cargo build --features logging,rustls-with-webpki-roots --no-default-features + - name: Build with native TLS backend + # expects runners have the proper Native SSL library + run: cargo build --features native-tls --no-default-features - name: Run tests run: cargo test -- --test-threads 1 diff --git a/Cargo.lock b/Cargo.lock index 008695c..6fcfe15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,6 +201,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "clap" version = "4.5.19" @@ -1153,15 +1159,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -1243,9 +1250,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64", "bytes", diff --git a/Cargo.toml b/Cargo.toml index bd0d07a..010fa08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ app_dirs = { version = "2", package = "app_dirs2" } clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.11", optional = true } log = "0.4" -reqwest = { version = "0.12.5", features = ["blocking"], default-features = false } +reqwest = { version = "0.12.9", features = ["blocking"], default-features = false } serde = "1.0.21" serde_derive = "1.0.21" toml = "0.8.19" @@ -44,21 +44,23 @@ tempfile = "3.1.0" filetime = "0.2.10" [features] -default = ["native-roots"] +default = ["native-tls", "rustls-with-webpki-roots", "rustls-with-native-roots"] logging = ["env_logger"] -# Reqwest (the HTTP client library) can handle TLS connections in three +# Reqwest (the HTTP client library) can handle TLS connections in four # different modes: # -# - Rustls with native roots -# - Rustls with WebPK roots -# - Native TLS (SChannel on Windows, Secure Transport on macOS and OpenSSL otherwise) +# - Rustls with: +# - native roots +# - WebPK roots +# - Native TLS (SChannel on Windows, Secure Transport on macOS and OpenSSL otherwise) with: +# - native roots +# - WebPK roots (not implemented in tealdeer) # -# Exactly one of the three variants must be selected. By default, Rustls with -# native roots is enabled. -native-roots = ["reqwest/rustls-tls-native-roots"] -webpki-roots = ["reqwest/rustls-tls-webpki-roots"] -native-tls = ["reqwest/native-tls"] +# At least one of variants must be selected. By default, uses native TLS and native roots. +native-tls = ["reqwest/rustls-tls-native-roots-no-provider", "reqwest/rustls-tls-webpki-roots-no-provider", "reqwest/native-tls"] +rustls-with-webpki-roots = ["reqwest/rustls-tls-native-roots-no-provider", "reqwest/rustls-tls-webpki-roots"] +rustls-with-native-roots = ["reqwest/rustls-tls-webpki-roots-no-provider", "reqwest/rustls-tls-native-roots"] ignore-online-tests = [] diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index 2678d4c..eaac735 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -32,3 +32,21 @@ fetched from the latest `tldr-pages/tldr` GitHub release. [updates] archive_source = https://my-company.example.com/tldr/ +### `tls_backend` + +Specifies which TLS backend to use. Try changing this setting if you encounter certificate errors. + +Available options: +- `rustls-with-native-roots` - [Rustls][rustls] (a TLS library in Rust) with native roots +- `rustls-with-webpki-roots` - Rustls with [WebPKI][rustls-webpki] roots +- `native-tls` - Native TLS + - SChannel on Windows + - Secure Transport on macOS + - OpenSSL on other platforms + + [updates] + tls_backend = "native-tls" + + +[rustls]: https://github.com/rustls/rustls +[rustls-webpki]: https://github.com/rustls/webpki diff --git a/docs/src/installing.md b/docs/src/installing.md index 71c8398..39de050 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -48,7 +48,7 @@ Release build: Release build with bundled CA roots: - $ cargo build --release --no-default-features --features webpki-roots + $ cargo build --release --no-default-features --features rustls-with-webpki-roots Debug build with logging support: diff --git a/src/cache.rs b/src/cache.rs index 9d27011..a72d0e0 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -13,7 +13,7 @@ use reqwest::{blocking::Client, Proxy}; use walkdir::{DirEntry, WalkDir}; use zip::ZipArchive; -use crate::{types::PlatformType, utils::print_warning}; +use crate::{config::TlsBackend, types::PlatformType, utils::print_warning}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; @@ -22,6 +22,7 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; pub struct Cache { cache_dir: PathBuf, enable_styles: bool, + tls_backend: TlsBackend, } #[derive(Debug)] @@ -86,13 +87,14 @@ pub enum CacheFreshness { } impl Cache { - pub fn new

(cache_dir: P, enable_styles: bool) -> Self + pub fn new

(cache_dir: P, enable_styles: bool, tls_backend: TlsBackend) -> Self where P: Into, { Self { cache_dir: cache_dir.into(), enable_styles, + tls_backend, } } @@ -135,9 +137,28 @@ impl Cache { self.cache_dir.join(TLDR_PAGES_DIR) } - /// Download the archive from the specified URL. - fn download(archive_url: &str) -> Result> { + fn build_client(tls_backend: TlsBackend) -> Result { let mut builder = Client::builder(); + builder = match tls_backend { + #[cfg(feature = "native-tls")] + TlsBackend::NativeTls => builder + .use_native_tls() + .tls_built_in_root_certs(true) + .tls_built_in_webpki_certs(false) + .tls_built_in_native_certs(false), + #[cfg(feature = "rustls-with-webpki-roots")] + TlsBackend::RustlsWithWebpkiRoots => builder + .use_rustls_tls() + .tls_built_in_root_certs(false) + .tls_built_in_webpki_certs(true) + .tls_built_in_native_certs(false), + #[cfg(feature = "rustls-with-native-roots")] + TlsBackend::RustlsWithNativeRoots => builder + .use_rustls_tls() + .tls_built_in_root_certs(false) + .tls_built_in_webpki_certs(false) + .tls_built_in_native_certs(true), + }; if let Ok(ref host) = env::var("HTTP_PROXY") { if let Ok(proxy) = Proxy::http(host) { builder = builder.proxy(proxy); @@ -148,9 +169,11 @@ impl Cache { builder = builder.proxy(proxy); } } - let client = builder - .build() - .context("Could not instantiate HTTP client")?; + builder.build().context("Could not instantiate HTTP client") + } + + /// Download the archive from the specified URL. + fn download(client: &Client, archive_url: &str) -> Result> { let mut resp = client .get(archive_url) .send()? @@ -166,10 +189,11 @@ impl Cache { pub fn update(&self, archive_source: &str) -> Result<()> { self.ensure_cache_dir_exists()?; - let archive_url = format!("{}/tldr.zip", archive_source); + let archive_url = format!("{archive_source}/tldr.zip"); + let client = Self::build_client(self.tls_backend)?; // First, download the compressed data - let bytes: Vec = Self::download(&archive_url)?; + let bytes: Vec = Self::download(&client, &archive_url)?; // Decompress the response body into an `Archive` let mut archive = ZipArchive::new(Cursor::new(bytes)) @@ -505,4 +529,22 @@ mod tests { assert_eq!(&buf, b"Hello\n"); } + + #[test] + #[cfg(feature = "native-tls")] + fn test_create_https_client_with_native_tls() { + Cache::build_client(TlsBackend::NativeTls).expect("fails to build a client."); + } + + #[test] + #[cfg(feature = "rustls-with-webpki-roots")] + fn test_create_https_client_with_rustls() { + Cache::build_client(TlsBackend::RustlsWithWebpkiRoots).expect("fails to build a client."); + } + + #[test] + #[cfg(feature = "rustls-with-native-roots")] + fn test_create_https_client_with_rustls_with_native_roots() { + Cache::build_client(TlsBackend::RustlsWithNativeRoots).expect("fails to build a client."); + } } diff --git a/src/config.rs b/src/config.rs index de86817..3d82eea 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,9 +5,10 @@ use std::{ time::Duration, }; -use anyhow::{bail, ensure, Context, Result}; +use anyhow::{anyhow, bail, ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use log::debug; +use serde::Serialize as _; use serde_derive::{Deserialize, Serialize}; use yansi::{Color, Style}; @@ -16,6 +17,14 @@ use crate::types::PathSource; pub const CONFIG_FILE_NAME: &str = "config.toml"; pub const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days const DEFAULT_UPDATE_INTERVAL_HOURS: u64 = MAX_CACHE_AGE.as_secs() / 3600; // 30 days +const SUPPORTED_TLS_BACKENDS: &[RawTlsBackend] = &[ + #[cfg(feature = "native-tls")] + RawTlsBackend::NativeTls, + #[cfg(feature = "rustls-with-webpki-roots")] + RawTlsBackend::RustlsWithWebpkiRoots, + #[cfg(feature = "rustls-with-native-roots")] + RawTlsBackend::RustlsWithNativeRoots, +]; fn default_underline() -> bool { false @@ -178,6 +187,8 @@ struct RawUpdatesConfig { pub auto_update_interval_hours: u64, #[serde(default = "default_archive_source")] pub archive_source: String, + #[serde(default)] + pub tls_backend: RawTlsBackend, } impl Default for RawUpdatesConfig { @@ -186,19 +197,39 @@ impl Default for RawUpdatesConfig { auto_update: false, auto_update_interval_hours: DEFAULT_UPDATE_INTERVAL_HOURS, archive_source: default_archive_source(), + tls_backend: RawTlsBackend::default(), } } } -impl From for UpdatesConfig { - fn from(raw_updates_config: RawUpdatesConfig) -> Self { - Self { +impl TryFrom for UpdatesConfig { + type Error = anyhow::Error; + + fn try_from(raw_updates_config: RawUpdatesConfig) -> Result { + let tls_backend = match raw_updates_config.tls_backend { + #[cfg(feature = "native-tls")] + RawTlsBackend::NativeTls => TlsBackend::NativeTls, + #[cfg(feature = "rustls-with-webpki-roots")] + RawTlsBackend::RustlsWithWebpkiRoots => TlsBackend::RustlsWithWebpkiRoots, + #[cfg(feature = "rustls-with-native-roots")] + RawTlsBackend::RustlsWithNativeRoots => TlsBackend::RustlsWithNativeRoots, + // when compiling without all TLS backend features, we want to handle config error. + #[allow(unreachable_patterns)] + _ => return Err(anyhow!( + "Unsupported TLS backend: {}. This tealdeer build has support for the following options: {}", + raw_updates_config.tls_backend, + SUPPORTED_TLS_BACKENDS.iter().map(std::string::ToString::to_string).collect::>().join(", ") + )) + }; + + Ok(Self { auto_update: raw_updates_config.auto_update, auto_update_interval: Duration::from_secs( raw_updates_config.auto_update_interval_hours * 3600, ), archive_source: raw_updates_config.archive_source, - } + tls_backend, + }) } } @@ -265,6 +296,7 @@ pub struct UpdatesConfig { pub auto_update: bool, pub auto_update_interval: Duration, pub archive_source: String, + pub tls_backend: TlsBackend, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -291,6 +323,43 @@ pub struct DirectoriesConfig { pub custom_pages_dir: Option, } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum RawTlsBackend { + /// Native TLS (`SChannel` on Windows, Secure Transport on macOS and OpenSSL otherwise) + NativeTls, + /// Rustls with `WebPKI` roots. + RustlsWithWebpkiRoots, + /// Rustls with native roots. + RustlsWithNativeRoots, +} + +impl Default for RawTlsBackend { + fn default() -> Self { + *SUPPORTED_TLS_BACKENDS.first().unwrap() + } +} + +impl std::fmt::Display for RawTlsBackend { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.serialize(f) + } +} + +/// Allows choosing a `reqwest`'s TLS backend. Available TLS backends: +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum TlsBackend { + /// Native TLS (`SChannel` on Windows, Secure Transport on macOS and OpenSSL otherwise) + #[cfg(feature = "native-tls")] + NativeTls, + /// Rustls with `WebPKI` roots. + #[cfg(feature = "rustls-with-webpki-roots")] + RustlsWithWebpkiRoots, + /// Rustls with native roots. + #[cfg(feature = "rustls-with-native-roots")] + RustlsWithNativeRoots, +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct Config { pub style: StyleConfig, @@ -307,7 +376,7 @@ impl Config { fn from_raw(raw_config: RawConfig, relative_path_root: &Path) -> Result { let style = raw_config.style.into(); let display = raw_config.display.into(); - let updates = raw_config.updates.into(); + let updates = raw_config.updates.try_into()?; // Determine directories config. For this, we need to take some // additional factory into account, like env variables, or the diff --git a/src/main.rs b/src/main.rs index 32b693b..a16f386 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,18 +16,13 @@ #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_lines)] -#[cfg(any( - all(feature = "native-roots", feature = "webpki-roots"), - all(feature = "native-roots", feature = "native-tls"), - all(feature = "webpki-roots", feature = "native-tls"), - not(any( - feature = "native-roots", - feature = "webpki-roots", - feature = "native-tls" - )), -))] +#[cfg(not(any( + feature = "native-tls", + feature = "rustls-with-webpki-roots", + feature = "rustls-with-native-roots", +)))] compile_error!( - "exactly one of the features \"native-roots\", \"webpki-roots\" or \"native-tls\" must be enabled" + "at least one of the features \"native-tls\", \"rustls-with-webpki-roots\" or \"rustls-with-native-roots\" must be enabled" ); use std::{ @@ -295,7 +290,11 @@ fn main() { } // Instantiate cache. This will not yet create the cache directory! - let cache = Cache::new(&config.directories.cache_dir.path, enable_styles); + let cache = Cache::new( + &config.directories.cache_dir.path, + enable_styles, + config.updates.tls_backend, + ); // Clear cache, pass through if args.clear_cache { diff --git a/tests/lib.rs b/tests/lib.rs index 63edca6..606424e 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -220,7 +220,31 @@ fn test_update_cache_default_features() { fn test_update_cache_rustls_webpki() { let testenv = TestEnv::new() .no_default_features() - .with_feature("webpki-roots"); + .with_feature("rustls-with-webpki-roots"); + + testenv + .command() + .args(["sl"]) + .assert() + .failure() + .stderr(contains("Page cache not found. Please run `tldr --update`")); + + testenv + .command() + .args(["--update"]) + .assert() + .success() + .stderr(contains("Successfully updated cache.")); + + testenv.command().args(["sl"]).assert().success(); +} + +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] +#[test] +fn test_update_cache_native_tls() { + let testenv = TestEnv::new() + .no_default_features() + .with_feature("rustls-with-native-roots"); testenv .command() @@ -258,6 +282,23 @@ fn test_quiet_cache() { .stdout(is_empty()); } +#[test] +fn test_warn_invalid_tls_backend() { + let testenv = TestEnv::new() + .no_default_features() + .with_feature("rustls-with-webpki-roots") + .remove_initial_config(); + + testenv.append_to_config("updates.tls_backend = 'invalid-tls-backend'\n"); + + testenv + .command() + .args(["sl"]) + .assert() + .failure() + .stderr(contains("unknown variant `invalid-tls-backend`, expected one of `native-tls`, `rustls-with-webpki-roots`, `rustls-with-native-roots`")); +} + #[test] fn test_quiet_failures() { let testenv = TestEnv::new().install_default_cache(); From 55f401df30849f88183cb9379999e56e05f3eeda Mon Sep 17 00:00:00 2001 From: lyj Date: Thu, 27 Feb 2025 05:03:18 +0800 Subject: [PATCH 145/196] Add args: `--edit-page` and `--edit-patch` (#388) Fix https://github.com/tealdeer-rs/tealdeer/issues/383 Co-authored-by: Niklas Mohrin --- docs/src/usage.txt | 2 ++ src/cli.rs | 8 ++++++ src/main.rs | 68 ++++++++++++++++++++++++++++++++++++++-------- tests/lib.rs | 64 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 12 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index b6af6c3..846ff8c 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -8,6 +8,8 @@ Arguments: Options: -l, --list List all commands in the cache + --edit-page Edit custom page with `EDITOR` + --edit-patch Edit custom patch with `EDITOR` -f, --render Render a specific markdown file -p, --platform Override the operating system, can be specified multiple times in order of preference [possible values: linux, macos, sunos, windows, android, diff --git a/src/cli.rs b/src/cli.rs index e671507..0ba9de9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -32,6 +32,14 @@ pub(crate) struct Cli { #[arg(short = 'l', long = "list")] pub list: bool, + /// Edit custom page with `EDITOR` + #[arg(long, requires = "command")] + pub edit_page: bool, + + /// Edit custom patch with `EDITOR` + #[arg(long, requires = "command", conflicts_with = "edit_page")] + pub edit_patch: bool, + /// Render a specific markdown file #[arg( short = 'f', diff --git a/src/main.rs b/src/main.rs index a16f386..74ab3d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,10 +27,15 @@ compile_error!( use std::{ env, + fs::create_dir_all, io::{self, IsTerminal}, + path::Path, process, + process::Command, }; +use anyhow::anyhow; +use anyhow::Context; use app_dirs::AppInfo; use clap::Parser; @@ -235,6 +240,27 @@ fn get_languages_from_env() -> Vec { ) } +fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> anyhow::Result<()> { + create_dir_all(custom_pages_dir).context("Failed to create custom pages directory")?; + + let custom_page_path = custom_pages_dir.join(file_name); + let Some(custom_page_path) = custom_page_path.to_str() else { + return Err(anyhow!("`custom_page_path.to_str()` failed")); + }; + let Ok(editor) = env::var("EDITOR") else { + return Err(anyhow!( + "To edit a custom page, please set the `EDITOR` environment variable." + )); + }; + println!("Editing {custom_page_path:?}"); + + let status = Command::new(&editor).arg(custom_page_path).status()?; + if !status.success() { + return Err(anyhow!("{editor} exit with code {:?}", status.code())); + } + Ok(()) +} + fn main() { // Initialize logger init_log(); @@ -266,6 +292,34 @@ fn main() { } }; + let custom_pages_dir = config + .directories + .custom_pages_dir + .as_ref() + .map(PathWithSource::path); + + // Note: According to the TLDR client spec, page names must be transparently + // lowercased before lookup: + // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#page-names + let command = args.command.join("-").to_lowercase(); + + if args.edit_patch || args.edit_page { + let file_name = if args.edit_patch { + format!("{command}.patch.md") + } else { + format!("{command}.page.md") + }; + + custom_pages_dir + .context("To edit custom pages/patches, please specify a custom pages directory.") + .and_then(|custom_pages_dir| spawn_editor(custom_pages_dir, &file_name)) + .unwrap_or_else(|err| { + print_error(enable_styles, &err); + process::exit(1); + }); + return; + } + // Show various paths if args.show_paths { show_paths(&config); @@ -312,7 +366,7 @@ fn main() { // Check cache presence and freshness if !cache_updated - && (args.list || !args.command.is_empty()) + && (args.list || !command.is_empty()) && check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing { process::exit(1); @@ -320,11 +374,6 @@ fn main() { // List cached commands and exit if args.list { - let custom_pages_dir = config - .directories - .custom_pages_dir - .as_ref() - .map(PathWithSource::path); println!( "{}", cache.list_pages(custom_pages_dir, &platforms).join("\n") @@ -333,12 +382,7 @@ fn main() { } // Show command from cache - if !args.command.is_empty() { - // Note: According to the TLDR client spec, page names must be transparently - // lowercased before lookup: - // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#page-names - let command = args.command.join("-").to_lowercase(); - + if !command.is_empty() { // Collect languages let languages = args .language diff --git a/tests/lib.rs b/tests/lib.rs index 606424e..d229286 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1031,3 +1031,67 @@ fn test_raw_render_file() { .success() .stdout(diff(include_str!("cache/pages/common/inkscape-v1.md"))); } + +fn touch_custom_page(testenv: &TestEnv) { + let args = vec!["--edit-page", "foo"]; + + testenv + .command() + .args(&args) + .env("EDITOR", "touch") + .assert() + .success(); + assert!(testenv.custom_pages_dir.path().join("foo.page.md").exists()); +} + +fn touch_custom_patch(testenv: &TestEnv) { + let args = vec!["--edit-patch", "foo"]; + + testenv + .command() + .args(&args) + .env("EDITOR", "touch") + .assert() + .success(); + assert!(testenv + .custom_pages_dir + .path() + .join("foo.patch.md") + .exists()); +} + +#[test] +fn test_edit_page() { + let testenv = TestEnv::new().write_custom_pages_config(); + touch_custom_page(&testenv); +} + +#[test] +fn test_edit_patch() { + let testenv = TestEnv::new().write_custom_pages_config(); + touch_custom_patch(&testenv); +} + +#[test] +fn test_recreate_dir() { + let testenv = TestEnv::new().write_custom_pages_config(); + touch_custom_patch(&testenv); + touch_custom_page(&testenv); +} + +#[test] +fn test_custom_pages_dir_is_not_dir() { + let testenv = TestEnv::new().write_custom_pages_config(); + let _ = std::fs::remove_dir_all(testenv.custom_pages_dir.path()); + let _ = File::create(testenv.custom_pages_dir.path()).unwrap(); + assert!(testenv.custom_pages_dir.path().is_file()); + + let args = vec!["--edit-patch", "foo"]; + + testenv + .command() + .args(&args) + .env("EDITOR", "touch") + .assert() + .failure(); +} From 009af7063f2c8fc2b72fba02cbca5cd2bf12ad37 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 26 Feb 2025 23:04:41 +0100 Subject: [PATCH 146/196] Move most of `main` to `try_main` (#400) Currently, `main` uses `print_error` and `process::exit` in several places. These could be unified by propagating errors via `Result`s. There is one place left that manually calls `print_error`, because the error should be followed by help instructions printed without any highlighting. --- src/main.rs | 131 +++++++++++++++++++++------------------------------- 1 file changed, 52 insertions(+), 79 deletions(-) diff --git a/src/main.rs b/src/main.rs index 74ab3d3..cfd00db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,12 +30,10 @@ use std::{ fs::create_dir_all, io::{self, IsTerminal}, path::Path, - process, - process::Command, + process::{Command, ExitCode}, }; -use anyhow::anyhow; -use anyhow::Context; +use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; use clap::Parser; @@ -119,11 +117,8 @@ fn check_cache(cache: &Cache, args: &Cli, enable_styles: bool) -> CheckCacheResu } /// Clear the cache -fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { - let cache_dir_found = cache.clear().unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not clear cache")); - process::exit(1); - }); +fn clear_cache(cache: &Cache, quietly: bool) -> Result<()> { + let cache_dir_found = cache.clear().context("Could not clear cache")?; if !quietly { let cache_dir = cache.cache_dir().display(); if cache_dir_found { @@ -132,17 +127,18 @@ fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { eprintln!("Cache directory not found at `{cache_dir}`, nothing to do."); } } + Ok(()) } /// Update the cache -fn update_cache(cache: &Cache, archive_source: &str, quietly: bool, enable_styles: bool) { - cache.update(archive_source).unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not update cache")); - process::exit(1); - }); +fn update_cache(cache: &Cache, archive_source: &str, quietly: bool) -> Result<()> { + cache + .update(archive_source) + .context("Could not update cache")?; if !quietly { eprintln!("Successfully updated cache."); } + Ok(()) } /// Show file paths @@ -179,21 +175,13 @@ fn show_paths(config: &Config) { println!("Custom pages dir: {custom_pages_dir}"); } -/// Create seed config file and exit -fn create_config_and_exit(enable_styles: bool) { - match make_default_config() { - Ok(config_file_path) => { - eprintln!( - "Successfully created seed config file here: {}", - config_file_path.to_str().unwrap() - ); - process::exit(0); - } - Err(e) => { - print_error(enable_styles, &e.context("Could not create seed config")); - process::exit(1); - } - } +fn create_config() -> Result<()> { + let config_file_path = make_default_config().context("Could not create seed config")?; + eprintln!( + "Successfully created seed config file here: {}", + config_file_path.to_str().unwrap() + ); + Ok(()) } #[cfg(feature = "logging")] @@ -240,7 +228,7 @@ fn get_languages_from_env() -> Vec { ) } -fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> anyhow::Result<()> { +fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> Result<()> { create_dir_all(custom_pages_dir).context("Failed to create custom pages directory")?; let custom_page_path = custom_pages_dir.join(file_name); @@ -261,7 +249,7 @@ fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> anyhow::Result<()> Ok(()) } -fn main() { +fn main() -> ExitCode { // Initialize logger init_log(); @@ -283,14 +271,15 @@ fn main() { ColorOptions::Never => false, }; + try_main(args, enable_styles).unwrap_or_else(|error| { + print_error(enable_styles, &error); + ExitCode::FAILURE + }) +} + +fn try_main(args: Cli, enable_styles: bool) -> Result { // Look up config file, if none is found fall back to default config. - let config = match Config::load(enable_styles) { - Ok(config) => config, - Err(e) => { - print_error(enable_styles, &e.context("Could not load config")); - process::exit(1); - } - }; + let config = Config::load(enable_styles).context("Could not load config")?; let custom_pages_dir = config .directories @@ -312,12 +301,9 @@ fn main() { custom_pages_dir .context("To edit custom pages/patches, please specify a custom pages directory.") - .and_then(|custom_pages_dir| spawn_editor(custom_pages_dir, &file_name)) - .unwrap_or_else(|err| { - print_error(enable_styles, &err); - process::exit(1); - }); - return; + .and_then(|custom_pages_dir| spawn_editor(custom_pages_dir, &file_name))?; + + return Ok(ExitCode::SUCCESS); } // Show various paths @@ -327,7 +313,8 @@ fn main() { // Create a basic config and exit if args.seed_config { - create_config_and_exit(enable_styles); + create_config()?; + return Ok(ExitCode::SUCCESS); } let platforms = compute_platforms(args.platforms.as_ref()); @@ -335,12 +322,8 @@ fn main() { // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); - if let Err(ref e) = print_page(&path, args.raw, enable_styles, args.pager, &config) { - print_error(enable_styles, e); - process::exit(1); - } else { - process::exit(0); - }; + print_page(&path, args.raw, enable_styles, args.pager, &config)?; + return Ok(ExitCode::SUCCESS); } // Instantiate cache. This will not yet create the cache directory! @@ -352,25 +335,17 @@ fn main() { // Clear cache, pass through if args.clear_cache { - clear_cache(&cache, args.quiet, enable_styles); + clear_cache(&cache, args.quiet)?; } - // Cache update, pass through - let cache_updated = if should_update_cache(&cache, &args, &config) { - let archive_source = config.updates.archive_source.as_str(); - update_cache(&cache, archive_source, args.quiet, enable_styles); - true - } else { - false - }; - - // Check cache presence and freshness - if !cache_updated - && (args.list || !command.is_empty()) + if should_update_cache(&cache, &args, &config) { + update_cache(&cache, &config.updates.archive_source, args.quiet)?; + } else if (args.list || !args.command.is_empty()) && check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing { - process::exit(1); - } + // Cache is needed, but missing + return Ok(ExitCode::FAILURE); + }; // List cached commands and exit if args.list { @@ -378,7 +353,8 @@ fn main() { "{}", cache.list_pages(custom_pages_dir, &platforms).join("\n") ); - process::exit(0); + + return Ok(ExitCode::SUCCESS); } // Show command from cache @@ -389,7 +365,7 @@ fn main() { .map_or_else(get_languages_from_env, |lang| vec![lang]); // Search for command in cache - if let Some(lookup_result) = cache.find_page( + let Some(lookup_result) = cache.find_page( &command, &languages, config @@ -398,15 +374,7 @@ fn main() { .as_ref() .map(PathWithSource::path), &platforms, - ) { - if let Err(ref e) = - print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) - { - print_error(enable_styles, e); - process::exit(1); - } - process::exit(0); - } else { + ) else { if !args.quiet { print_warning( enable_styles, @@ -418,9 +386,14 @@ fn main() { ), ); } - process::exit(1); - } + + return Ok(ExitCode::FAILURE); + }; + + print_page(&lookup_result, args.raw, enable_styles, args.pager, &config)?; } + + Ok(ExitCode::SUCCESS) } /// Returns the passed or default platform types and appends `PlatformType::Common` as fallback. From c6de583c46c8cbd10fab570785ea1c05773876fe Mon Sep 17 00:00:00 2001 From: Nachiket Kanore <44920607+nachiketkanore@users.noreply.github.com> Date: Sun, 2 Mar 2025 16:33:09 +0530 Subject: [PATCH 147/196] Only create a single temporary directory in integration tests (#411) --- tests/lib.rs | 115 ++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 65 deletions(-) diff --git a/tests/lib.rs b/tests/lib.rs index d229286..420eb08 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -18,52 +18,60 @@ use tempfile::{Builder as TempfileBuilder, TempDir}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; struct TestEnv { - pub cache_dir: TempDir, - pub custom_pages_dir: TempDir, - pub config_dir: TempDir, + _test_dir: TempDir, pub default_features: bool, pub features: Vec, } impl TestEnv { fn new() -> Self { + let test_dir: TempDir = TempfileBuilder::new() + .prefix(".tldr.test") + .tempdir() + .unwrap(); + let this = TestEnv { - cache_dir: TempfileBuilder::new() - .prefix(".tldr.test.cache") - .tempdir() - .unwrap(), - config_dir: TempfileBuilder::new() - .prefix(".tldr.test.conf") - .tempdir() - .unwrap(), - custom_pages_dir: TempfileBuilder::new() - .prefix(".tldr.test.custom-pages") - .tempdir() - .unwrap(), + _test_dir: test_dir, default_features: true, features: vec![], }; + create_dir_all(&this.cache_dir()).unwrap(); + create_dir_all(&this.config_dir()).unwrap(); + create_dir_all(&this.custom_pages_dir()).unwrap(); + this.append_to_config(format!( "directories.cache_dir = '{}'\n", - this.cache_dir.path().to_str().unwrap(), + this.cache_dir().to_str().unwrap(), )); this } + fn cache_dir(&self) -> PathBuf { + self._test_dir.path().join(".cache") + } + + fn config_dir(&self) -> PathBuf { + self._test_dir.path().join(".config") + } + + fn custom_pages_dir(&self) -> PathBuf { + self._test_dir.path().join(".custom_pages") + } + fn append_to_config(&self, content: impl AsRef) { File::options() .create(true) .append(true) - .open(self.config_dir.path().join("config.toml")) + .open(self.config_dir().join("config.toml")) .expect("Failed to open config file") .write_all(content.as_ref().as_bytes()) .expect("Failed to append to config file."); } fn remove_initial_config(self) -> Self { - let _ = fs::remove_file(self.config_dir.path().join("config.toml")); + let _ = fs::remove_file(self.config_dir().join("config.toml")); self } @@ -74,12 +82,7 @@ impl TestEnv { /// Add entry for that environment to an OS-specific subfolder. fn add_os_entry(&self, os: &str, name: &str, contents: &str) { - let dir = self - .cache_dir - .path() - .join(TLDR_PAGES_DIR) - .join("pages") - .join(os); + let dir = self.cache_dir().join(TLDR_PAGES_DIR).join("pages").join(os); create_dir_all(&dir).unwrap(); fs::write(dir.join(format!("{name}.md")), contents.as_bytes()).unwrap(); @@ -87,14 +90,14 @@ impl TestEnv { /// Add custom patch entry to the custom_pages_dir fn add_page_entry(&self, name: &str, contents: &str) { - let dir = self.custom_pages_dir.path(); + let dir = &self.custom_pages_dir(); create_dir_all(dir).unwrap(); fs::write(dir.join(format!("{name}.page.md")), contents.as_bytes()).unwrap(); } /// Add custom patch entry to the custom_pages_dir fn add_patch_entry(&self, name: &str, contents: &str) { - let dir = self.custom_pages_dir.path(); + let dir = &self.custom_pages_dir(); create_dir_all(dir).unwrap(); fs::write(dir.join(format!("{name}.patch.md")), contents.as_bytes()).unwrap(); } @@ -126,17 +129,14 @@ impl TestEnv { } let run = build.run().expect("Failed to build tealdeer for testing"); let mut cmd = run.command(); - cmd.env( - "TEALDEER_CONFIG_DIR", - self.config_dir.path().to_str().unwrap(), - ); + cmd.env("TEALDEER_CONFIG_DIR", self.config_dir().to_str().unwrap()); cmd } fn install_default_cache(self) -> Self { copy_recursively( &PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "tests", "cache"]), - &self.cache_dir.path().join(TLDR_PAGES_DIR), + &self.cache_dir().join(TLDR_PAGES_DIR), ) .expect("Failed to copy the cache to the test environment"); @@ -146,7 +146,7 @@ impl TestEnv { fn install_default_custom_pages(self) -> Self { copy_recursively( &PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "tests", "custom-pages"]), - self.custom_pages_dir.path(), + self.custom_pages_dir().as_path(), ) .expect("Failed to copy the custom pages to the test environment"); @@ -156,7 +156,7 @@ impl TestEnv { fn write_custom_pages_config(self) -> Self { self.append_to_config(format!( "directories.custom_pages_dir = '{}'\n", - self.custom_pages_dir.path().to_str().unwrap() + self.custom_pages_dir().to_str().unwrap() )); self @@ -316,7 +316,7 @@ fn test_quiet_old_cache() { let testenv = TestEnv::new().install_default_cache(); filetime::set_file_mtime( - testenv.cache_dir.path().join(TLDR_PAGES_DIR), + testenv.cache_dir().join(TLDR_PAGES_DIR), filetime::FileTime::from_unix_time(1, 0), ) .unwrap(); @@ -340,7 +340,7 @@ fn test_quiet_old_cache() { #[test] fn test_create_cache_directory_path() { let testenv = TestEnv::new().remove_initial_config(); - let cache_dir = testenv.cache_dir.path(); + let cache_dir = &testenv.cache_dir(); let internal_cache_dir = cache_dir.join("internal"); testenv.append_to_config(format!( "directories.cache_dir = '{}'\n", @@ -368,7 +368,7 @@ fn test_create_cache_directory_path() { #[test] fn test_cache_location_not_a_directory() { let testenv = TestEnv::new().remove_initial_config(); - let cache_dir = testenv.cache_dir.path(); + let cache_dir = &testenv.cache_dir(); let internal_file = cache_dir.join("internal"); File::create(&internal_file).unwrap(); @@ -391,7 +391,7 @@ fn test_cache_location_not_a_directory() { #[test] fn test_cache_location_source() { let testenv = TestEnv::new().remove_initial_config(); - let default_cache_dir = testenv.cache_dir.path(); + let default_cache_dir = &testenv.cache_dir(); let tmp_cache_dir = TempfileBuilder::new() .prefix(".tldr.test.cache_dir") .tempdir() @@ -447,7 +447,7 @@ fn test_setup_seed_config() { .success() .stderr(contains("Successfully created seed config file here")); - assert!(testenv.config_dir.path().join("config.toml").is_file()); + assert!(testenv.config_dir().join("config.toml").is_file()); } #[test] @@ -462,29 +462,19 @@ fn test_show_paths() { .success() .stdout(contains(format!( "Config dir: {}", - testenv.config_dir.path().to_str().unwrap(), + testenv.config_dir().to_str().unwrap(), ))) .stdout(contains(format!( "Config path: {}", - testenv - .config_dir - .path() - .join("config.toml") - .to_str() - .unwrap(), + testenv.config_dir().join("config.toml").to_str().unwrap(), ))) .stdout(contains(format!( "Cache dir: {}", - testenv.cache_dir.path().to_str().unwrap(), + testenv.cache_dir().to_str().unwrap(), ))) .stdout(contains(format!( "Pages dir: {}", - testenv - .cache_dir - .path() - .join(TLDR_PAGES_DIR) - .to_str() - .unwrap(), + testenv.cache_dir().join(TLDR_PAGES_DIR).to_str().unwrap(), ))); let testenv = testenv.write_custom_pages_config(); @@ -497,7 +487,7 @@ fn test_show_paths() { .success() .stdout(contains(format!( "Custom pages dir: {}", - testenv.custom_pages_dir.path().to_str().unwrap(), + testenv.custom_pages_dir().to_str().unwrap(), ))); } @@ -853,7 +843,7 @@ fn test_autoupdate_cache() { .failure() .stderr(contains("Page cache not found. Please run `tldr --update`")); - let cache_file_path = testenv.cache_dir.path().join(TLDR_PAGES_DIR); + let cache_file_path = testenv.cache_dir().join(TLDR_PAGES_DIR); testenv .append_to_config("updates.auto_update = true\nupdates.auto_update_interval_hours = 24\n"); @@ -1006,8 +996,7 @@ fn test_raw_render_file() { let testenv = TestEnv::new().install_default_cache(); let path = testenv - .cache_dir - .path() + .cache_dir() .join(TLDR_PAGES_DIR) .join("pages/common/inkscape-v1.md"); let mut args = vec!["--color", "never", "-f", &path.to_str().unwrap()]; @@ -1041,7 +1030,7 @@ fn touch_custom_page(testenv: &TestEnv) { .env("EDITOR", "touch") .assert() .success(); - assert!(testenv.custom_pages_dir.path().join("foo.page.md").exists()); + assert!(testenv.custom_pages_dir().join("foo.page.md").exists()); } fn touch_custom_patch(testenv: &TestEnv) { @@ -1053,11 +1042,7 @@ fn touch_custom_patch(testenv: &TestEnv) { .env("EDITOR", "touch") .assert() .success(); - assert!(testenv - .custom_pages_dir - .path() - .join("foo.patch.md") - .exists()); + assert!(testenv.custom_pages_dir().join("foo.patch.md").exists()); } #[test] @@ -1082,9 +1067,9 @@ fn test_recreate_dir() { #[test] fn test_custom_pages_dir_is_not_dir() { let testenv = TestEnv::new().write_custom_pages_config(); - let _ = std::fs::remove_dir_all(testenv.custom_pages_dir.path()); - let _ = File::create(testenv.custom_pages_dir.path()).unwrap(); - assert!(testenv.custom_pages_dir.path().is_file()); + let _ = std::fs::remove_dir_all(testenv.custom_pages_dir()); + let _ = File::create(testenv.custom_pages_dir()).unwrap(); + assert!(testenv.custom_pages_dir().is_file()); let args = vec!["--edit-patch", "foo"]; From 3d8d488f66f23e202d8afc67181f237cabaaf50f Mon Sep 17 00:00:00 2001 From: Erick Guan <297343+erickguan@users.noreply.github.com> Date: Sun, 9 Mar 2025 22:06:47 +0100 Subject: [PATCH 148/196] Replace reqwest with ureq (#417) ureq is a blocking HTTP client. ureq is simpler than reqwest. This brings: - smaller binary size - cleaner configuration interfaces --- Cargo.lock | 1093 +++++++------------------------------------------- Cargo.toml | 20 +- src/cache.rs | 88 ++-- 3 files changed, 186 insertions(+), 1015 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6fcfe15..317311a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" @@ -87,7 +78,7 @@ version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7e7b35733e3a8c1ccb90385088dd5b6eaa61325cb4d1ad56e683b5224ff352e" dependencies = [ - "jni", + "jni 0.21.1", "ndk-context", "winapi", "xdg", @@ -124,27 +115,18 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "2.6.0" @@ -168,12 +150,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.7.2" @@ -201,12 +177,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - [[package]] name = "clap" version = "4.5.19" @@ -294,6 +264,16 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "pem-rfc7468", + "zeroize", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -458,65 +438,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -528,12 +449,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - [[package]] name = "hashbrown" version = "0.15.2" @@ -546,12 +461,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "http" version = "1.1.0" @@ -563,29 +472,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - [[package]] name = "httparse" version = "1.9.5" @@ -598,218 +484,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "indexmap" version = "2.6.0" @@ -820,12 +494,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "ipnet" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -838,6 +506,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + [[package]] name = "jni" version = "0.21.1" @@ -860,15 +542,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "libc" version = "0.2.169" @@ -892,12 +565,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "litemap" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" - [[package]] name = "lockfree-object-pool" version = "0.1.6" @@ -906,9 +573,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" @@ -916,12 +583,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -931,23 +592,11 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c" dependencies = [ "libc", "log", @@ -972,6 +621,25 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -981,15 +649,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.20.2" @@ -998,9 +657,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ "bitflags", "cfg-if", @@ -1024,15 +683,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -1050,39 +709,27 @@ dependencies = [ "libc", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "predicates" version = "3.1.2" @@ -1122,55 +769,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "quinn" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" -dependencies = [ - "bytes", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" -dependencies = [ - "bytes", - "rand", - "ring", - "rustc-hash", - "rustls", - "slab", - "thiserror", - "tinyvec", - "tracing", -] - -[[package]] -name = "quinn-udp" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.52.0", -] - [[package]] name = "quote" version = "1.0.37" @@ -1180,36 +778,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "redox_syscall" version = "0.5.7" @@ -1248,53 +816,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "windows-registry", -] - [[package]] name = "ring" version = "0.17.8" @@ -1310,18 +831,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" - [[package]] name = "rustix" version = "0.38.37" @@ -1337,10 +846,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ + "log", "once_cell", "ring", "rustls-pki-types", @@ -1351,9 +861,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -1373,9 +883,36 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-platform-verifier" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni 0.19.0", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-roots", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" @@ -1405,9 +942,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -1422,14 +959,15 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -1476,18 +1014,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "shlex" version = "1.3.0" @@ -1500,43 +1026,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "subtle" version = "2.6.1" @@ -1554,26 +1049,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tealdeer" version = "1.7.1" @@ -1588,11 +1063,11 @@ dependencies = [ "log", "pager", "predicates", - "reqwest", "serde", "serde_derive", "tempfile", "toml", + "ureq", "walkdir", "yansi", "zip", @@ -1647,67 +1122,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls", - "rustls-pki-types", - "tokio", -] - [[package]] name = "toml" version = "0.8.19" @@ -1742,37 +1156,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "unicode-ident" version = "1.0.13" @@ -1786,27 +1169,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] -name = "url" -version = "2.5.4" +name = "ureq" +version = "3.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "06f78313c985f2fba11100dd06d60dd402d0cabb458af4d94791b8e09c025323" dependencies = [ - "form_urlencoded", - "idna", + "base64", + "der", + "flate2", + "log", + "native-tls", "percent-encoding", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "rustls-platform-verifier", + "ureq-proto", + "utf-8", + "webpki-root-certs", + "webpki-roots", ] [[package]] -name = "utf16_iter" -version = "1.0.5" +name = "ureq-proto" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +checksum = "64adb55464bad1ab1aa9229133d0d59d2f679180f4d15f0d9debe616f541f25e" +dependencies = [ + "base64", + "http", + "httparse", + "log", +] [[package]] -name = "utf8_iter" -version = "1.0.4" +name = "utf-8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" @@ -1839,15 +1239,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1855,87 +1246,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.93" +name = "webpki-root-certs" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4" dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", + "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -1971,36 +1294,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -2158,18 +1451,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - [[package]] name = "xdg" version = "2.5.2" @@ -2182,100 +1463,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" -[[package]] -name = "yoke" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -[[package]] -name = "zerovec" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "zip" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index 010fa08..4787d64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,9 @@ app_dirs = { version = "2", package = "app_dirs2" } clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.11", optional = true } log = "0.4" -reqwest = { version = "0.12.9", features = ["blocking"], default-features = false } serde = "1.0.21" serde_derive = "1.0.21" +ureq = { version = "3.0.8", default-features = false, features = ["gzip"] } toml = "0.8.19" walkdir = "2.0.1" yansi = "1" @@ -47,20 +47,10 @@ filetime = "0.2.10" default = ["native-tls", "rustls-with-webpki-roots", "rustls-with-native-roots"] logging = ["env_logger"] -# Reqwest (the HTTP client library) can handle TLS connections in four -# different modes: -# -# - Rustls with: -# - native roots -# - WebPK roots -# - Native TLS (SChannel on Windows, Secure Transport on macOS and OpenSSL otherwise) with: -# - native roots -# - WebPK roots (not implemented in tealdeer) -# -# At least one of variants must be selected. By default, uses native TLS and native roots. -native-tls = ["reqwest/rustls-tls-native-roots-no-provider", "reqwest/rustls-tls-webpki-roots-no-provider", "reqwest/native-tls"] -rustls-with-webpki-roots = ["reqwest/rustls-tls-native-roots-no-provider", "reqwest/rustls-tls-webpki-roots"] -rustls-with-native-roots = ["reqwest/rustls-tls-webpki-roots-no-provider", "reqwest/rustls-tls-native-roots"] +# At least one of variants for `ureq` HTTP client must be selected. +native-tls = ["ureq/native-tls", "ureq/platform-verifier"] +rustls-with-webpki-roots = ["ureq/rustls"] # ureq uses WebPKI roots by default +rustls-with-native-roots = ["ureq/rustls", "ureq/platform-verifier"] ignore-online-tests = [] diff --git a/src/cache.rs b/src/cache.rs index a72d0e0..76f0abe 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,5 +1,4 @@ use std::{ - env, ffi::OsStr, fs::{self, File}, io::{BufReader, Cursor, Read}, @@ -9,7 +8,8 @@ use std::{ use anyhow::{ensure, Context, Result}; use log::debug; -use reqwest::{blocking::Client, Proxy}; +use ureq::tls::{RootCerts, TlsConfig, TlsProvider}; +use ureq::Agent; use walkdir::{DirEntry, WalkDir}; use zip::ZipArchive; @@ -137,54 +137,6 @@ impl Cache { self.cache_dir.join(TLDR_PAGES_DIR) } - fn build_client(tls_backend: TlsBackend) -> Result { - let mut builder = Client::builder(); - builder = match tls_backend { - #[cfg(feature = "native-tls")] - TlsBackend::NativeTls => builder - .use_native_tls() - .tls_built_in_root_certs(true) - .tls_built_in_webpki_certs(false) - .tls_built_in_native_certs(false), - #[cfg(feature = "rustls-with-webpki-roots")] - TlsBackend::RustlsWithWebpkiRoots => builder - .use_rustls_tls() - .tls_built_in_root_certs(false) - .tls_built_in_webpki_certs(true) - .tls_built_in_native_certs(false), - #[cfg(feature = "rustls-with-native-roots")] - TlsBackend::RustlsWithNativeRoots => builder - .use_rustls_tls() - .tls_built_in_root_certs(false) - .tls_built_in_webpki_certs(false) - .tls_built_in_native_certs(true), - }; - if let Ok(ref host) = env::var("HTTP_PROXY") { - if let Ok(proxy) = Proxy::http(host) { - builder = builder.proxy(proxy); - } - } - if let Ok(ref host) = env::var("HTTPS_PROXY") { - if let Ok(proxy) = Proxy::https(host) { - builder = builder.proxy(proxy); - } - } - builder.build().context("Could not instantiate HTTP client") - } - - /// Download the archive from the specified URL. - fn download(client: &Client, archive_url: &str) -> Result> { - let mut resp = client - .get(archive_url) - .send()? - .error_for_status() - .with_context(|| format!("Could not download tldr pages from {archive_url}"))?; - let mut buf: Vec = vec![]; - let bytes_downloaded = resp.copy_to(&mut buf)?; - debug!("{} bytes downloaded", bytes_downloaded); - Ok(buf) - } - /// Update the pages cache from the specified URL. pub fn update(&self, archive_source: &str) -> Result<()> { self.ensure_cache_dir_exists()?; @@ -475,6 +427,42 @@ impl Cache { } } +impl Cache { + fn build_client(tls_backend: TlsBackend) -> Result { + let tls_builder = match tls_backend { + #[cfg(feature = "native-tls")] + TlsBackend::NativeTls => TlsConfig::builder() + .provider(TlsProvider::NativeTls) + .root_certs(RootCerts::PlatformVerifier), + #[cfg(feature = "rustls-with-webpki-roots")] + TlsBackend::RustlsWithWebpkiRoots => TlsConfig::builder() + .provider(TlsProvider::Rustls) + .root_certs(RootCerts::WebPki), + #[cfg(feature = "rustls-with-native-roots")] + TlsBackend::RustlsWithNativeRoots => TlsConfig::builder() + .provider(TlsProvider::Rustls) + .root_certs(RootCerts::PlatformVerifier), + }; + let config = Agent::config_builder() + .tls_config(tls_builder.build()) + .build(); + + Ok(config.into()) + } + + /// Download the archive from the specified URL. + fn download(client: &Agent, archive_url: &str) -> Result> { + let response = client + .get(archive_url) + .call() + .with_context(|| format!("Could not download tldr pages from {archive_url}"))?; + let mut buf: Vec = Vec::new(); + response.into_body().into_reader().read_to_end(&mut buf)?; + debug!("{} bytes downloaded", buf.len()); + Ok(buf) + } +} + /// Unit Tests for cache module #[cfg(test)] mod tests { From 9f43adb7f9aaacdff217bca68631e75a8dcd4831 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 18 Mar 2025 22:58:26 +0100 Subject: [PATCH 149/196] Require `zip >= 2.3.0` --- Cargo.lock | 54 +++++++++++++++++++++++++++++++++++++----------------- Cargo.toml | 2 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb75c7..582b25d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] @@ -284,15 +284,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", @@ -714,7 +714,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.64", "walkdir", "windows-sys 0.45.0", ] @@ -983,9 +983,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -1003,7 +1003,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror", + "thiserror 1.0.64", "tokio", "tracing", ] @@ -1020,7 +1020,7 @@ dependencies = [ "rustc-hash", "rustls", "slab", - "thiserror", + "thiserror 1.0.64", "tinyvec", "tracing", ] @@ -1406,9 +1406,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1483,7 +1483,16 @@ version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.64", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -1497,6 +1506,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2042,9 +2062,9 @@ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" -version = "2.2.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" +checksum = "938cc23ac49778ac8340e366ddc422b2227ea176edb447e23fc0627608dddadd" dependencies = [ "arbitrary", "crc32fast", @@ -2053,7 +2073,7 @@ dependencies = [ "flate2", "indexmap", "memchr", - "thiserror", + "thiserror 2.0.12", "zopfli", ] diff --git a/Cargo.toml b/Cargo.toml index aa1f423..e584a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ serde_derive = "1.0.21" toml = "0.8.19" walkdir = "2.0.1" yansi = "1" -zip = { version = "2.1.6", default-features = false, features = ["deflate"] } +zip = { version = "2.3.0", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] pager = "0.16" From 81a0662dbcd5275937a1e8e2d8880bbede8b8133 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 18 Mar 2025 23:02:56 +0100 Subject: [PATCH 150/196] Run CI on backport branches and on dispatch --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9274a0f..f2b9f6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,11 @@ on: push: branches: - main + - "v*.x" pull_request: schedule: - cron: '30 3 * * 2' + workflow_dispatch: jobs: test: From 8f433e7774f9b212ed77a0b3aee1495759f2a91b Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 18 Mar 2025 23:38:12 +0100 Subject: [PATCH 151/196] Release v1.7.2 --- CHANGELOG.md | 16 ++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/usage.txt | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fdd4d..2c8af3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,21 @@ Possible log types: - `[docs]` for documentation changes. - `[chore]` for maintenance work. +### [v1.7.2][v1.7.2] (2025-03-18) + +This patch release updates the `zip` dependency to mitigate a potential security +vulnerability. A successful attack against tealdeer users would require +manipulation of the tldr pages archive downloaded during an update. As the +archive is downloaded from a trusted source (the tldr-pages organization), it +seems very unlikely that running a version of tealdeer prior to 1.7.2 poses a +security risk. Nevertheless, it cannot hurt to rule out any chance of an attack +by updating tealdeer to version 1.7.2. + +For more details, please see https://github.com/advisories/GHSA-94vh-gphv-8pm8. + +- [security] Require `zip >= 2.3.0` +- [chore] Run CI on backport branches and on dispatch + ### [v1.7.1][v1.7.1] (2024-11-14) This patch release updates the `yansi` dependency to version 1, so that the @@ -457,6 +472,7 @@ Thanks! [v1.6.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.0...v1.6.1 [v1.7.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.7.0 [v1.7.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.0...v1.7.1 +[v1.7.2]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.1...v1.7.2 [i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 [i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 diff --git a/Cargo.lock b/Cargo.lock index 582b25d..2652093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,7 +1426,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.7.1" +version = "1.7.2" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index e584a29..59a7d72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" -version = "1.7.1" +version = "1.7.2" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.75" edition = "2021" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 5129fbe..a326eac 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.7.1: A fast TLDR client +tealdeer 1.7.2: A fast TLDR client Danilo Bargen , Niklas Mohrin Usage: tldr [OPTIONS] [COMMAND]... From 9bb95ad11dcc8ce8bf1e79bd1b1c95a84d148c64 Mon Sep 17 00:00:00 2001 From: MHS-0 Date: Sat, 31 May 2025 23:13:39 +0330 Subject: [PATCH 152/196] Add an option to specify a custom config file to be used (#422) Co-authored-by: Niklas Mohrin --- docs/src/usage.txt | 1 + src/cache.rs | 4 +- src/cli.rs | 4 ++ src/config.rs | 146 +++++++++++++++++++++++++++------------------ src/main.rs | 30 ++++++---- src/output.rs | 2 +- src/types.rs | 3 + tests/lib.rs | 118 +++++++++++++++++++++++++++++++++++- 8 files changed, 236 insertions(+), 72 deletions(-) diff --git a/docs/src/usage.txt b/docs/src/usage.txt index a4a5fcb..33e6020 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -18,6 +18,7 @@ Options: -u, --update Update the local cache --no-auto-update If auto update is configured, disable it for this run -c, --clear-cache Clear the local cache + --config-path Override config file location --pager Use a pager to page output -r, --raw Display the raw markdown instead of rendering it -q, --quiet Suppress informational messages diff --git a/src/cache.rs b/src/cache.rs index 76f0abe..c1308f2 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -174,8 +174,8 @@ impl Cache { if let Ok(mtime) = metadata.modified() { let now = SystemTime::now(); return now.duration_since(mtime).ok(); - }; - }; + } + } None } diff --git a/src/cli.rs b/src/cli.rs index 0ba9de9..55fe74f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -74,6 +74,10 @@ pub(crate) struct Cli { #[arg(short = 'c', long = "clear-cache")] pub clear_cache: bool, + /// Override config file location + #[arg(long = "config-path", value_name = "FILE")] + pub config_path: Option, + /// Use a pager to page output #[arg(long = "pager", requires = "command_or_file")] pub pager: bool, diff --git a/src/config.rs b/src/config.rs index 3d82eea..be41dd2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,13 +1,13 @@ use std::{ - env, fmt, fs, - io::{Read, Write}, + env, fmt, + fs::{self, File}, + io::{ErrorKind, Read, Write}, path::{Path, PathBuf}, time::Duration, }; use anyhow::{anyhow, bail, ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; -use log::debug; use serde::Serialize as _; use serde_derive::{Deserialize, Serialize}; use yansi::{Color, Style}; @@ -254,6 +254,14 @@ impl RawConfig { fn new() -> Self { Self::default() } + + fn load(mut config: impl Read) -> Result { + let mut content = String::new(); + config + .read_to_string(&mut content) + .context("Failed to read from config file")?; + toml::from_str(&content).context("Failed to parse TOML config file") + } } impl Default for RawConfig { @@ -276,7 +284,7 @@ impl Default for RawConfig { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct StyleConfig { pub description: Style, pub command_name: Style, @@ -366,6 +374,7 @@ pub struct Config { pub display: DisplayConfig, pub updates: UpdatesConfig, pub directories: DirectoriesConfig, + pub file_path: PathWithSource, } impl Config { @@ -373,10 +382,14 @@ impl Config { /// /// For this, some values need to be converted to other types and some /// defaults need to be set (sometimes based on env variables). - fn from_raw(raw_config: RawConfig, relative_path_root: &Path) -> Result { + fn from_raw(raw_config: RawConfig, config_file_path: PathWithSource) -> Result { let style = raw_config.style.into(); let display = raw_config.display.into(); let updates = raw_config.updates.try_into()?; + let relative_path_root = config_file_path + .path() + .parent() + .context("Failed to get config directory")?; // Determine directories config. For this, we need to take some // additional factory into account, like env variables, or the @@ -438,48 +451,48 @@ impl Config { display, updates, directories, + file_path: config_file_path, }) } - pub fn load(enable_styles: bool) -> Result { - debug!("Loading config"); + /// Load and read the config file from the given path into + /// a [Config] and return it. + /// + /// path: The path to the config file. + pub fn load(path: &Path) -> Result { + let raw_config = RawConfig::load(File::open(path)?)?; + let config = Self::from_raw( + raw_config, + PathWithSource { + path: path.into(), + source: PathSource::Cli, + }, + ) + .context("Could not process raw config")?; + + Ok(config) + } + + /// Load and read the config file from the default path into + /// a [Config] and return it. + pub fn load_default_path() -> Result { // Determine path - let (config_file_path, _) = get_config_path().context("Could not determine config path")?; + let config_file_path = + get_default_config_path().context("Could not determine config path")?; - // Load raw config - let raw_config: RawConfig = if config_file_path.exists() && config_file_path.is_file() { - let mut config_file = fs::File::open(&config_file_path).with_context(|| { - format!("Failed to open config file path at {:?}", &config_file_path) - })?; - let mut contents = String::new(); - config_file.read_to_string(&mut contents).with_context(|| { - format!("Failed to read from config file at {:?}", &config_file_path) - })?; - toml::from_str(&contents).with_context(|| { - format!("Failed to parse TOML config file at {config_file_path:?}") - })? - } else { - RawConfig::new() + let raw_config = match File::open(config_file_path.path()) { + Ok(file) => RawConfig::load(file)?, + Err(e) if e.kind() == ErrorKind::NotFound => RawConfig::default(), + Err(e) => { + return Err(e).context(format!( + "Failed to open config file at {}", + config_file_path.path().display() + )); + } }; - - // Safe to unwrap, it's a file path, so it should have a directory component - let config_file_dir = config_file_path.parent().unwrap(); - - // Convert to config, resolve relative paths from the config file dir - let mut config = - Self::from_raw(raw_config, config_file_dir).context("Could not process raw config")?; - - // Potentially override styles - if !enable_styles { - config.style = StyleConfig { - command_name: Style::default(), - description: Style::default(), - example_text: Style::default(), - example_code: Style::default(), - example_variable: Style::default(), - }; - } + let config = + Self::from_raw(raw_config, config_file_path).context("Could not process raw config")?; Ok(config) } @@ -497,7 +510,7 @@ pub fn get_config_dir() -> Result<(PathBuf, PathSource)> { // $TEALDEER_CONFIG_DIR env variable. if let Ok(value) = env::var("TEALDEER_CONFIG_DIR") { return Ok((PathBuf::from(value), PathSource::EnvVar)); - }; + } // Otherwise, fall back to the user config directory. let dirs = get_app_root(AppDataType::UserConfig, &crate::APP_INFO) @@ -509,29 +522,39 @@ pub fn get_config_dir() -> Result<(PathBuf, PathSource)> { /// /// Note that this function does not verify whether the file at that location /// exists, or is a file. -pub fn get_config_path() -> Result<(PathBuf, PathSource)> { +pub fn get_default_config_path() -> Result { let (config_dir, source) = get_config_dir()?; let config_file_path = config_dir.join(CONFIG_FILE_NAME); - Ok((config_file_path, source)) + Ok(PathWithSource { + path: config_file_path, + source, + }) } /// Create default config file. -pub fn make_default_config() -> Result { - let (config_dir, _) = get_config_dir()?; - - // Ensure that config directory exists - if config_dir.exists() { - ensure!( - config_dir.is_dir(), - "Config directory could not be created: {} already exists but is not a directory", - config_dir.to_string_lossy(), - ); +/// path: Can be specified to create the config in that path instead of +/// the default path. +pub fn make_default_config(path: Option<&Path>) -> Result { + let config_file_path = if let Some(p) = path { + p.into() } else { - fs::create_dir_all(&config_dir).context("Could not create config directory")?; - } + let (config_dir, _) = get_config_dir()?; + + // Ensure that config directory exists + if config_dir.exists() { + ensure!( + config_dir.is_dir(), + "Config directory could not be created: {} already exists but is not a directory", + config_dir.to_string_lossy(), + ); + } else { + fs::create_dir_all(&config_dir).context("Could not create config directory")?; + } + + config_dir.join(CONFIG_FILE_NAME) + }; // Ensure that a config file doesn't get overwritten - let config_file_path = config_dir.join(CONFIG_FILE_NAME); ensure!( !config_file_path.is_file(), "A configuration file already exists at {}, no action was taken.", @@ -544,7 +567,7 @@ pub fn make_default_config() -> Result { // Write default config let mut config_file = - fs::File::create(&config_file_path).context("Could not create config file")?; + File::create(&config_file_path).context("Could not create config file")?; let _wc = config_file .write(serialized_config.as_bytes()) .context("Could not write to config file")?; @@ -566,7 +589,14 @@ fn test_relative_path_resolution() { raw_config.directories.cache_dir = Some("../cache".into()); raw_config.directories.custom_pages_dir = Some("../custom_pages".into()); - let config = Config::from_raw(raw_config, Path::new("/path/to/config")).unwrap(); + let config = Config::from_raw( + raw_config, + PathWithSource { + path: PathBuf::from("/path/to/config/config.toml"), + source: PathSource::OsConvention, + }, + ) + .unwrap(); assert_eq!( config.directories.cache_dir.path(), diff --git a/src/main.rs b/src/main.rs index cfd00db..99403b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,8 @@ use std::{ use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; use clap::Parser; +use config::StyleConfig; +use log::debug; mod cache; mod cli; @@ -50,7 +52,7 @@ mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, cli::Cli, - config::{get_config_dir, get_config_path, make_default_config, Config, PathWithSource}, + config::{get_config_dir, make_default_config, Config, PathWithSource}, extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, @@ -153,10 +155,7 @@ fn show_paths(config: &Config) { } }, ); - let config_path = get_config_path().map_or_else( - |e| format!("[Error: {e}]"), - |(path, _)| path.display().to_string(), - ); + let config_path = config.file_path.to_string(); let cache_dir = config.directories.cache_dir.to_string(); let pages_dir = { let mut path = config.directories.cache_dir.path.clone(); @@ -175,8 +174,8 @@ fn show_paths(config: &Config) { println!("Custom pages dir: {custom_pages_dir}"); } -fn create_config() -> Result<()> { - let config_file_path = make_default_config().context("Could not create seed config")?; +fn create_config(path: Option<&Path>) -> Result<()> { + let config_file_path = make_default_config(path).context("Could not create seed config")?; eprintln!( "Successfully created seed config file here: {}", config_file_path.to_str().unwrap() @@ -279,7 +278,18 @@ fn main() -> ExitCode { fn try_main(args: Cli, enable_styles: bool) -> Result { // Look up config file, if none is found fall back to default config. - let config = Config::load(enable_styles).context("Could not load config")?; + debug!("Loading config"); + let mut config = match &args.config_path { + Some(path) if !args.seed_config => { + Config::load(path).context("Could not load config from given path")? + } + _ => Config::load_default_path().context("Could not load config from default path")?, + }; + + // Override styles if needed + if !enable_styles { + config.style = StyleConfig::default(); + } let custom_pages_dir = config .directories @@ -313,7 +323,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { // Create a basic config and exit if args.seed_config { - create_config()?; + create_config(args.config_path.as_deref())?; return Ok(ExitCode::SUCCESS); } @@ -345,7 +355,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { { // Cache is needed, but missing return Ok(ExitCode::FAILURE); - }; + } // List cached commands and exit if args.list { diff --git a/src/output.rs b/src/output.rs index abef1db..046abe8 100644 --- a/src/output.rs +++ b/src/output.rs @@ -71,7 +71,7 @@ pub fn print_page( !config.display.compact, ) .context("Could not write to stdout")?; - }; + } // We're done outputting data, flush stdout now! handle.flush().context("Could not flush stdout")?; diff --git a/src/types.rs b/src/types.rs index 416d267..69c7599 100644 --- a/src/types.rs +++ b/src/types.rs @@ -205,6 +205,8 @@ pub enum PathSource { EnvVar, /// Config file ConfigFile, + /// CLI argument override + Cli, } impl fmt::Display for PathSource { @@ -216,6 +218,7 @@ impl fmt::Display for PathSource { Self::OsConvention => "OS convention", Self::EnvVar => "env variable", Self::ConfigFile => "config file", + Self::Cli => "command line argument", } ) } diff --git a/tests/lib.rs b/tests/lib.rs index 420eb08..172c1c5 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -70,6 +70,24 @@ impl TestEnv { .expect("Failed to append to config file."); } + fn create_secondary_config(self) -> Self { + self.append_to_secondary_config(format!( + "directories.cache_dir = '{}'\n", + self.cache_dir().to_str().unwrap(), + )); + self + } + + fn append_to_secondary_config(&self, content: impl AsRef) { + File::options() + .create(true) + .append(true) + .open(self.config_dir().join("config-secondary.toml")) + .expect("Failed to open config file") + .write_all(content.as_ref().as_bytes()) + .expect("Failed to append to config file."); + } + fn remove_initial_config(self) -> Self { let _ = fs::remove_file(self.config_dir().join("config.toml")); self @@ -183,6 +201,61 @@ fn test_cannot_build_without_tls_feature() { let _ = TestEnv::new().no_default_features().command(); } +#[test] +fn test_load_the_correct_config() { + let testenv = TestEnv::new() + .install_default_cache() + .create_secondary_config(); + testenv.append_to_secondary_config(include_str!("style-config.toml")); + + let expected_default = include_str!("rendered/inkscape-default.expected"); + let expected_with_config = include_str!("rendered/inkscape-with-config.expected"); + + testenv + .command() + .args(["--color", "always", "inkscape-v2"]) + .assert() + .success() + .stdout(diff(expected_default)); + + testenv + .command() + .args([ + "--color", + "always", + "--config-path", + testenv + .config_dir() + .join("config-secondary.toml") + .to_str() + .unwrap(), + "inkscape-v2", + ]) + .assert() + .success() + .stdout(diff(expected_with_config)); +} + +#[test] +fn test_fail_on_custom_config_path_is_directory() { + let testenv = TestEnv::new(); + let error = if cfg!(windows) { + "Access is denied" + } else { + "Is a directory" + }; + testenv + .command() + .args([ + "--config-path", + testenv.config_dir().to_str().unwrap(), + "sl", + ]) + .assert() + .failure() + .stderr(contains(error)); +} + #[test] fn test_missing_cache() { TestEnv::new() @@ -438,8 +511,9 @@ fn test_setup_seed_config() { .failure() .stderr(contains("A configuration file already exists")); - let testenv = testenv.remove_initial_config(); + assert!(testenv.config_dir().join("config.toml").is_file()); + let testenv = testenv.remove_initial_config(); testenv .command() .args(["--seed-config"]) @@ -448,6 +522,48 @@ fn test_setup_seed_config() { .stderr(contains("Successfully created seed config file here")); assert!(testenv.config_dir().join("config.toml").is_file()); + + // Create parent directories as needed for the default config path. + fs::remove_dir_all(testenv.config_dir()).unwrap(); + testenv + .command() + .args(["--seed-config"]) + .assert() + .success() + .stderr(contains("Successfully created seed config file here")); + + assert!(testenv.config_dir().join("config.toml").is_file()); + + // Write the default config to --config-path if specified by the user + // at the same time. + let custom_config_path = testenv.config_dir().join("config_custom.toml"); + testenv + .command() + .args([ + "--seed-config", + "--config-path", + custom_config_path.to_str().unwrap(), + ]) + .assert() + .success() + .stderr(contains("Successfully created seed config file here")); + + assert!(custom_config_path.is_file()); + + // DON'T create parent directories for a custom config path. + fs::remove_dir_all(testenv.config_dir()).unwrap(); + testenv + .command() + .args([ + "--seed-config", + "--config-path", + custom_config_path.to_str().unwrap(), + ]) + .assert() + .failure() + .stderr(contains("Could not create config file")); + + assert!(!custom_config_path.is_file()); } #[test] From bc820c5f10b1ae54d0c3012575df55d13accfde1 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 6 Jun 2025 22:52:44 +0200 Subject: [PATCH 153/196] Upload binaries from build step as artifact (#423) --- .github/workflows/ci.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c1cdf3..3553418 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,19 +16,33 @@ jobs: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] toolchain: [stable, 1.75.0] + include: + - platform: windows-latest + exe_suffix: .exe runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} + - run: mkdir artifacts - name: Build with default features - run: cargo build + run: | + cargo build + cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-default${{ matrix.exe_suffix}} - name: Build with logging and Rustls with webpki roots - run: cargo build --features logging,rustls-with-webpki-roots --no-default-features + run: | + cargo build --features logging,rustls-with-webpki-roots --no-default-features + cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-logging-rustls-webpki${{ matrix.exe_suffix}} - name: Build with native TLS backend - # expects runners have the proper Native SSL library - run: cargo build --features native-tls --no-default-features + run: | + # expects runners have the proper Native SSL library + cargo build --features native-tls --no-default-features + cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-native-tls${{ matrix.exe_suffix}} + - uses: actions/upload-artifact@v4 + with: + name: tldr-debug-build-${{ matrix.platform }}-rust-${{ matrix.toolchain }} + path: artifacts/ - name: Run tests run: cargo test -- --test-threads 1 From 43ab2cb920f500795fcf9a353a9695eb2d896664 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 6 Jun 2025 23:13:47 +0200 Subject: [PATCH 154/196] Bump MSRV to 1.80 (#426) --- .github/workflows/ci.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3553418..3a99b2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - toolchain: [stable, 1.75.0] + toolchain: [stable, 1.80.1] include: - platform: windows-latest exe_suffix: .exe diff --git a/Cargo.toml b/Cargo.toml index bbd31c7..628c9bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" version = "1.7.2" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] -rust-version = "1.75" +rust-version = "1.80" edition = "2021" [[bin]] From d1be7d6bb92bed580257edcf82d665fb86ff2788 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 6 Jun 2025 23:25:30 +0200 Subject: [PATCH 155/196] Introduce Language struct (#425) * Remove unneeded Clone bound on Dedup * Introduce Language struct to represent language strings * Move language directory name logic into own method on Language type --- src/cache.rs | 26 ++++++++++-------- src/extensions.rs | 4 +-- src/main.rs | 70 ++++++++++++++++++++++++++++++++--------------- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index c1308f2..fdd77da 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -18,6 +18,19 @@ use crate::{config::TlsBackend, types::PlatformType, utils::print_warning}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct Language<'a>(pub &'a str); + +impl Language<'_> { + fn directory_name(&self) -> String { + if *self == Language("en") { + String::from("pages") + } else { + format!("pages.{}", self.0) + } + } +} + #[derive(Debug)] pub struct Cache { cache_dir: PathBuf, @@ -227,7 +240,7 @@ impl Cache { pub fn find_page( &self, name: &str, - languages: &[String], + languages: &[Language<'_>], custom_pages_dir: Option<&Path>, platforms: &[PlatformType], ) -> Option { @@ -237,16 +250,7 @@ impl Cache { // Determine directory paths let pages_dir = self.pages_dir(); - let lang_dirs: Vec = languages - .iter() - .map(|lang| { - if lang == "en" { - String::from("pages") - } else { - format!("pages.{lang}") - } - }) - .collect(); + let lang_dirs: Vec = languages.iter().map(Language::directory_name).collect(); // Look up custom page (.page.md). If it exists, return it directly if let Some(config_dir) = custom_pages_dir { diff --git a/src/extensions.rs b/src/extensions.rs index 3aebfa2..e74e9f3 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -1,14 +1,14 @@ use std::mem; /// An extension trait to clear duplicates from a collection. -pub(crate) trait Dedup { +pub(crate) trait Dedup { fn clear_duplicates(&mut self); } /// Clear duplicates from a collection, keep the first one seen. /// /// For small vectors, this will be faster than a `HashSet`. -impl Dedup for Vec { +impl Dedup for Vec { fn clear_duplicates(&mut self) { let orig = mem::replace(self, Vec::with_capacity(self.len())); for item in orig { diff --git a/src/main.rs b/src/main.rs index 99403b9..2113de0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,10 +31,12 @@ use std::{ io::{self, IsTerminal}, path::Path, process::{Command, ExitCode}, + sync::LazyLock, }; use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; +use cache::Language; use clap::Parser; use config::StyleConfig; use log::debug; @@ -191,14 +193,16 @@ fn init_log() { #[cfg(not(feature = "logging"))] fn init_log() {} -fn get_languages(env_lang: Option<&str>, env_language: Option<&str>) -> Vec { +fn get_languages<'a>( + env_lang: Option<&'a str>, + env_language: Option<&'a str>, +) -> Vec> { // Language list according to // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#language - if env_lang.is_none() { - return vec!["en".to_string()]; - } - let env_lang = env_lang.unwrap(); + let Some(env_lang) = env_lang else { + return vec![Language("en")]; + }; // Create an iterator that contains $LANGUAGE (':' separated list) followed by $LANG (single language) let locales = env_language.unwrap_or("").split(':').chain([env_lang]); @@ -207,23 +211,25 @@ fn get_languages(env_lang: Option<&str>, env_language: Option<&str>) -> Vec= 5 && locale.chars().nth(2) == Some('_') { - lang_list.push(&locale[..5]); + lang_list.push(Language(&locale[..5])); } // Language code only (e.g. `en`) if locale.len() >= 2 && locale != "POSIX" { - lang_list.push(&locale[..2]); + lang_list.push(Language(&locale[..2])); } } - lang_list.push("en"); + lang_list.push(Language("en")); lang_list.clear_duplicates(); - lang_list.into_iter().map(str::to_string).collect() + lang_list } -fn get_languages_from_env() -> Vec { +fn get_languages_from_env<'a>() -> Vec> { + static LANG: LazyLock> = LazyLock::new(|| std::env::var("LANG").ok()); + static LANGUAGE: LazyLock> = LazyLock::new(|| std::env::var("LANGUAGE").ok()); get_languages( - std::env::var("LANG").ok().as_deref(), - std::env::var("LANGUAGE").ok().as_deref(), + LANG.as_ref().map(String::as_str), + LANGUAGE.as_ref().map(String::as_str), ) } @@ -372,7 +378,8 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { // Collect languages let languages = args .language - .map_or_else(get_languages_from_env, |lang| vec![lang]); + .as_deref() + .map_or_else(get_languages_from_env, |lang| vec![Language(lang)]); // Search for command in cache let Some(lookup_result) = cache.find_page( @@ -422,7 +429,7 @@ fn compute_platforms(platforms: Option<&Vec>) -> Vec #[cfg(test)] mod test { - use crate::get_languages; + use super::*; mod language { use super::*; @@ -430,41 +437,60 @@ mod test { #[test] fn missing_lang_env() { let lang_list = get_languages(None, Some("de:fr")); - assert_eq!(lang_list, ["en"]); + assert_eq!(lang_list, [Language("en")]); let lang_list = get_languages(None, None); - assert_eq!(lang_list, ["en"]); + assert_eq!(lang_list, [Language("en")]); } #[test] fn missing_language_env() { let lang_list = get_languages(Some("de"), None); - assert_eq!(lang_list, ["de", "en"]); + assert_eq!(lang_list, [Language("de"), Language("en")]); } #[test] fn preference_order() { let lang_list = get_languages(Some("de"), Some("fr:cn")); - assert_eq!(lang_list, ["fr", "cn", "de", "en"]); + assert_eq!( + lang_list, + [ + Language("fr"), + Language("cn"), + Language("de"), + Language("en") + ] + ); } #[test] fn country_code_expansion() { let lang_list = get_languages(Some("pt_BR"), None); - assert_eq!(lang_list, ["pt_BR", "pt", "en"]); + assert_eq!( + lang_list, + [Language("pt_BR"), Language("pt"), Language("en")] + ); } #[test] fn ignore_posix_and_c() { let lang_list = get_languages(Some("POSIX"), None); - assert_eq!(lang_list, ["en"]); + assert_eq!(lang_list, [Language("en")]); let lang_list = get_languages(Some("C"), None); - assert_eq!(lang_list, ["en"]); + assert_eq!(lang_list, [Language("en")]); } #[test] fn no_duplicates() { let lang_list = get_languages(Some("de"), Some("fr:de:cn:de")); - assert_eq!(lang_list, ["fr", "de", "cn", "en"]); + assert_eq!( + lang_list, + [ + Language("fr"), + Language("de"), + Language("cn"), + Language("en") + ] + ); } } } From 1e87db7ab74e7d271849b9bc724e3c5ddd096cb3 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 1 Aug 2025 16:03:01 +0200 Subject: [PATCH 156/196] Cache rewrite (#416) --- Cargo.lock | 1 - Cargo.toml | 1 - src/cache.rs | 636 +++++++----------- src/main.rs | 220 +++--- .../common/git-checkout.md | 0 .../{pages => pages.en}/common/inkscape-v1.md | 0 .../{pages => pages.en}/common/inkscape-v2.md | 0 .../cache/{pages => pages.en}/common/which.md | 0 tests/lib.rs | 111 ++- 9 files changed, 462 insertions(+), 507 deletions(-) rename tests/cache/{pages => pages.en}/common/git-checkout.md (100%) rename tests/cache/{pages => pages.en}/common/inkscape-v1.md (100%) rename tests/cache/{pages => pages.en}/common/inkscape-v2.md (100%) rename tests/cache/{pages => pages.en}/common/which.md (100%) diff --git a/Cargo.lock b/Cargo.lock index e8db079..4da46ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1068,7 +1068,6 @@ dependencies = [ "tempfile", "toml", "ureq", - "walkdir", "yansi", "zip", ] diff --git a/Cargo.toml b/Cargo.toml index 628c9bb..6594b14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ serde = "1.0.21" serde_derive = "1.0.21" ureq = { version = "3.0.8", default-features = false, features = ["gzip"] } toml = "0.8.19" -walkdir = "2.0.1" yansi = "1" zip = { version = "2.3.0", default-features = false, features = ["deflate"] } diff --git a/src/cache.rs b/src/cache.rs index fdd77da..c18f03f 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,41 +1,38 @@ use std::{ - ffi::OsStr, fs::{self, File}, - io::{BufReader, Cursor, Read}, + io::{BufReader, Cursor, ErrorKind, Read}, path::{Path, PathBuf}, time::{Duration, SystemTime}, }; -use anyhow::{ensure, Context, Result}; +use anyhow::{anyhow, bail, ensure, Context, Result}; use log::debug; -use ureq::tls::{RootCerts, TlsConfig, TlsProvider}; -use ureq::Agent; -use walkdir::{DirEntry, WalkDir}; +use ureq::{ + http::StatusCode, + tls::{RootCerts, TlsConfig, TlsProvider}, + Agent, +}; use zip::ZipArchive; -use crate::{config::TlsBackend, types::PlatformType, utils::print_warning}; +use crate::{config::TlsBackend, types::PlatformType}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; -static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; +pub static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; #[derive(Debug, PartialEq, Eq, Hash)] pub struct Language<'a>(pub &'a str); -impl Language<'_> { - fn directory_name(&self) -> String { - if *self == Language("en") { - String::from("pages") - } else { - format!("pages.{}", self.0) - } - } +#[derive(Clone)] +pub struct CacheConfig<'a> { + pub pages_directory: &'a Path, + pub custom_pages_directory: Option<&'a Path>, + pub platforms: &'a [PlatformType], + pub languages: &'a [Language<'a>], } -#[derive(Debug)] -pub struct Cache { - cache_dir: PathBuf, - enable_styles: bool, - tls_backend: TlsBackend, +/// The directory backing this cache is checked to be populated at construction. +pub struct Cache<'a> { + config: CacheConfig<'a>, } #[derive(Debug)] @@ -44,6 +41,218 @@ pub struct PageLookupResult { pub patch_path: Option, } +impl<'a> Cache<'a> { + /// Try opening a cache at the location given by `config.pages_directory`. If no directory + /// exists at this location, `Ok(None)` is returned. + pub fn open(config: CacheConfig<'a>) -> Result> { + match config.pages_directory.metadata() { + Ok(md) => { + ensure!( + md.is_dir(), + "Cache directory `{}` exists, but is not a directory.", + config.pages_directory.display(), + ); + Ok(Some(Cache { config })) + } + Err(err) if err.kind() == ErrorKind::NotFound => Ok(None), + Err(err) => Err(anyhow!(err).context(format!( + "Error getting metdata of cache directory {}", + config.pages_directory.display() + ))), + } + } + + /// Open an existing cache at `config.pages_directory` or create one if no cache resides at + /// this location. In case of success, the return value is a tuple with the `Cache` and a + /// boolean indicating whether the cache was newly created. + pub fn open_or_create(config: CacheConfig<'a>) -> Result<(Self, bool)> { + if let Some(cache) = Self::open(config.clone())? { + return Ok((cache, false)); + } + + fs::create_dir_all(config.pages_directory).with_context(|| { + format!( + "Cache directory `{}` cannot be created", + config.pages_directory.display(), + ) + })?; + eprintln!( + "Successfully created cache directory `{}`.", + config.pages_directory.display(), + ); + + Ok((Cache { config }, true)) + } + + pub fn age(&self) -> Result { + let mtime = self.config.pages_directory.metadata()?.modified()?; + SystemTime::now() + .duration_since(mtime) + .context("Error comparing cache mtime with current time") + } + + pub fn find_page(&self, command: &str) -> Option { + let page_filename = format!("{command}.md"); + let patch_filename = format!("{command}.patch.md"); + let custom_filename = format!("{command}.page.md"); + + if let Some(custom_pages_dir) = self.config.custom_pages_directory { + let custom_page = custom_pages_dir.join(custom_filename); + if custom_page.is_file() { + return Some(PageLookupResult::with_page(custom_page)); + } + } + + let patch_path = self + .config + .custom_pages_directory + .map(|dir| dir.join(&patch_filename)) + .filter(|path| path.is_file()); + + for &platform in self.config.platforms { + for language in self.config.languages { + let mut search_path = self.config.pages_directory.to_path_buf(); + search_path.push(language.directory_name()); + search_path.push(platform.directory_name()); + search_path.push(&page_filename); + + if search_path.is_file() { + return Some( + PageLookupResult::with_page(search_path).with_optional_patch(patch_path), + ); + } + } + } + + None + } + + pub fn list_pages(&self) -> Result> { + let mut pages = Vec::new(); + + let mut append_all = |directory: &Path, suffix: &str| -> Result<()> { + let Ok(file_iter) = fs::read_dir(directory) else { + return Ok(()); + }; + + for entry in file_iter { + let entry = entry?; + if entry.file_type()?.is_file() { + let mut page_path = entry + .file_name() + .into_string() + .map_err(|_| anyhow!("Found invalid filename: {:?}", entry.path()))?; + + if page_path.ends_with(suffix) { + page_path.truncate(page_path.len() - suffix.len()); + pages.push(page_path); + } else { + debug!( + "Skipping page entry not ending in \".md\": {:?}", + entry.path(), + ); + } + } + } + + Ok(()) + }; + + let mut search_path = self.config.pages_directory.to_path_buf(); + for language in self.config.languages { + search_path.push(language.directory_name()); + for platform in self.config.platforms { + search_path.push(platform.directory_name()); + append_all(&search_path, ".md")?; + search_path.pop(); + } + search_path.pop(); + } + + if let Some(custom_pages_dir) = self.config.custom_pages_directory { + append_all(custom_pages_dir, ".page.md")?; + } + + pages.sort_unstable(); + pages.dedup(); + Ok(pages) + } + + pub fn old_custom_pages_exist(&self) -> Result { + let Some(directory) = self.config.custom_pages_directory else { + return Ok(false); + }; + let Ok(file_iter) = fs::read_dir(directory) else { + return Ok(false); + }; + + for entry in file_iter { + if let Some(extension) = entry?.path().extension() { + if extension == "page" || extension == "patch" { + return Ok(true); + } + } + } + + Ok(false) + } + + pub fn clear(self) -> Result<()> { + fs::remove_dir_all(self.config.pages_directory).with_context(|| { + format!( + "Could not remove pages directory at {}", + self.config.pages_directory.display(), + ) + }) + } + + pub fn update(&mut self, archive_url: &str, tls_backend: TlsBackend) -> Result<()> { + let client = Self::build_client(tls_backend); + + // Download everything before deleting anything + let archives = self + .config + .languages + .iter() + .map(|lang| { + Ok(( + lang, + Self::download( + &client, + &format!("{archive_url}/tldr-{}.zip", lang.directory_name()), + )? + .map(|bytes| ZipArchive::new(Cursor::new(bytes))) + .transpose()?, + )) + }) + .collect::>>()?; + + // Clear cache directory + // Note: This is not the best solution. Ideally we would download the + // archive to a temporary directory and then swap the two directories. + // But renaming a directory doesn't work across filesystems and Rust + // does not yet offer a recursive directory copying function. So for + // now, we'll use this approach. + fs::remove_dir_all(self.config.pages_directory)?; + fs::create_dir(self.config.pages_directory)?; + + for (lang, archive) in archives { + if let Some(mut archive) = archive { + debug!("Extracting archive for {lang:?}"); + archive.extract(self.config.pages_directory.join(lang.directory_name()))?; + } else { + debug!("No archive found for {lang:?}"); + } + } + + Ok(()) + } + + pub fn config(&self) -> &CacheConfig<'a> { + &self.config + } +} + impl PageLookupResult { pub fn with_page(page_path: PathBuf) -> Self { Self { @@ -90,120 +299,15 @@ impl PageLookupResult { } } -pub enum CacheFreshness { - /// The cache is still fresh (less than `MAX_CACHE_AGE` old) - Fresh, - /// The cache is stale and should be updated - Stale(Duration), - /// The cache is missing - Missing, +impl Language<'_> { + fn directory_name(&self) -> String { + format!("pages.{}", self.0) + } } -impl Cache { - pub fn new

(cache_dir: P, enable_styles: bool, tls_backend: TlsBackend) -> Self - where - P: Into, - { - Self { - cache_dir: cache_dir.into(), - enable_styles, - tls_backend, - } - } - - pub fn cache_dir(&self) -> &Path { - &self.cache_dir - } - - /// Make sure that the cache directory exists and is a directory. - /// If necessary, create the directory. - fn ensure_cache_dir_exists(&self) -> Result<()> { - // Check whether `cache_dir` exists and is a directory - let (cache_dir_exists, cache_dir_is_dir) = self - .cache_dir - .metadata() - .map_or((false, false), |md| (true, md.is_dir())); - ensure!( - !cache_dir_exists || cache_dir_is_dir, - "Cache directory path `{}` is not a directory", - self.cache_dir.display(), - ); - - if !cache_dir_exists { - // If missing, try to create the complete directory path - fs::create_dir_all(&self.cache_dir).with_context(|| { - format!( - "Cache directory path `{}` cannot be created", - self.cache_dir.display(), - ) - })?; - eprintln!( - "Successfully created cache directory path `{}`.", - self.cache_dir.display(), - ); - } - - Ok(()) - } - - fn pages_dir(&self) -> PathBuf { - self.cache_dir.join(TLDR_PAGES_DIR) - } - - /// Update the pages cache from the specified URL. - pub fn update(&self, archive_source: &str) -> Result<()> { - self.ensure_cache_dir_exists()?; - - let archive_url = format!("{archive_source}/tldr.zip"); - - let client = Self::build_client(self.tls_backend)?; - // First, download the compressed data - let bytes: Vec = Self::download(&client, &archive_url)?; - - // Decompress the response body into an `Archive` - let mut archive = ZipArchive::new(Cursor::new(bytes)) - .context("Could not decompress downloaded ZIP archive")?; - - // Clear cache directory - // Note: This is not the best solution. Ideally we would download the - // archive to a temporary directory and then swap the two directories. - // But renaming a directory doesn't work across filesystems and Rust - // does not yet offer a recursive directory copying function. So for - // now, we'll use this approach. - self.clear() - .context("Could not clear the cache directory")?; - - // Extract archive into pages dir - archive - .extract(self.pages_dir()) - .context("Could not unpack compressed data")?; - - Ok(()) - } - - /// Return the duration since the cache directory was last modified. - pub fn last_update(&self) -> Option { - if let Ok(metadata) = fs::metadata(self.pages_dir()) { - if let Ok(mtime) = metadata.modified() { - let now = SystemTime::now(); - return now.duration_since(mtime).ok(); - } - } - None - } - - /// Return the freshness of the cache (fresh, stale or missing). - pub fn freshness(&self) -> CacheFreshness { - match self.last_update() { - Some(ago) if ago > crate::config::MAX_CACHE_AGE => CacheFreshness::Stale(ago), - Some(_) => CacheFreshness::Fresh, - None => CacheFreshness::Missing, - } - } - - /// Return the platform directory. - fn get_platform_dir(platform: PlatformType) -> &'static str { - match platform { +impl PlatformType { + fn directory_name(self) -> &'static str { + match self { PlatformType::Linux => "linux", PlatformType::OsX => "osx", PlatformType::SunOs => "sunos", @@ -215,224 +319,10 @@ impl Cache { PlatformType::Common => "common", } } - - /// Check for pages for a given platform in one of the given languages. - fn find_page_for_platform( - page_name: &str, - pages_dir: &Path, - platform: &str, - language_dirs: &[String], - ) -> Option { - language_dirs - .iter() - .map(|lang_dir| pages_dir.join(lang_dir).join(platform).join(page_name)) - .find(|path| path.exists() && path.is_file()) - } - - /// Look up custom patch (.patch.md). If it exists, store it in a variable. - fn find_patch(patch_name: &str, custom_pages_dir: Option<&Path>) -> Option { - custom_pages_dir - .map(|custom_dir| custom_dir.join(patch_name)) - .filter(|path| path.exists() && path.is_file()) - } - - /// Search for a page and return the path to it. - pub fn find_page( - &self, - name: &str, - languages: &[Language<'_>], - custom_pages_dir: Option<&Path>, - platforms: &[PlatformType], - ) -> Option { - let page_filename = format!("{name}.md"); - let patch_filename = format!("{name}.patch.md"); - let custom_filename = format!("{name}.page.md"); - - // Determine directory paths - let pages_dir = self.pages_dir(); - let lang_dirs: Vec = languages.iter().map(Language::directory_name).collect(); - - // Look up custom page (.page.md). If it exists, return it directly - if let Some(config_dir) = custom_pages_dir { - // TODO: Remove this check 1 year after version 1.7.0 was released - self.check_for_old_custom_pages(config_dir); - - let custom_page = config_dir.join(custom_filename); - if custom_page.exists() && custom_page.is_file() { - return Some(PageLookupResult::with_page(custom_page)); - } - } - - let patch_path = Self::find_patch(&patch_filename, custom_pages_dir); - - // Try to find a platform specific path next, in the order supplied by the user, and append custom patch to it. - for &platform in platforms { - let platform_dir = Cache::get_platform_dir(platform); - if let Some(page) = - Self::find_page_for_platform(&page_filename, &pages_dir, platform_dir, &lang_dirs) - { - return Some(PageLookupResult::with_page(page).with_optional_patch(patch_path)); - } - } - - None - } - - /// Return the available pages. - pub fn list_pages( - &self, - custom_pages_dir: Option<&Path>, - platforms: &[PlatformType], - ) -> Vec { - // Determine platforms directory and platform - let platforms_dir = self.pages_dir().join("pages"); - let platform_dirs: Vec<&'static str> = platforms - .iter() - .map(|&p| Self::get_platform_dir(p)) - .collect(); - - // Closure that allows the WalkDir instance to traverse platform - // relevant page directories, but not others. - let should_walk = |entry: &DirEntry| -> bool { - let file_type = entry.file_type(); - let Some(file_name) = entry.file_name().to_str() else { - return false; - }; - if file_type.is_dir() { - return platform_dirs.contains(&file_name); - } else if file_type.is_file() { - return true; - } - false - }; - - let to_stem = |entry: DirEntry| -> Option { - entry - .path() - .file_stem() - .and_then(OsStr::to_str) - .map(str::to_string) - }; - - let to_stem_custom = |entry: DirEntry| -> Option { - entry - .path() - .file_name() - .and_then(OsStr::to_str) - .and_then(|s| s.strip_suffix(".page.md")) - .map(str::to_string) - }; - - // Recursively walk through platform specific directory - let mut pages = WalkDir::new(platforms_dir) - .min_depth(1) // Skip root directory - .into_iter() - .filter_entry(should_walk) // Filter out pages for other architectures - .filter_map(Result::ok) // Convert results to options, filter out errors - .filter_map(|e| { - let extension = e.path().extension().unwrap_or_default(); - if e.file_type().is_file() && extension == "md" { - to_stem(e) - } else { - None - } - }) - .collect::>(); - - if let Some(custom_pages_dir) = custom_pages_dir { - let is_page = |entry: &DirEntry| -> bool { - entry.file_type().is_file() - && entry - .path() - .file_name() - .and_then(OsStr::to_str) - .is_some_and(|file_name| file_name.ends_with(".page.md")) - }; - - let custom_pages = WalkDir::new(custom_pages_dir) - .min_depth(1) - .max_depth(1) - .into_iter() - .filter_entry(is_page) - .filter_map(Result::ok) - .filter_map(to_stem_custom); - - pages.extend(custom_pages); - } - - pages.sort(); - pages.dedup(); - pages - } - - /// Delete the cache directory - /// - /// Returns true if the cache was deleted and false if the cache dir did - /// not exist. - pub fn clear(&self) -> Result { - if !self.cache_dir.exists() { - return Ok(false); - } - ensure!( - self.cache_dir.is_dir(), - "Cache path ({}) is not a directory.", - self.cache_dir.display(), - ); - - // Delete old tldr-pages cache location as well if present - // TODO: To be removed in the future - for pages_dir_name in [TLDR_PAGES_DIR, TLDR_OLD_PAGES_DIR] { - let pages_dir = self.cache_dir.join(pages_dir_name); - - if pages_dir.exists() { - fs::remove_dir_all(&pages_dir).with_context(|| { - format!( - "Could not remove the cache directory at {}", - pages_dir.display() - ) - })?; - } - } - - Ok(true) - } - - /// Check for old custom pages (without .md suffix) and print a warning. - fn check_for_old_custom_pages(&self, custom_pages_dir: &Path) { - let old_custom_pages_exist = WalkDir::new(custom_pages_dir) - .min_depth(1) - .max_depth(1) - .into_iter() - .filter_entry(|entry| entry.file_type().is_file()) - .any(|entry| { - if let Ok(entry) = entry { - let extension = entry.path().extension(); - if let Some(extension) = extension { - extension == "page" || extension == "patch" - } else { - false - } - } else { - false - } - }); - if old_custom_pages_exist { - print_warning( - self.enable_styles, - &format!( - "Custom pages using the old naming convention were found in {}.\n\ - Please rename them to follow the new convention:\n\ - - `.page` → `.page.md`\n\ - - `.patch` → `.patch.md`", - custom_pages_dir.display() - ), - ); - } - } } -impl Cache { - fn build_client(tls_backend: TlsBackend) -> Result { +impl Cache<'_> { + fn build_client(tls_backend: TlsBackend) -> Agent { let tls_builder = match tls_backend { #[cfg(feature = "native-tls")] TlsBackend::NativeTls => TlsConfig::builder() @@ -448,22 +338,32 @@ impl Cache { .root_certs(RootCerts::PlatformVerifier), }; let config = Agent::config_builder() + .http_status_as_error(false) // because we want to handle them .tls_config(tls_builder.build()) .build(); - Ok(config.into()) + config.into() } /// Download the archive from the specified URL. - fn download(client: &Agent, archive_url: &str) -> Result> { - let response = client - .get(archive_url) - .call() - .with_context(|| format!("Could not download tldr pages from {archive_url}"))?; - let mut buf: Vec = Vec::new(); - response.into_body().into_reader().read_to_end(&mut buf)?; - debug!("{} bytes downloaded", buf.len()); - Ok(buf) + fn download(client: &Agent, archive_url: &str) -> Result>> { + debug!("Downloading archive from {archive_url}"); + let response = client.get(archive_url).call(); + match response { + Ok(response) if response.status().is_success() => { + let mut buf: Vec = Vec::new(); + response.into_body().into_reader().read_to_end(&mut buf)?; + debug!("{} bytes downloaded", buf.len()); + Ok(Some(buf)) + } + Ok(response) if response.status() == StatusCode::NOT_FOUND => Ok(None), + _ => { + bail!( + "Could not download tldr pages from {archive_url}: {:?}", + response, + ) + } + } } } @@ -521,22 +421,4 @@ mod tests { assert_eq!(&buf, b"Hello\n"); } - - #[test] - #[cfg(feature = "native-tls")] - fn test_create_https_client_with_native_tls() { - Cache::build_client(TlsBackend::NativeTls).expect("fails to build a client."); - } - - #[test] - #[cfg(feature = "rustls-with-webpki-roots")] - fn test_create_https_client_with_rustls() { - Cache::build_client(TlsBackend::RustlsWithWebpkiRoots).expect("fails to build a client."); - } - - #[test] - #[cfg(feature = "rustls-with-native-roots")] - fn test_create_https_client_with_rustls_with_native_roots() { - Cache::build_client(TlsBackend::RustlsWithNativeRoots).expect("fails to build a client."); - } } diff --git a/src/main.rs b/src/main.rs index 2113de0..3797f0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,9 +36,9 @@ use std::{ use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; -use cache::Language; +use cache::{CacheConfig, Language, TLDR_OLD_PAGES_DIR}; use clap::Parser; -use config::StyleConfig; +use config::{StyleConfig, TlsBackend}; use log::debug; mod cache; @@ -52,7 +52,7 @@ mod types; mod utils; use crate::{ - cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, + cache::{Cache, PageLookupResult, TLDR_PAGES_DIR}, cli::Cli, config::{get_config_dir, make_default_config, Config, PathWithSource}, extensions::Dedup, @@ -67,77 +67,25 @@ const APP_INFO: AppInfo = AppInfo { author: NAME, }; -/// The cache should be updated if it was explicitly requested, -/// or if an automatic update is due and allowed. -fn should_update_cache(cache: &Cache, args: &Cli, config: &Config) -> bool { - args.update - || (!args.no_auto_update - && config.updates.auto_update - && cache - .last_update() - .map_or(true, |ago| ago >= config.updates.auto_update_interval)) -} - -#[derive(PartialEq)] -enum CheckCacheResult { - CacheFound, - CacheMissing, -} - -/// Check the cache for freshness. If it's stale or missing, show a warning. -fn check_cache(cache: &Cache, args: &Cli, enable_styles: bool) -> CheckCacheResult { - match cache.freshness() { - CacheFreshness::Fresh => CheckCacheResult::CacheFound, - CacheFreshness::Stale(_) if args.quiet => CheckCacheResult::CacheFound, - CacheFreshness::Stale(age) => { - print_warning( - enable_styles, - &format!( - "The cache hasn't been updated for {} days.\n\ - You should probably run `tldr --update` soon.", - age.as_secs() / 24 / 3600 - ), - ); - CheckCacheResult::CacheFound - } - CacheFreshness::Missing => { - print_error( - enable_styles, - &anyhow::anyhow!( - "Page cache not found. Please run `tldr --update` to download the cache." - ), - ); - println!("\nNote: You can optionally enable automatic cache updates by adding the"); - println!("following config to your config file:\n"); - println!(" [updates]"); - println!(" auto_update = true\n"); - println!("The path to your config file can be looked up with `tldr --show-paths`."); - println!("To create an initial config file, use `tldr --seed-config`.\n"); - println!("You can find more tips and tricks in our docs:\n"); - println!(" https://tealdeer-rs.github.io/tealdeer/config_updates.html"); - CheckCacheResult::CacheMissing - } - } -} - /// Clear the cache -fn clear_cache(cache: &Cache, quietly: bool) -> Result<()> { - let cache_dir_found = cache.clear().context("Could not clear cache")?; +fn clear_cache(cache: Cache, quietly: bool) -> Result<()> { + let cache_dir = cache.config().pages_directory.display(); + cache.clear().context("Could not clear cache")?; if !quietly { - let cache_dir = cache.cache_dir().display(); - if cache_dir_found { - eprintln!("Successfully cleared cache at `{cache_dir}`."); - } else { - eprintln!("Cache directory not found at `{cache_dir}`, nothing to do."); - } + eprintln!("Successfully cleared cache at `{cache_dir}`."); } Ok(()) } /// Update the cache -fn update_cache(cache: &Cache, archive_source: &str, quietly: bool) -> Result<()> { +fn update_cache( + cache: &mut Cache, + archive_source: &str, + tls_backend: TlsBackend, + quietly: bool, +) -> Result<()> { cache - .update(archive_source) + .update(archive_source, tls_backend) .context("Could not update cache")?; if !quietly { eprintln!("Successfully updated cache."); @@ -333,8 +281,6 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { return Ok(ExitCode::SUCCESS); } - let platforms = compute_platforms(args.platforms.as_ref()); - // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); @@ -342,56 +288,120 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { return Ok(ExitCode::SUCCESS); } - // Instantiate cache. This will not yet create the cache directory! - let cache = Cache::new( - &config.directories.cache_dir.path, - enable_styles, - config.updates.tls_backend, - ); + let platforms = compute_platforms(args.platforms.as_ref()); + let languages = args + .language + .as_deref() + .map_or_else(get_languages_from_env, |lang| vec![Language(lang)]); + + let cache_config = CacheConfig { + pages_directory: &config.directories.cache_dir.path().join(TLDR_PAGES_DIR), + custom_pages_directory: config + .directories + .custom_pages_dir + .as_ref() + .map(PathWithSource::path), + platforms: &platforms, + languages: &languages, + }; + + // TODO: remove in tealdeer 1.9 + let old_config = CacheConfig { + pages_directory: &config.directories.cache_dir.path().join(TLDR_OLD_PAGES_DIR), + ..cache_config + }; + if let Ok(Some(old_cache)) = Cache::open(old_config) { + old_cache.clear()?; + eprintln!("Cleared pages from old cache location."); + } - // Clear cache, pass through if args.clear_cache { - clear_cache(&cache, args.quiet)?; + if let Some(cache) = Cache::open(cache_config)? { + clear_cache(cache, args.quiet)?; + } + return Ok(ExitCode::SUCCESS); } - if should_update_cache(&cache, &args, &config) { - update_cache(&cache, &config.updates.archive_source, args.quiet)?; - } else if (args.list || !args.command.is_empty()) - && check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing - { - // Cache is needed, but missing - return Ok(ExitCode::FAILURE); - } + let cache = if args.update || config.updates.auto_update && !args.no_auto_update { + let (mut cache, was_created) = Cache::open_or_create(cache_config)?; + if was_created || args.update || cache.age()? >= config.updates.auto_update_interval { + update_cache( + &mut cache, + &config.updates.archive_source, + config.updates.tls_backend, + args.quiet, + )?; + } + + cache + } else if args.list || !command.is_empty() { + // Cache is needed for these commands to work + let Some(cache) = Cache::open(cache_config)? else { + print_error( + enable_styles, + &anyhow::anyhow!( + "Page cache not found. Please run `tldr --update` to download the cache." + ), + ); + println!("\nNote: You can optionally enable automatic cache updates by adding the"); + println!("following config to your config file:\n"); + println!(" [updates]"); + println!(" auto_update = true\n"); + println!("The path to your config file can be looked up with `tldr --show-paths`."); + println!("To create an initial config file, use `tldr --seed-config`.\n"); + println!("You can find more tips and tricks in our docs:\n"); + println!(" https://tealdeer-rs.github.io/tealdeer/config_updates.html"); + + return Ok(ExitCode::FAILURE); + }; + + let age = cache.age()?; + if age > config::MAX_CACHE_AGE && !args.quiet { + print_warning( + enable_styles, + &format!( + "The cache hasn't been updated for {} days.\n\ + You should probably run `tldr --update` soon.", + age.as_secs() / 24 / 3600 + ), + ); + } + + cache + } else { + // There is nothing left to do + return Ok(ExitCode::SUCCESS); + }; - // List cached commands and exit if args.list { - println!( - "{}", - cache.list_pages(custom_pages_dir, &platforms).join("\n") - ); + for page in cache.list_pages()? { + println!("{page}"); + } return Ok(ExitCode::SUCCESS); } // Show command from cache if !command.is_empty() { - // Collect languages - let languages = args - .language - .as_deref() - .map_or_else(get_languages_from_env, |lang| vec![Language(lang)]); + // TODO: Remove this check 1 year after version 1.7.0 was released + if cache.old_custom_pages_exist()? { + print_warning( + enable_styles, + &format!( + "Custom pages using the old naming convention were found in {}.\n\ + Please rename them to follow the new convention:\n\ + - `.page` → `.page.md`\n\ + - `.patch` → `.patch.md`", + cache + .config() + .custom_pages_directory + .expect("Old custom pages can only exist in custom pages directory") + .display(), + ), + ); + } - // Search for command in cache - let Some(lookup_result) = cache.find_page( - &command, - &languages, - config - .directories - .custom_pages_dir - .as_ref() - .map(PathWithSource::path), - &platforms, - ) else { + let Some(lookup_result) = cache.find_page(&command) else { if !args.quiet { print_warning( enable_styles, diff --git a/tests/cache/pages/common/git-checkout.md b/tests/cache/pages.en/common/git-checkout.md similarity index 100% rename from tests/cache/pages/common/git-checkout.md rename to tests/cache/pages.en/common/git-checkout.md diff --git a/tests/cache/pages/common/inkscape-v1.md b/tests/cache/pages.en/common/inkscape-v1.md similarity index 100% rename from tests/cache/pages/common/inkscape-v1.md rename to tests/cache/pages.en/common/inkscape-v1.md diff --git a/tests/cache/pages/common/inkscape-v2.md b/tests/cache/pages.en/common/inkscape-v2.md similarity index 100% rename from tests/cache/pages/common/inkscape-v2.md rename to tests/cache/pages.en/common/inkscape-v2.md diff --git a/tests/cache/pages/common/which.md b/tests/cache/pages.en/common/which.md similarity index 100% rename from tests/cache/pages/common/which.md rename to tests/cache/pages.en/common/which.md diff --git a/tests/lib.rs b/tests/lib.rs index 172c1c5..2a1665c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -16,6 +16,7 @@ use predicates::{ use tempfile::{Builder as TempfileBuilder, TempDir}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; +pub static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; struct TestEnv { _test_dir: TempDir, @@ -36,9 +37,9 @@ impl TestEnv { features: vec![], }; - create_dir_all(&this.cache_dir()).unwrap(); - create_dir_all(&this.config_dir()).unwrap(); - create_dir_all(&this.custom_pages_dir()).unwrap(); + create_dir_all(this.cache_dir()).unwrap(); + create_dir_all(this.config_dir()).unwrap(); + create_dir_all(this.custom_pages_dir()).unwrap(); this.append_to_config(format!( "directories.cache_dir = '{}'\n", @@ -100,7 +101,11 @@ impl TestEnv { /// Add entry for that environment to an OS-specific subfolder. fn add_os_entry(&self, os: &str, name: &str, contents: &str) { - let dir = self.cache_dir().join(TLDR_PAGES_DIR).join("pages").join(os); + let dir = self + .cache_dir() + .join(TLDR_PAGES_DIR) + .join("pages.en") + .join(os); create_dir_all(&dir).unwrap(); fs::write(dir.join(format!("{name}.md")), contents.as_bytes()).unwrap(); @@ -355,6 +360,45 @@ fn test_quiet_cache() { .stdout(is_empty()); } +#[test] +fn test_clear_only_pages_directory() { + let testenv = TestEnv::new().install_default_cache(); + testenv + .command() + .args(["--clear-cache"]) + .assert() + .success() + .stderr(contains(format!( + "Successfully cleared cache at `{}`.", + testenv.cache_dir().join(TLDR_PAGES_DIR).to_str().unwrap(), + ))); + + assert!(testenv.cache_dir().is_dir()); + assert!(!testenv.cache_dir().join(TLDR_PAGES_DIR).exists()); +} + +#[test] +fn test_always_delete_old_pages_directory() { + let testenv = TestEnv::new().install_default_cache(); + fs::rename( + testenv.cache_dir().join(TLDR_PAGES_DIR), + testenv.cache_dir().join(TLDR_OLD_PAGES_DIR), + ) + .unwrap(); + + testenv + .command() + .arg("--list") + .assert() + .failure() + .stderr(contains("Cleared pages from old cache location.")) + .stderr(contains("Page cache not found.")); + + assert!(testenv.cache_dir().is_dir()); + assert!(!testenv.cache_dir().join(TLDR_PAGES_DIR).exists()); + assert!(!testenv.cache_dir().join(TLDR_OLD_PAGES_DIR).exists()); +} + #[test] fn test_warn_invalid_tls_backend() { let testenv = TestEnv::new() @@ -429,38 +473,59 @@ fn test_create_cache_directory_path() { .assert() .success() .stderr(contains(format!( - "Successfully created cache directory path `{}`.", - internal_cache_dir.to_str().unwrap() + "Successfully created cache directory `{}`.", + internal_cache_dir.join(TLDR_PAGES_DIR).to_str().unwrap() ))) .stderr(contains("Successfully updated cache.")); assert!(internal_cache_dir.is_dir()); } -#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_cache_location_not_a_directory() { - let testenv = TestEnv::new().remove_initial_config(); + let testenv = TestEnv::new(); let cache_dir = &testenv.cache_dir(); - let internal_file = cache_dir.join("internal"); - File::create(&internal_file).unwrap(); - - testenv.append_to_config(format!( - "directories.cache_dir = '{}'\n", - internal_file.to_str().unwrap() - )); + File::create(cache_dir.join(TLDR_PAGES_DIR)).unwrap(); testenv .command() - .arg("--update") + .arg("--list") .assert() .failure() .stderr(contains(format!( - "Cache directory path `{}` is not a directory", - internal_file.display(), + "Cache directory `{}` exists, but is not a directory.", + cache_dir.join(TLDR_PAGES_DIR).display(), ))); } +#[cfg(unix)] +#[test] +fn test_cache_location_permission_denied() { + use std::os::unix::fs::PermissionsExt; + + let testenv = TestEnv::new().install_default_cache(); + + testenv + .command() + .arg("--list") + .assert() + .success() + .stderr(contains("Permission denied").not()); + + // Make cache directory unreadable + let cache_dir = testenv.cache_dir(); + let mut permissions = cache_dir.metadata().unwrap().permissions(); + permissions.set_mode(0); + fs::set_permissions(cache_dir, permissions).unwrap(); + + testenv + .command() + .arg("--list") + .assert() + .failure() + .stderr(contains("Permission denied")); +} + #[test] fn test_cache_location_source() { let testenv = TestEnv::new().remove_initial_config(); @@ -624,7 +689,7 @@ fn test_os_specific_page() { fn test_markdown_rendering() { let testenv = TestEnv::new().install_default_cache(); - let expected = include_str!("cache/pages/common/which.md"); + let expected = include_str!("cache/pages.en/common/which.md"); testenv .command() .args(["--raw", "which"]) @@ -1008,7 +1073,7 @@ fn test_custom_page_overwrites() { // Add .page.md file to custom_pages_dir testenv.add_page_entry( "inkscape-v2", - include_str!("cache/pages/common/inkscape-v2.md"), + include_str!("cache/pages.en/common/inkscape-v2.md"), ); // Load expected output @@ -1051,7 +1116,7 @@ fn test_custom_patch_does_not_append_to_custom() { // In addition to the page in the cache, add the same page as a custom page. testenv.add_page_entry( "inkscape-v2", - include_str!("cache/pages/common/inkscape-v2.md"), + include_str!("cache/pages.en/common/inkscape-v2.md"), ); // Load expected output @@ -1114,7 +1179,7 @@ fn test_raw_render_file() { let path = testenv .cache_dir() .join(TLDR_PAGES_DIR) - .join("pages/common/inkscape-v1.md"); + .join("pages.en/common/inkscape-v1.md"); let mut args = vec!["--color", "never", "-f", &path.to_str().unwrap()]; // Default render @@ -1134,7 +1199,7 @@ fn test_raw_render_file() { .args(&args) .assert() .success() - .stdout(diff(include_str!("cache/pages/common/inkscape-v1.md"))); + .stdout(diff(include_str!("cache/pages.en/common/inkscape-v1.md"))); } fn touch_custom_page(testenv: &TestEnv) { From 630b7f442376232012b01f4fde5fcae6fc236aa2 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 5 Aug 2025 23:46:49 +0200 Subject: [PATCH 157/196] Allow references in `Config` (#429) For #251, I want to use the `Language<'_>` type inside `Config`. The languages will either refer to values read from the config file, or to static strings from `get_languages_from_env`, so just using `Language<'static>` is not an option. Instead, some input for the `Config` needs to be persisted in the main function for the duration of the program so that the config can reference it. At first I was hoping that this input would be the `contents` string from `RawConfig::load`, but as it turns out you cannot (in general) deserialize strings from toml without having to alter them, for example when they contain escapes like `\n`. Thus, the toml parser seemingly doesn't even try and just throws an error when deserializing into a borrowed string (even if it could in theory just return the correct substring from the input). Given that `RawConfig` should stay static then, the raw config itself is the next best thing to keep alive and have the config reference into. While this change might seem a bit drastic for little benefit, I am actually pretty happy with it because I want to unify the configuration anyways at some point so that the CLI arguments, environment variables, and the config file are merged at the beginning of the program and then only a single config is used for the everything (no more `enable_styles` everywhere!). At this time, the `Config` would have references into `Cli` anyways, and having the `ConfigLoader` as an entity for this merging also seems natural. --- src/config.rs | 146 ++++++++++++++++++++++++++------------------------ src/main.rs | 13 +++-- 2 files changed, 83 insertions(+), 76 deletions(-) diff --git a/src/config.rs b/src/config.rs index be41dd2..2d4d3a8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ use std::{ env, fmt, fs::{self, File}, - io::{ErrorKind, Read, Write}, + io::{ErrorKind, Write}, path::{Path, PathBuf}, time::Duration, }; @@ -138,8 +138,8 @@ struct RawStyleConfig { pub example_variable: RawStyle, } -impl From for StyleConfig { - fn from(raw_style_config: RawStyleConfig) -> Self { +impl From<&RawStyleConfig> for StyleConfig { + fn from(raw_style_config: &RawStyleConfig) -> Self { Self { command_name: raw_style_config.command_name.into(), description: raw_style_config.description.into(), @@ -158,8 +158,8 @@ struct RawDisplayConfig { pub use_pager: bool, } -impl From for DisplayConfig { - fn from(raw_display_config: RawDisplayConfig) -> Self { +impl From<&RawDisplayConfig> for DisplayConfig { + fn from(raw_display_config: &RawDisplayConfig) -> Self { Self { compact: raw_display_config.compact, use_pager: raw_display_config.use_pager, @@ -202,10 +202,10 @@ impl Default for RawUpdatesConfig { } } -impl TryFrom for UpdatesConfig { +impl<'a> TryFrom<&'a RawUpdatesConfig> for UpdatesConfig<'a> { type Error = anyhow::Error; - fn try_from(raw_updates_config: RawUpdatesConfig) -> Result { + fn try_from(raw_updates_config: &'a RawUpdatesConfig) -> Result { let tls_backend = match raw_updates_config.tls_backend { #[cfg(feature = "native-tls")] RawTlsBackend::NativeTls => TlsBackend::NativeTls, @@ -227,7 +227,7 @@ impl TryFrom for UpdatesConfig { auto_update_interval: Duration::from_secs( raw_updates_config.auto_update_interval_hours * 3600, ), - archive_source: raw_updates_config.archive_source, + archive_source: &raw_updates_config.archive_source, tls_backend, }) } @@ -250,20 +250,6 @@ struct RawConfig { directories: RawDirectoriesConfig, } -impl RawConfig { - fn new() -> Self { - Self::default() - } - - fn load(mut config: impl Read) -> Result { - let mut content = String::new(); - config - .read_to_string(&mut content) - .context("Failed to read from config file")?; - toml::from_str(&content).context("Failed to parse TOML config file") - } -} - impl Default for RawConfig { fn default() -> Self { let mut raw_config = RawConfig { @@ -300,10 +286,10 @@ pub struct DisplayConfig { } #[derive(Clone, Debug, PartialEq, Eq)] -pub struct UpdatesConfig { +pub struct UpdatesConfig<'a> { pub auto_update: bool, pub auto_update_interval: Duration, - pub archive_source: String, + pub archive_source: &'a str, pub tls_backend: TlsBackend, } @@ -369,23 +355,23 @@ pub enum TlsBackend { } #[derive(Clone, Debug, PartialEq, Eq)] -pub struct Config { +pub struct Config<'a> { pub style: StyleConfig, pub display: DisplayConfig, - pub updates: UpdatesConfig, + pub updates: UpdatesConfig<'a>, pub directories: DirectoriesConfig, pub file_path: PathWithSource, } -impl Config { +impl<'a> Config<'a> { /// Convert a `RawConfig` to a high-level `Config`. /// /// For this, some values need to be converted to other types and some /// defaults need to be set (sometimes based on env variables). - fn from_raw(raw_config: RawConfig, config_file_path: PathWithSource) -> Result { - let style = raw_config.style.into(); - let display = raw_config.display.into(); - let updates = raw_config.updates.try_into()?; + fn from_raw(raw_config: &'a RawConfig, config_file_path: PathWithSource) -> Result { + let style = (&raw_config.style).into(); + let display = (&raw_config.display).into(); + let updates = (&raw_config.updates).try_into()?; let relative_path_root = config_file_path .path() .parent() @@ -404,7 +390,7 @@ impl Config { path: PathBuf::from(env_var), source: PathSource::EnvVar, } - } else if let Some(config_value) = raw_config.directories.cache_dir { + } else if let Some(config_value) = &raw_config.directories.cache_dir { // If the user explicitly configured a cache directory, use that. PathWithSource { // Resolve possible relative path. It would be nicer to clean up the path, but Rust stdlib @@ -425,6 +411,7 @@ impl Config { let custom_pages_dir = raw_config .directories .custom_pages_dir + .as_ref() .map(|path| PathWithSource { // Resolve possible relative path. path: relative_path_root.join(path), @@ -454,47 +441,64 @@ impl Config { file_path: config_file_path, }) } +} - /// Load and read the config file from the given path into - /// a [Config] and return it. - /// - /// path: The path to the config file. - pub fn load(path: &Path) -> Result { - let raw_config = RawConfig::load(File::open(path)?)?; +/// The [`ConfigLoader`] is used to load a [`Config`] from a file. +/// +/// Since the rich [`Config`] keeps references to [`RawConfig`], the raw config needs to be kept alive outside of the +/// [`Config`]. The [`ConfigLoader`] thus offers the following flow: +/// 1. Read a raw config using [`ConfigLoader::read`] or [`ConfigLoader::read_default_path`]. +/// 2. Validate the contents to a [`Config`] that borrows the [`ConfigLoader`]. +pub struct ConfigLoader { + raw: RawConfig, + path: PathWithSource, +} - let config = Self::from_raw( - raw_config, - PathWithSource { - path: path.into(), - source: PathSource::Cli, - }, - ) - .context("Could not process raw config")?; - - Ok(config) +impl ConfigLoader { + fn read_internal(path: PathWithSource, allow_not_found: bool) -> Result { + match fs::read_to_string(&path.path) { + Ok(content) => Ok(Self { + raw: toml::from_str(&content).with_context(|| { + format!( + "Could not parse config file contents as toml from {}.", + path.path.display() + ) + })?, + path, + }), + Err(e) if allow_not_found && e.kind() == ErrorKind::NotFound => Ok(Self { + raw: RawConfig::default(), + path, + }), + Err(e) => Err(e).context(format!( + "Could not read config file contents from {}.", + path.path().display() + )), + } } - /// Load and read the config file from the default path into - /// a [Config] and return it. - pub fn load_default_path() -> Result { - // Determine path - let config_file_path = - get_default_config_path().context("Could not determine config path")?; + /// Create a loader that uses the config at `path`. + pub fn read(path: PathBuf) -> Result { + Self::read_internal( + PathWithSource { + path, + source: PathSource::Cli, + }, + false, + ) + } - let raw_config = match File::open(config_file_path.path()) { - Ok(file) => RawConfig::load(file)?, - Err(e) if e.kind() == ErrorKind::NotFound => RawConfig::default(), - Err(e) => { - return Err(e).context(format!( - "Failed to open config file at {}", - config_file_path.path().display() - )); - } - }; - let config = - Self::from_raw(raw_config, config_file_path).context("Could not process raw config")?; + /// Create a loader that uses the default config file location. If no file is present at the default location, the + /// default configuration is used. + pub fn read_default_path() -> Result { + let path = get_default_config_path().context("Could not determine default config path.")?; + Self::read_internal(path, true) + } - Ok(config) + /// Parse the read [`RawConfig`] into a [`Config`]. + pub fn load(&self) -> Result> { + Config::from_raw(&self.raw, self.path.clone()) + .context("Could not process raw config into rich config") } } @@ -563,7 +567,7 @@ pub fn make_default_config(path: Option<&Path>) -> Result { // Create default config let serialized_config = - toml::to_string(&RawConfig::new()).context("Failed to serialize default config")?; + toml::to_string(&RawConfig::default()).context("Failed to serialize default config")?; // Write default config let mut config_file = @@ -577,7 +581,7 @@ pub fn make_default_config(path: Option<&Path>) -> Result { #[test] fn test_serialize_deserialize() { - let raw_config = RawConfig::new(); + let raw_config = RawConfig::default(); let serialized = toml::to_string(&raw_config).unwrap(); let deserialized: RawConfig = toml::from_str(&serialized).unwrap(); assert_eq!(raw_config, deserialized); @@ -585,12 +589,12 @@ fn test_serialize_deserialize() { #[test] fn test_relative_path_resolution() { - let mut raw_config = RawConfig::new(); + let mut raw_config = RawConfig::default(); raw_config.directories.cache_dir = Some("../cache".into()); raw_config.directories.custom_pages_dir = Some("../custom_pages".into()); let config = Config::from_raw( - raw_config, + &raw_config, PathWithSource { path: PathBuf::from("/path/to/config/config.toml"), source: PathSource::OsConvention, diff --git a/src/main.rs b/src/main.rs index 3797f0b..6920c63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,7 @@ use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; use cache::{CacheConfig, Language, TLDR_OLD_PAGES_DIR}; use clap::Parser; -use config::{StyleConfig, TlsBackend}; +use config::{ConfigLoader, StyleConfig, TlsBackend}; use log::debug; mod cache; @@ -233,12 +233,15 @@ fn main() -> ExitCode { fn try_main(args: Cli, enable_styles: bool) -> Result { // Look up config file, if none is found fall back to default config. debug!("Loading config"); - let mut config = match &args.config_path { + let config_loader = match &args.config_path { Some(path) if !args.seed_config => { - Config::load(path).context("Could not load config from given path")? + ConfigLoader::read(path.clone()).context("Could not read config from given path")? + } + _ => { + ConfigLoader::read_default_path().context("Could not read config from default path")? } - _ => Config::load_default_path().context("Could not load config from default path")?, }; + let mut config = config_loader.load()?; // Override styles if needed if !enable_styles { @@ -327,7 +330,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { if was_created || args.update || cache.age()? >= config.updates.auto_update_interval { update_cache( &mut cache, - &config.updates.archive_source, + config.updates.archive_source, config.updates.tls_backend, args.quiet, )?; From 4377366c97770fe12efcb2370fd8a56f3e872317 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:52:36 +0200 Subject: [PATCH 158/196] Bump actions/checkout from 4 to 5 (#434) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/gh-pages.yml | 2 +- .github/workflows/release.yml | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a99b2f..f20709e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: exe_suffix: .exe runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} @@ -50,7 +50,7 @@ jobs: name: run clippy lints runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -62,7 +62,7 @@ jobs: name: run rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -74,7 +74,7 @@ jobs: name: build docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 with: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 26fff6e..8746d42 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -8,7 +8,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5ccdf9..9371ef5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: create-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Create release for tag if: startsWith(github.ref, 'refs/tags/') run: | @@ -24,7 +24,7 @@ jobs: matrix: target: ["bash", "fish", "zsh"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | @@ -40,7 +40,7 @@ jobs: matrix: target: ["MIT", "APACHE"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | @@ -66,7 +66,7 @@ jobs: - arch: "arm" libc: "musleabihf" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - name: Build in Docker @@ -86,7 +86,7 @@ jobs: - arch: "x86_64" - arch: "aarch64" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -102,7 +102,7 @@ jobs: build-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -134,7 +134,7 @@ jobs: - macos-aarch64 - windows-x86_64-msvc steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/download-artifact@v4 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') From 5cfb817e999f16681769041379bbdc0bd8ea6251 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 17:17:51 +0200 Subject: [PATCH 159/196] Bump actions/download-artifact from 4 to 5 (#433) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Niklas Mohrin --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9371ef5..b144b0f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -135,7 +135,7 @@ jobs: - windows-x86_64-msvc steps: - uses: actions/checkout@v5 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v5 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | From 94f9030d36f5c41feae1f1d5ee8cfd1a5243eddf Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sat, 2 Aug 2025 23:29:18 +0200 Subject: [PATCH 160/196] Move Language related functionality into config module --- src/cache.rs | 8 ++-- src/config.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 114 +------------------------------------------------- 3 files changed, 119 insertions(+), 117 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index c18f03f..315f6f0 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -14,14 +14,14 @@ use ureq::{ }; use zip::ZipArchive; -use crate::{config::TlsBackend, types::PlatformType}; +use crate::{ + config::{Language, TlsBackend}, + types::PlatformType, +}; pub static TLDR_PAGES_DIR: &str = "tldr-pages"; pub static TLDR_OLD_PAGES_DIR: &str = "tldr-master"; -#[derive(Debug, PartialEq, Eq, Hash)] -pub struct Language<'a>(pub &'a str); - #[derive(Clone)] pub struct CacheConfig<'a> { pub pages_directory: &'a Path, diff --git a/src/config.rs b/src/config.rs index 2d4d3a8..f9ea88e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,6 +3,7 @@ use std::{ fs::{self, File}, io::{ErrorKind, Write}, path::{Path, PathBuf}, + sync::LazyLock, time::Duration, }; @@ -12,7 +13,7 @@ use serde::Serialize as _; use serde_derive::{Deserialize, Serialize}; use yansi::{Color, Style}; -use crate::types::PathSource; +use crate::{extensions::Dedup as _, types::PathSource}; pub const CONFIG_FILE_NAME: &str = "config.toml"; pub const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days @@ -317,6 +318,49 @@ pub struct DirectoriesConfig { pub custom_pages_dir: Option, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Language<'a>(pub &'a str); + +fn get_languages<'a>( + env_lang: Option<&'a str>, + env_language: Option<&'a str>, +) -> Vec> { + // Language list according to + // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#language + + let Some(env_lang) = env_lang else { + return vec![Language("en")]; + }; + + // Create an iterator that contains $LANGUAGE (':' separated list) followed by $LANG (single language) + let locales = env_language.unwrap_or("").split(':').chain([env_lang]); + + let mut lang_list = Vec::new(); + for locale in locales { + // Language plus country code (e.g. `en_US`) + if locale.len() >= 5 && locale.chars().nth(2) == Some('_') { + lang_list.push(Language(&locale[..5])); + } + // Language code only (e.g. `en`) + if locale.len() >= 2 && locale != "POSIX" { + lang_list.push(Language(&locale[..2])); + } + } + + lang_list.push(Language("en")); + lang_list.clear_duplicates(); + lang_list +} + +pub fn get_languages_from_env<'a>() -> Vec> { + static LANG: LazyLock> = LazyLock::new(|| std::env::var("LANG").ok()); + static LANGUAGE: LazyLock> = LazyLock::new(|| std::env::var("LANGUAGE").ok()); + get_languages( + LANG.as_ref().map(String::as_str), + LANGUAGE.as_ref().map(String::as_str), + ) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] pub enum RawTlsBackend { @@ -611,3 +655,71 @@ fn test_relative_path_resolution() { Path::new("/path/to/config/../custom_pages") ); } + +#[cfg(test)] +mod test { + use super::*; + + mod language { + use super::*; + + #[test] + fn missing_lang_env() { + let lang_list = get_languages(None, Some("de:fr")); + assert_eq!(lang_list, [Language("en")]); + let lang_list = get_languages(None, None); + assert_eq!(lang_list, [Language("en")]); + } + + #[test] + fn missing_language_env() { + let lang_list = get_languages(Some("de"), None); + assert_eq!(lang_list, [Language("de"), Language("en")]); + } + + #[test] + fn preference_order() { + let lang_list = get_languages(Some("de"), Some("fr:cn")); + assert_eq!( + lang_list, + [ + Language("fr"), + Language("cn"), + Language("de"), + Language("en") + ] + ); + } + + #[test] + fn country_code_expansion() { + let lang_list = get_languages(Some("pt_BR"), None); + assert_eq!( + lang_list, + [Language("pt_BR"), Language("pt"), Language("en")] + ); + } + + #[test] + fn ignore_posix_and_c() { + let lang_list = get_languages(Some("POSIX"), None); + assert_eq!(lang_list, [Language("en")]); + let lang_list = get_languages(Some("C"), None); + assert_eq!(lang_list, [Language("en")]); + } + + #[test] + fn no_duplicates() { + let lang_list = get_languages(Some("de"), Some("fr:de:cn:de")); + assert_eq!( + lang_list, + [ + Language("fr"), + Language("de"), + Language("cn"), + Language("en") + ] + ); + } + } +} diff --git a/src/main.rs b/src/main.rs index 6920c63..5ae0a59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,14 +31,13 @@ use std::{ io::{self, IsTerminal}, path::Path, process::{Command, ExitCode}, - sync::LazyLock, }; use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; -use cache::{CacheConfig, Language, TLDR_OLD_PAGES_DIR}; +use cache::{CacheConfig, TLDR_OLD_PAGES_DIR}; use clap::Parser; -use config::{ConfigLoader, StyleConfig, TlsBackend}; +use config::{get_languages_from_env, ConfigLoader, Language, StyleConfig, TlsBackend}; use log::debug; mod cache; @@ -55,7 +54,6 @@ use crate::{ cache::{Cache, PageLookupResult, TLDR_PAGES_DIR}, cli::Cli, config::{get_config_dir, make_default_config, Config, PathWithSource}, - extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, utils::{print_error, print_warning}, @@ -141,46 +139,6 @@ fn init_log() { #[cfg(not(feature = "logging"))] fn init_log() {} -fn get_languages<'a>( - env_lang: Option<&'a str>, - env_language: Option<&'a str>, -) -> Vec> { - // Language list according to - // https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#language - - let Some(env_lang) = env_lang else { - return vec![Language("en")]; - }; - - // Create an iterator that contains $LANGUAGE (':' separated list) followed by $LANG (single language) - let locales = env_language.unwrap_or("").split(':').chain([env_lang]); - - let mut lang_list = Vec::new(); - for locale in locales { - // Language plus country code (e.g. `en_US`) - if locale.len() >= 5 && locale.chars().nth(2) == Some('_') { - lang_list.push(Language(&locale[..5])); - } - // Language code only (e.g. `en`) - if locale.len() >= 2 && locale != "POSIX" { - lang_list.push(Language(&locale[..2])); - } - } - - lang_list.push(Language("en")); - lang_list.clear_duplicates(); - lang_list -} - -fn get_languages_from_env<'a>() -> Vec> { - static LANG: LazyLock> = LazyLock::new(|| std::env::var("LANG").ok()); - static LANGUAGE: LazyLock> = LazyLock::new(|| std::env::var("LANGUAGE").ok()); - get_languages( - LANG.as_ref().map(String::as_str), - LANGUAGE.as_ref().map(String::as_str), - ) -} - fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> Result<()> { create_dir_all(custom_pages_dir).context("Failed to create custom pages directory")?; @@ -439,71 +397,3 @@ fn compute_platforms(platforms: Option<&Vec>) -> Vec None => vec![PlatformType::current(), PlatformType::Common], } } - -#[cfg(test)] -mod test { - use super::*; - - mod language { - use super::*; - - #[test] - fn missing_lang_env() { - let lang_list = get_languages(None, Some("de:fr")); - assert_eq!(lang_list, [Language("en")]); - let lang_list = get_languages(None, None); - assert_eq!(lang_list, [Language("en")]); - } - - #[test] - fn missing_language_env() { - let lang_list = get_languages(Some("de"), None); - assert_eq!(lang_list, [Language("de"), Language("en")]); - } - - #[test] - fn preference_order() { - let lang_list = get_languages(Some("de"), Some("fr:cn")); - assert_eq!( - lang_list, - [ - Language("fr"), - Language("cn"), - Language("de"), - Language("en") - ] - ); - } - - #[test] - fn country_code_expansion() { - let lang_list = get_languages(Some("pt_BR"), None); - assert_eq!( - lang_list, - [Language("pt_BR"), Language("pt"), Language("en")] - ); - } - - #[test] - fn ignore_posix_and_c() { - let lang_list = get_languages(Some("POSIX"), None); - assert_eq!(lang_list, [Language("en")]); - let lang_list = get_languages(Some("C"), None); - assert_eq!(lang_list, [Language("en")]); - } - - #[test] - fn no_duplicates() { - let lang_list = get_languages(Some("de"), Some("fr:de:cn:de")); - assert_eq!( - lang_list, - [ - Language("fr"), - Language("de"), - Language("cn"), - Language("en") - ] - ); - } - } -} From 7e014093cf1151fe4a5d808081c8728fe3faa39e Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sat, 2 Aug 2025 23:30:30 +0200 Subject: [PATCH 161/196] Move existing tests from config module into test submodule --- src/config.rs | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/config.rs b/src/config.rs index f9ea88e..7ae6299 100644 --- a/src/config.rs +++ b/src/config.rs @@ -623,43 +623,43 @@ pub fn make_default_config(path: Option<&Path>) -> Result { Ok(config_file_path) } -#[test] -fn test_serialize_deserialize() { - let raw_config = RawConfig::default(); - let serialized = toml::to_string(&raw_config).unwrap(); - let deserialized: RawConfig = toml::from_str(&serialized).unwrap(); - assert_eq!(raw_config, deserialized); -} - -#[test] -fn test_relative_path_resolution() { - let mut raw_config = RawConfig::default(); - raw_config.directories.cache_dir = Some("../cache".into()); - raw_config.directories.custom_pages_dir = Some("../custom_pages".into()); - - let config = Config::from_raw( - &raw_config, - PathWithSource { - path: PathBuf::from("/path/to/config/config.toml"), - source: PathSource::OsConvention, - }, - ) - .unwrap(); - - assert_eq!( - config.directories.cache_dir.path(), - Path::new("/path/to/config/../cache") - ); - assert_eq!( - config.directories.custom_pages_dir.unwrap().path(), - Path::new("/path/to/config/../custom_pages") - ); -} - #[cfg(test)] mod test { use super::*; + #[test] + fn serialize_deserialize() { + let raw_config = RawConfig::default(); + let serialized = toml::to_string(&raw_config).unwrap(); + let deserialized: RawConfig = toml::from_str(&serialized).unwrap(); + assert_eq!(raw_config, deserialized); + } + + #[test] + fn relative_path_resolution() { + let mut raw_config = RawConfig::default(); + raw_config.directories.cache_dir = Some("../cache".into()); + raw_config.directories.custom_pages_dir = Some("../custom_pages".into()); + + let config = Config::from_raw( + &raw_config, + PathWithSource { + path: PathBuf::from("/path/to/config/config.toml"), + source: PathSource::OsConvention, + }, + ) + .unwrap(); + + assert_eq!( + config.directories.cache_dir.path(), + Path::new("/path/to/config/../cache") + ); + assert_eq!( + config.directories.custom_pages_dir.unwrap().path(), + Path::new("/path/to/config/../custom_pages") + ); + } + mod language { use super::*; From 3fa96a5bb2c73810909635764084edd46432bb70 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sat, 6 Sep 2025 15:57:17 +0200 Subject: [PATCH 162/196] Add test config::test::language::with_encoding --- src/config.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/config.rs b/src/config.rs index 7ae6299..b4d6910 100644 --- a/src/config.rs +++ b/src/config.rs @@ -700,6 +700,15 @@ mod test { ); } + #[test] + fn with_encoding() { + let lang_list = get_languages(Some("de_DE.UTF-8"), None); + assert_eq!( + lang_list, + [Language("de_DE"), Language("de"), Language("en")] + ); + } + #[test] fn ignore_posix_and_c() { let lang_list = get_languages(Some("POSIX"), None); From a74b7120bd1f6e7a380223ee589649f27195bee1 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 3 Aug 2025 00:45:12 +0200 Subject: [PATCH 163/196] Add search.languages setting --- docs/src/SUMMARY.md | 1 + docs/src/config.md | 2 +- docs/src/config_search.md | 14 ++++++ src/config.rs | 24 ++++++++++ src/main.rs | 12 ++--- tests/lib.rs | 98 +++++++++++++++++++++++++++++++++++++-- 6 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 docs/src/config_search.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 2d5c716..4649382 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -8,6 +8,7 @@ - [Configuration](./config.md) - [Section: \[display\]](./config_display.md) - [Section: \[style\]](./config_style.md) + - [Section: \[search\]](./config_search.md) - [Section: \[updates\]](./config_updates.md) - [Section: \[directories\]](./config_directories.md) - [Tips and Tricks](./tips_and_tricks.md) diff --git a/docs/src/config.md b/docs/src/config.md index ece2706..6eeede4 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -22,7 +22,7 @@ On Linux, this will usually be `~/.config/tealdeer/config.toml`. Here's an example configuration file. Note that this example does not contain all possible config options. For details on the things that can be configured, please refer to the subsections of this documentation page -([display](config_display.html), [style](config_style.html), +([display](config_display.html), [style](config_style.html), [search](config_search.html), [updates](config_updates.html) or [directories](config_directories.html)). ```toml diff --git a/docs/src/config_search.md b/docs/src/config_search.md new file mode 100644 index 0000000..2d59d65 --- /dev/null +++ b/docs/src/config_search.md @@ -0,0 +1,14 @@ +# Section: \[search\] + +This config section is used to configure the page search in the cache. +The settings apply to `tldr ` and `tldr --list`. + +## `languages` + +The list of languages that should be considered when searching. +If unspecified, the list of languages will be inferred from the `LANG` and `LANGUAGE` environment variables. +Either way, the language used can be overwritten using the `--language` command line flag. + + [search] + # Show pages in German if available, otherwise show in English + languages = ["de", "en"] diff --git a/src/config.rs b/src/config.rs index b4d6910..69de9b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -242,6 +242,11 @@ struct RawDirectoriesConfig { pub custom_pages_dir: Option, } +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] +struct RawSearchConfig { + pub languages: Option>, +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(default)] struct RawConfig { @@ -249,6 +254,7 @@ struct RawConfig { display: RawDisplayConfig, updates: RawUpdatesConfig, directories: RawDirectoriesConfig, + search: RawSearchConfig, } impl Default for RawConfig { @@ -258,6 +264,7 @@ impl Default for RawConfig { display: RawDisplayConfig::default(), updates: RawUpdatesConfig::default(), directories: RawDirectoriesConfig::default(), + search: RawSearchConfig::default(), }; // Set default config @@ -318,6 +325,11 @@ pub struct DirectoriesConfig { pub custom_pages_dir: Option, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SearchConfig<'a> { + pub languages: Vec>, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Language<'a>(pub &'a str); @@ -404,6 +416,7 @@ pub struct Config<'a> { pub display: DisplayConfig, pub updates: UpdatesConfig<'a>, pub directories: DirectoriesConfig, + pub search: SearchConfig<'a>, pub file_path: PathWithSource, } @@ -416,6 +429,16 @@ impl<'a> Config<'a> { let style = (&raw_config.style).into(); let display = (&raw_config.display).into(); let updates = (&raw_config.updates).try_into()?; + let search = SearchConfig { + languages: raw_config + .search + .languages + .as_ref() + .map_or_else(get_languages_from_env, |langs| { + langs.iter().map(|lang| Language(lang)).collect() + }), + }; + let relative_path_root = config_file_path .path() .parent() @@ -482,6 +505,7 @@ impl<'a> Config<'a> { display, updates, directories, + search, file_path: config_file_path, }) } diff --git a/src/main.rs b/src/main.rs index 5ae0a59..5bd0fa0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; use cache::{CacheConfig, TLDR_OLD_PAGES_DIR}; use clap::Parser; -use config::{get_languages_from_env, ConfigLoader, Language, StyleConfig, TlsBackend}; +use config::{ConfigLoader, Language, StyleConfig, TlsBackend}; use log::debug; mod cache; @@ -250,10 +250,10 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { } let platforms = compute_platforms(args.platforms.as_ref()); - let languages = args - .language - .as_deref() - .map_or_else(get_languages_from_env, |lang| vec![Language(lang)]); + let languages = match args.language.as_deref() { + Some(lang) => &[Language(lang)] as &[_], + None => &config.search.languages, + }; let cache_config = CacheConfig { pages_directory: &config.directories.cache_dir.path().join(TLDR_PAGES_DIR), @@ -263,7 +263,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { .as_ref() .map(PathWithSource::path), platforms: &platforms, - languages: &languages, + languages, }; // TODO: remove in tealdeer 1.9 diff --git a/tests/lib.rs b/tests/lib.rs index 2a1665c..37f3b30 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -11,6 +11,7 @@ use std::{ use assert_cmd::prelude::*; use predicates::{ boolean::PredicateBooleanExt, + ord::eq, prelude::predicate::str::{contains, diff, is_empty, is_match}, }; use tempfile::{Builder as TempfileBuilder, TempDir}; @@ -41,10 +42,7 @@ impl TestEnv { create_dir_all(this.config_dir()).unwrap(); create_dir_all(this.custom_pages_dir()).unwrap(); - this.append_to_config(format!( - "directories.cache_dir = '{}'\n", - this.cache_dir().to_str().unwrap(), - )); + this.init_config(); this } @@ -70,6 +68,15 @@ impl TestEnv { .write_all(content.as_ref().as_bytes()) .expect("Failed to append to config file."); } + fn delete_config(&self) { + fs::remove_file(self.config_dir().join("config.toml")).unwrap(); + } + fn init_config(&self) { + self.append_to_config(format!( + "directories.cache_dir = '{}'\n", + self.cache_dir().to_str().unwrap(), + )); + } fn create_secondary_config(self) -> Self { self.append_to_secondary_config(format!( @@ -101,10 +108,20 @@ impl TestEnv { /// Add entry for that environment to an OS-specific subfolder. fn add_os_entry(&self, os: &str, name: &str, contents: &str) { + self.add_os_lang_entry(os, "en", name, contents); + } + + /// Add entry for that environment to a language-specific subfolder. + fn add_lang_entry(&self, lang: &str, name: &str, contents: &str) { + self.add_os_lang_entry("common", lang, name, contents); + } + + /// Add entry for that environment to an OS- and language specific subfolder. + fn add_os_lang_entry(&self, os: &str, lang: &str, name: &str, contents: &str) { let dir = self .cache_dir() .join(TLDR_PAGES_DIR) - .join("pages.en") + .join(format!("pages.{lang}")) .join(os); create_dir_all(&dir).unwrap(); @@ -152,6 +169,19 @@ impl TestEnv { } let run = build.run().expect("Failed to build tealdeer for testing"); let mut cmd = run.command(); + + // Avoid inheriting those from the test process. We can't just use .env_clear() because + // this breaks tests on Windows in GitHub Actions. + let relevant_env_variables = [ + "LANG", + "LANGUAGE", + "TEALDEER_CACHE_DIR", + "EDITOR", + "NO_COLOR", + ]; + for variable_name in relevant_env_variables { + cmd.env_remove(variable_name); + } cmd.env("TEALDEER_CONFIG_DIR", self.config_dir().to_str().unwrap()); cmd } @@ -908,6 +938,64 @@ fn test_common_platform_is_used_as_fallback() { .success(); } +#[test] +fn test_search_language_precedence() { + let testenv = TestEnv::new(); + for lang in ["en", "de", "it", "fr", "pl", "nl"] { + testenv.add_lang_entry(lang, lang, ""); + } + + let run = |cases: &[(Vec<(&str, &str)>, Vec<&str>, &str)]| { + for (extra_env, extra_args, expected) in cases { + let mut cmd = testenv.command(); + for (key, value) in extra_env { + cmd.env(key, value); + } + cmd.args(extra_args); + cmd.arg("--list"); + cmd.assert().success().stdout(eq(*expected)); + } + }; + + let env_cases = &[ + (vec![], vec![], "en\n"), + (vec![("LANGUAGE", "de:it")], vec![], "en\n"), + ( + vec![("LANG", "fr"), ("LANGUAGE", "de:it")], + vec![], + "de\nen\nfr\nit\n", + ), + ( + vec![("LANG", "fr"), ("LANGUAGE", "de:it")], + vec!["--language", "pl"], + "pl\n", + ), + ]; + run(env_cases); + + // Environment is only used when config setting is not set + testenv.append_to_config("search.languages = ['nl']\n"); + let config_cases = &[ + (vec![], vec![], "nl\n"), + (vec![("LANGUAGE", "de:it")], vec![], "nl\n"), + (vec![("LANG", "fr"), ("LANGUAGE", "de:it")], vec![], "nl\n"), + ( + vec![("LANG", "fr"), ("LANGUAGE", "de:it")], + vec!["--language", "pl"], + "pl\n", + ), + ]; + run(config_cases); + + // The above update setting does not change anything + testenv.append_to_config("updates.download_languages = ['cz']"); + run(config_cases); + testenv.delete_config(); + testenv.init_config(); + testenv.append_to_config("updates.download_languages = ['cz']"); + run(env_cases); +} + #[test] fn test_list_flag_rendering() { let testenv = TestEnv::new().write_custom_pages_config(); From c741146db592cd7aaccfd8ba3a7f108718a96111 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 3 Aug 2025 01:00:24 +0200 Subject: [PATCH 164/196] Add updates.download_languages setting --- docs/src/config_updates.md | 20 ++++++++++- src/cache.rs | 39 ++++++++++++-------- src/config.rs | 74 +++++++++++++++++++++----------------- src/main.rs | 21 ++++++++--- tests/lib.rs | 24 +++++++++++++ 5 files changed, 125 insertions(+), 53 deletions(-) diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index eaac735..cc5868e 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -1,5 +1,7 @@ # Section: \[updates\] +This config section contains settings related to updating the tealdeer cache. + ## Automatic updates Tealdeer can refresh the cache automatically when it is outdated. This @@ -24,7 +26,23 @@ is set to `false`. auto_update = true auto_update_interval_hours = 24 -### archive_source +## Download configuration + +### `download_languages` + +The list of languages which should be downloaded when updating. +If unspecified, the languages listed in the `search.languages` setting are used. +Thus, this setting is the most useful to instruct tealdeer to download pages in additional languages that are not searched by default. +Either way, the language used can be overwritten using the `--language` command line flag. + + [search] + languages = ["de", "en"] + + [updates] + # sometimes I like to read the Italian description + download_languages = ["de", "en", "it"] + +### `archive_source` URL for the location of the tldr pages archive. By default the pages are fetched from the latest `tldr-pages/tldr` GitHub release. diff --git a/src/cache.rs b/src/cache.rs index 315f6f0..23fd668 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -6,7 +6,7 @@ use std::{ }; use anyhow::{anyhow, bail, ensure, Context, Result}; -use log::debug; +use log::{debug, info}; use ureq::{ http::StatusCode, tls::{RootCerts, TlsConfig, TlsProvider}, @@ -27,7 +27,8 @@ pub struct CacheConfig<'a> { pub pages_directory: &'a Path, pub custom_pages_directory: Option<&'a Path>, pub platforms: &'a [PlatformType], - pub languages: &'a [Language<'a>], + pub search_languages: &'a [Language<'a>], + pub download_languages: &'a [Language<'a>], } /// The directory backing this cache is checked to be populated at construction. @@ -110,7 +111,7 @@ impl<'a> Cache<'a> { .filter(|path| path.is_file()); for &platform in self.config.platforms { - for language in self.config.languages { + for language in self.config.search_languages { let mut search_path = self.config.pages_directory.to_path_buf(); search_path.push(language.directory_name()); search_path.push(platform.directory_name()); @@ -159,7 +160,7 @@ impl<'a> Cache<'a> { }; let mut search_path = self.config.pages_directory.to_path_buf(); - for language in self.config.languages { + for language in self.config.search_languages { search_path.push(language.directory_name()); for platform in self.config.platforms { search_path.push(platform.directory_name()); @@ -206,15 +207,23 @@ impl<'a> Cache<'a> { }) } - pub fn update(&mut self, archive_url: &str, tls_backend: TlsBackend) -> Result<()> { + /// Download archives for the languages in `self.config().download_languages` and replace the + /// pages directory with the newly downloaded pages. As not all languages might have pages + /// available (for example, `en_US` instead of `en`), an iterator yielding all languages which + /// were successfully downloaded is returned. + pub fn update( + &mut self, + archive_url: &str, + tls_backend: TlsBackend, + ) -> Result>> { let client = Self::build_client(tls_backend); // Download everything before deleting anything - let archives = self + let mut archives = self .config - .languages + .download_languages .iter() - .map(|lang| { + .map(|&lang| { Ok(( lang, Self::download( @@ -236,16 +245,18 @@ impl<'a> Cache<'a> { fs::remove_dir_all(self.config.pages_directory)?; fs::create_dir(self.config.pages_directory)?; - for (lang, archive) in archives { - if let Some(mut archive) = archive { - debug!("Extracting archive for {lang:?}"); + for (lang, archive) in &mut archives { + if let Some(archive) = archive { + info!("Extracting archive for {lang:?}"); archive.extract(self.config.pages_directory.join(lang.directory_name()))?; } else { - debug!("No archive found for {lang:?}"); + info!("No archive found for {lang:?}"); } } - Ok(()) + Ok(archives + .into_iter() + .filter_map(|(lang, archive)| archive.is_some().then_some(lang))) } pub fn config(&self) -> &CacheConfig<'a> { @@ -347,7 +358,7 @@ impl Cache<'_> { /// Download the archive from the specified URL. fn download(client: &Agent, archive_url: &str) -> Result>> { - debug!("Downloading archive from {archive_url}"); + info!("Downloading archive from {archive_url}"); let response = client.get(archive_url).call(); match response { Ok(response) if response.status().is_success() => { diff --git a/src/config.rs b/src/config.rs index 69de9b5..bac3f74 100644 --- a/src/config.rs +++ b/src/config.rs @@ -190,6 +190,8 @@ struct RawUpdatesConfig { pub archive_source: String, #[serde(default)] pub tls_backend: RawTlsBackend, + #[serde(default)] + pub download_languages: Option>, } impl Default for RawUpdatesConfig { @@ -199,41 +201,11 @@ impl Default for RawUpdatesConfig { auto_update_interval_hours: DEFAULT_UPDATE_INTERVAL_HOURS, archive_source: default_archive_source(), tls_backend: RawTlsBackend::default(), + download_languages: None, } } } -impl<'a> TryFrom<&'a RawUpdatesConfig> for UpdatesConfig<'a> { - type Error = anyhow::Error; - - fn try_from(raw_updates_config: &'a RawUpdatesConfig) -> Result { - let tls_backend = match raw_updates_config.tls_backend { - #[cfg(feature = "native-tls")] - RawTlsBackend::NativeTls => TlsBackend::NativeTls, - #[cfg(feature = "rustls-with-webpki-roots")] - RawTlsBackend::RustlsWithWebpkiRoots => TlsBackend::RustlsWithWebpkiRoots, - #[cfg(feature = "rustls-with-native-roots")] - RawTlsBackend::RustlsWithNativeRoots => TlsBackend::RustlsWithNativeRoots, - // when compiling without all TLS backend features, we want to handle config error. - #[allow(unreachable_patterns)] - _ => return Err(anyhow!( - "Unsupported TLS backend: {}. This tealdeer build has support for the following options: {}", - raw_updates_config.tls_backend, - SUPPORTED_TLS_BACKENDS.iter().map(std::string::ToString::to_string).collect::>().join(", ") - )) - }; - - Ok(Self { - auto_update: raw_updates_config.auto_update, - auto_update_interval: Duration::from_secs( - raw_updates_config.auto_update_interval_hours * 3600, - ), - archive_source: &raw_updates_config.archive_source, - tls_backend, - }) - } -} - #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawDirectoriesConfig { #[serde(default)] @@ -299,6 +271,7 @@ pub struct UpdatesConfig<'a> { pub auto_update_interval: Duration, pub archive_source: &'a str, pub tls_backend: TlsBackend, + pub download_languages: Vec>, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -330,7 +303,7 @@ pub struct SearchConfig<'a> { pub languages: Vec>, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Language<'a>(pub &'a str); fn get_languages<'a>( @@ -410,6 +383,28 @@ pub enum TlsBackend { RustlsWithNativeRoots, } +impl TryFrom for TlsBackend { + type Error = anyhow::Error; + + fn try_from(raw: RawTlsBackend) -> Result { + match raw { + #[cfg(feature = "native-tls")] + RawTlsBackend::NativeTls => Ok(TlsBackend::NativeTls), + #[cfg(feature = "rustls-with-webpki-roots")] + RawTlsBackend::RustlsWithWebpkiRoots => Ok(TlsBackend::RustlsWithWebpkiRoots), + #[cfg(feature = "rustls-with-native-roots")] + RawTlsBackend::RustlsWithNativeRoots => Ok(TlsBackend::RustlsWithNativeRoots), + // when compiling without all TLS backend features, we want to handle config error. + #[allow(unreachable_patterns)] + _ => Err(anyhow!( + "Unsupported TLS backend: {}. This tealdeer build has support for the following options: {}", + raw, + SUPPORTED_TLS_BACKENDS.iter().map(std::string::ToString::to_string).collect::>().join(", ") + )) + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct Config<'a> { pub style: StyleConfig, @@ -428,7 +423,7 @@ impl<'a> Config<'a> { fn from_raw(raw_config: &'a RawConfig, config_file_path: PathWithSource) -> Result { let style = (&raw_config.style).into(); let display = (&raw_config.display).into(); - let updates = (&raw_config.updates).try_into()?; + let search = SearchConfig { languages: raw_config .search @@ -439,6 +434,19 @@ impl<'a> Config<'a> { }), }; + let updates = UpdatesConfig { + auto_update: raw_config.updates.auto_update, + auto_update_interval: Duration::from_secs( + raw_config.updates.auto_update_interval_hours * 3600, + ), + archive_source: &raw_config.updates.archive_source, + tls_backend: raw_config.updates.tls_backend.try_into()?, + download_languages: raw_config.updates.download_languages.as_ref().map_or_else( + || search.languages.clone(), + |languages| languages.iter().map(|lang| Language(lang)).collect(), + ), + }; + let relative_path_root = config_file_path .path() .parent() diff --git a/src/main.rs b/src/main.rs index 5bd0fa0..2f730a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,11 +82,21 @@ fn update_cache( tls_backend: TlsBackend, quietly: bool, ) -> Result<()> { - cache + let downloaded_languages = cache .update(archive_source, tls_backend) .context("Could not update cache")?; if !quietly { eprintln!("Successfully updated cache."); + eprint!("Pages for the following languages were downloaded: "); + let language_strings: Vec<_> = downloaded_languages + .into_iter() + .map(|lang| lang.0) + .collect(); + if language_strings.is_empty() { + eprintln!("(none)"); + } else { + eprintln!("{}", language_strings.join(", ")); + } } Ok(()) } @@ -250,9 +260,9 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { } let platforms = compute_platforms(args.platforms.as_ref()); - let languages = match args.language.as_deref() { - Some(lang) => &[Language(lang)] as &[_], - None => &config.search.languages, + let (search_languages, download_languages): (&[_], &[_]) = match args.language.as_deref() { + Some(lang) => (&[Language(lang)], &[Language(lang)]), + None => (&config.search.languages, &config.updates.download_languages), }; let cache_config = CacheConfig { @@ -263,7 +273,8 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { .as_ref() .map(PathWithSource::path), platforms: &platforms, - languages, + search_languages, + download_languages, }; // TODO: remove in tealdeer 1.9 diff --git a/tests/lib.rs b/tests/lib.rs index 37f3b30..eceb427 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -996,6 +996,30 @@ fn test_search_language_precedence() { run(env_cases); } +#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] +#[test] +fn test_update_language_arg() { + let testenv = TestEnv::new(); + testenv + .command() + .env("LANG", "it") + .arg("--update") + .assert() + .success() + .stderr(contains("it")) + .stderr(contains("en")); + + testenv + .command() + .env("LANG", "en") + .args(["--language", "it"]) + .arg("--update") + .assert() + .success() + .stderr(contains("it")) + .stderr(contains("en").not()); +} + #[test] fn test_list_flag_rendering() { let testenv = TestEnv::new().write_custom_pages_config(); From abb7e8ac5525f4b65141b996ef00e89f5c42bab4 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Mon, 22 Sep 2025 16:06:36 +0200 Subject: [PATCH 165/196] Remove native-tls from default feature set (#436) --- .github/workflows/release.yml | 2 +- Cargo.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b144b0f..360dd94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,7 @@ jobs: toolchain: stable targets: "${{ matrix.arch }}-apple-darwin" - name: Build - run: cargo build --release --target ${{ matrix.arch }}-apple-darwin --no-default-features --features webpki-roots + run: cargo build --release --target ${{ matrix.arch }}-apple-darwin - uses: actions/upload-artifact@v4 with: name: "tealdeer-macos-${{ matrix.arch }}" diff --git a/Cargo.toml b/Cargo.toml index 6594b14..3447307 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,8 @@ tempfile = "3.1.0" filetime = "0.2.10" [features] -default = ["native-tls", "rustls-with-webpki-roots", "rustls-with-native-roots"] +# native-tls is not enabled by default, because it is difficult to build for musl +default = ["rustls-with-webpki-roots", "rustls-with-native-roots"] logging = ["env_logger"] # At least one of variants for `ureq` HTTP client must be selected. From 5b306756af6163eb735eee9e84569ef0be9a0ff1 Mon Sep 17 00:00:00 2001 From: hex1c <84087661+hex1c@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:23:25 +0530 Subject: [PATCH 166/196] Add `display.show_title` option to display command titles in output (#439) --- docs/src/config.md | 1 + docs/src/config_display.md | 10 ++++++ src/config.rs | 4 +++ src/formatter.rs | 14 ++++++-- src/output.rs | 2 ++ tests/lib.rs | 36 +++++++++++++++++++ .../inkscape-with-title-no-color.expected | 34 ++++++++++++++++++ tests/rendered/inkscape-with-title.expected | 34 ++++++++++++++++++ 8 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 tests/rendered/inkscape-with-title-no-color.expected create mode 100644 tests/rendered/inkscape-with-title.expected diff --git a/docs/src/config.md b/docs/src/config.md index 6eeede4..b0bf922 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -29,6 +29,7 @@ please refer to the subsections of this documentation page [display] compact = false use_pager = true +show_title = false [style.command_name] foreground = "red" diff --git a/docs/src/config_display.md b/docs/src/config_display.md index 36d5f23..56b5cd3 100644 --- a/docs/src/config_display.md +++ b/docs/src/config_display.md @@ -21,3 +21,13 @@ Set this to enforce more compact output, where empty lines are stripped out [display] compact = true + +## `show_title` + +Display the command name at the top of the page output (default `false`). + + [display] + show_title = true + +When enabled, the command name will be displayed at the top of the output, +styled with the `command_name` style configuration. \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index bac3f74..446b841 100644 --- a/src/config.rs +++ b/src/config.rs @@ -157,6 +157,8 @@ struct RawDisplayConfig { pub compact: bool, #[serde(default)] pub use_pager: bool, + #[serde(default)] + pub show_title: bool, } impl From<&RawDisplayConfig> for DisplayConfig { @@ -164,6 +166,7 @@ impl From<&RawDisplayConfig> for DisplayConfig { Self { compact: raw_display_config.compact, use_pager: raw_display_config.use_pager, + show_title: raw_display_config.show_title, } } } @@ -263,6 +266,7 @@ pub struct StyleConfig { pub struct DisplayConfig { pub compact: bool, pub use_pager: bool, + pub show_title: bool, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/formatter.rs b/src/formatter.rs index 369efce..d86de9b 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -12,6 +12,7 @@ pub enum PageSnippet<'a> { NormalCode(&'a str), Description(&'a str), Text(&'a str), + Title(&'a str), Linebreak, } @@ -20,7 +21,9 @@ impl PageSnippet<'_> { use PageSnippet::*; match self { - CommandName(s) | Variable(s) | NormalCode(s) | Description(s) | Text(s) => s.is_empty(), + CommandName(s) | Variable(s) | NormalCode(s) | Description(s) | Text(s) | Title(s) => { + s.is_empty() + } Linebreak => false, } } @@ -31,6 +34,7 @@ pub fn highlight_lines( lines: L, process_snippet: &mut F, keep_empty_lines: bool, + show_title: bool, ) -> Result<(), E> where L: Iterator, @@ -45,8 +49,12 @@ where } } LineType::Title(title) => { - debug!("Ignoring title"); - + if show_title { + process_snippet(PageSnippet::Linebreak)?; + process_snippet(PageSnippet::Title(&title))?; + } else { + debug!("Ignoring title"); + } // This is safe as long as the parsed title is only the command, // and the iterator yields values in order of appearance. command = title; diff --git a/src/output.rs b/src/output.rs index 046abe8..5f1aeae 100644 --- a/src/output.rs +++ b/src/output.rs @@ -69,6 +69,7 @@ pub fn print_page( LineIterator::new(reader), &mut process_snippet, !config.display.compact, + config.display.show_title, ) .context("Could not write to stdout")?; } @@ -92,6 +93,7 @@ fn print_snippet( NormalCode(s) => write!(writer, "{}", s.paint(style.example_code)), Description(s) => writeln!(writer, " {}", s.paint(style.description)), Text(s) => writeln!(writer, " {}", s.paint(style.example_text)), + Title(s) => writeln!(writer, " {}", s.paint(style.command_name)), Linebreak => writeln!(writer), } } diff --git a/tests/lib.rs b/tests/lib.rs index eceb427..ef5777d 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -807,6 +807,42 @@ fn test_correct_rendering_with_config() { .stdout(diff(expected)); } +/// An end-to-end integration test for rendering with show_title config option enabled. +#[test] +fn test_show_title_config() { + // Test that default behavior without show_title shows no title + let testenv = TestEnv::new().install_default_cache(); + let expected_no_title = include_str!("rendered/inkscape-default.expected"); + + testenv + .command() + .args(["--color", "always", "inkscape-v2"]) + .assert() + .success() + .stdout(diff(expected_no_title)); + + // Configure to enable show_title + testenv.append_to_config("display.show_title = true\n"); + + let expected_no_color = include_str!("rendered/inkscape-with-title-no-color.expected"); + + testenv + .command() + .args(["inkscape-v2"]) + .assert() + .success() + .stdout(diff(expected_no_color)); + + let expected = include_str!("rendered/inkscape-with-title.expected"); + + testenv + .command() + .args(["--color", "always", "inkscape-v2"]) + .assert() + .success() + .stdout(diff(expected)); +} + #[test] fn test_spaces_find_command() { let testenv = TestEnv::new().install_default_cache(); diff --git a/tests/rendered/inkscape-with-title-no-color.expected b/tests/rendered/inkscape-with-title-no-color.expected new file mode 100644 index 0000000..b6a4572 --- /dev/null +++ b/tests/rendered/inkscape-with-title-no-color.expected @@ -0,0 +1,34 @@ + + inkscape + + An SVG (Scalable Vector Graphics) editing program. + Use -z to not open the GUI and only process files in the console. + + Open an SVG file in the Inkscape GUI: + + inkscape filename.svg + + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + + inkscape filename.svg -e filename.png + + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + + inkscape filename.svg -e filename.png -w 600 -h 400 + + Export a single object, given its ID, into a bitmap: + + inkscape filename.svg -i id -e object.png + + Export an SVG document to PDF, converting all texts to paths: + + inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path + + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + + inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit + + Some invalid command just to test the correct highlighting of the command name: + + inkscape --use-inkscape=v3.0 file + diff --git a/tests/rendered/inkscape-with-title.expected b/tests/rendered/inkscape-with-title.expected new file mode 100644 index 0000000..7e7d428 --- /dev/null +++ b/tests/rendered/inkscape-with-title.expected @@ -0,0 +1,34 @@ + + inkscape + + An SVG (Scalable Vector Graphics) editing program. + Use -z to not open the GUI and only process files in the console. + + Open an SVG file in the Inkscape GUI: + + inkscape filename.svg + + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + + inkscape filename.svg -e filename.png + + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + + inkscape filename.svg -e filename.png -w 600 -h 400 + + Export a single object, given its ID, into a bitmap: + + inkscape filename.svg -i id -e object.png + + Export an SVG document to PDF, converting all texts to paths: + + inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path + + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + + inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit + + Some invalid command just to test the correct highlighting of the command name: + + inkscape --use-inkscape=v3.0 file + From 911508ce33cf2d405e663de056bea4a483060efe Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 3 Oct 2025 20:15:34 +0200 Subject: [PATCH 167/196] Add `search.platforms` config option and search all platforms by default (#435) --- docs/src/config_search.md | 15 +++++++++ src/config.rs | 70 +++++++++++++++++++++++++++++++++------ src/main.rs | 27 ++++++--------- tests/lib.rs | 38 +++++++++++++++++++++ 4 files changed, 122 insertions(+), 28 deletions(-) diff --git a/docs/src/config_search.md b/docs/src/config_search.md index 2d59d65..d368159 100644 --- a/docs/src/config_search.md +++ b/docs/src/config_search.md @@ -12,3 +12,18 @@ Either way, the language used can be overwritten using the `--language` command [search] # Show pages in German if available, otherwise show in English languages = ["de", "en"] + +## `platforms` + +The list of platforms that should be considered when searching. +In addition to the platforms listed in the help text of the `--platform` flag, there are two special platforms available: +- `"current"`: equals the platform that tealdeer was compiled for +- `"all"`: adds all remaining platforms to the list + +Tealdeer searches the platforms in order of appearance in this list. +The default list of platforms is `["current", "common", "all"]`. +The list of platforms can be overwritten using the `--platform` command line flag. + + [search] + # Search for linux and common, and then search windows before trying the remaining platforms + platforms = ["linux", "common", "windows", "all"] diff --git a/src/config.rs b/src/config.rs index 446b841..e5e85e8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,11 +9,15 @@ use std::{ use anyhow::{anyhow, bail, ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; +use clap::ValueEnum; use serde::Serialize as _; use serde_derive::{Deserialize, Serialize}; use yansi::{Color, Style}; -use crate::{extensions::Dedup as _, types::PathSource}; +use crate::{ + extensions::Dedup as _, + types::{PathSource, PlatformType}, +}; pub const CONFIG_FILE_NAME: &str = "config.toml"; pub const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days @@ -217,9 +221,61 @@ struct RawDirectoriesConfig { pub custom_pages_dir: Option, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +enum RawPlatformType { + Current, + All, + MacOs, // alias for Platform(PlatformType::OsX) + #[serde(untagged)] + Platform(PlatformType), +} + +impl RawPlatformType { + pub fn flatten(raw_platforms: impl IntoIterator) -> Vec { + let mut flattened = Vec::new(); + for raw_platform in raw_platforms { + match raw_platform { + RawPlatformType::Current => flattened.push(PlatformType::current()), + RawPlatformType::Platform(platform) => flattened.push(platform), + RawPlatformType::MacOs => flattened.push(PlatformType::OsX), + RawPlatformType::All => flattened.extend(PlatformType::value_variants()), + } + } + flattened.clear_duplicates(); + flattened + } +} + #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawSearchConfig { pub languages: Option>, + pub platforms: Option>, +} + +impl<'a> From<&'a RawSearchConfig> for SearchConfig<'a> { + fn from(raw_search_config: &'a RawSearchConfig) -> Self { + let languages = raw_search_config + .languages + .as_ref() + .map_or_else(get_languages_from_env, |langs| { + langs.iter().map(|lang| Language(lang)).collect() + }); + let platforms = if let Some(raw_platforms) = raw_search_config.platforms.as_ref() { + RawPlatformType::flatten(raw_platforms.iter().copied()) + } else { + RawPlatformType::flatten([ + RawPlatformType::Current, + RawPlatformType::Platform(PlatformType::Common), + RawPlatformType::All, + ]) + }; + + Self { + languages, + platforms, + } + } } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -305,6 +361,7 @@ pub struct DirectoriesConfig { #[derive(Clone, Debug, PartialEq, Eq)] pub struct SearchConfig<'a> { pub languages: Vec>, + pub platforms: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -427,16 +484,7 @@ impl<'a> Config<'a> { fn from_raw(raw_config: &'a RawConfig, config_file_path: PathWithSource) -> Result { let style = (&raw_config.style).into(); let display = (&raw_config.display).into(); - - let search = SearchConfig { - languages: raw_config - .search - .languages - .as_ref() - .map_or_else(get_languages_from_env, |langs| { - langs.iter().map(|lang| Language(lang)).collect() - }), - }; + let search: SearchConfig<'a> = (&raw_config.search).into(); let updates = UpdatesConfig { auto_update: raw_config.updates.auto_update, diff --git a/src/main.rs b/src/main.rs index 2f730a4..fcf3273 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ use cache::{CacheConfig, TLDR_OLD_PAGES_DIR}; use clap::Parser; use config::{ConfigLoader, Language, StyleConfig, TlsBackend}; use log::debug; +use types::PlatformType; mod cache; mod cli; @@ -55,7 +56,7 @@ use crate::{ cli::Cli, config::{get_config_dir, make_default_config, Config, PathWithSource}, output::print_page, - types::{ColorOptions, PlatformType}, + types::ColorOptions, utils::{print_error, print_warning}, }; @@ -259,7 +260,13 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { return Ok(ExitCode::SUCCESS); } - let platforms = compute_platforms(args.platforms.as_ref()); + if let Some(platforms) = args.platforms { + config.search.platforms = platforms; + if !config.search.platforms.contains(&PlatformType::Common) { + config.search.platforms.push(PlatformType::Common); + } + } + let (search_languages, download_languages): (&[_], &[_]) = match args.language.as_deref() { Some(lang) => (&[Language(lang)], &[Language(lang)]), None => (&config.search.languages, &config.updates.download_languages), @@ -272,7 +279,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { .custom_pages_dir .as_ref() .map(PathWithSource::path), - platforms: &platforms, + platforms: &config.search.platforms, search_languages, download_languages, }; @@ -394,17 +401,3 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { Ok(ExitCode::SUCCESS) } - -/// Returns the passed or default platform types and appends `PlatformType::Common` as fallback. -fn compute_platforms(platforms: Option<&Vec>) -> Vec { - match platforms { - Some(p) => { - let mut result = p.clone(); - if !result.contains(&PlatformType::Common) { - result.push(PlatformType::Common); - } - result - } - None => vec![PlatformType::current(), PlatformType::Common], - } -} diff --git a/tests/lib.rs b/tests/lib.rs index ef5777d..cb987db 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -715,6 +715,36 @@ fn test_os_specific_page() { .success(); } +#[test] +fn test_config_platforms() { + let testenv = TestEnv::new(); + testenv.add_os_entry("sunos", "sunos-command", ""); + + let set_config_platforms = |platforms| { + testenv.delete_config(); + testenv.init_config(); + testenv.append_to_config(format!("search.platforms = {platforms}")); + }; + + // By default all platforms are searched + testenv.command().arg("sunos-command").assert().success(); + + set_config_platforms("[]"); + testenv.command().arg("sunos-command").assert().failure(); + + set_config_platforms("['linux']"); + testenv.command().arg("sunos-command").assert().failure(); + + set_config_platforms("['sunos']"); + testenv.command().arg("sunos-command").assert().success(); + + set_config_platforms("['linux', 'all']"); + testenv.command().arg("sunos-command").assert().success(); + + set_config_platforms("['current', 'all']"); + testenv.command().arg("sunos-command").assert().success(); +} + #[test] fn test_markdown_rendering() { let testenv = TestEnv::new().install_default_cache(); @@ -956,6 +986,14 @@ fn test_macos_is_alias_for_osx() { .args(["--platform", "osx", "--list"]) .assert() .stdout("maconly\n"); + + testenv.append_to_config("search.platforms = ['osx']\n"); + testenv.command().arg("--list").assert().stdout("maconly\n"); + + testenv.delete_config(); + testenv.init_config(); + testenv.append_to_config("search.platforms = ['macos']\n"); + testenv.command().arg("--list").assert().stdout("maconly\n"); } #[test] From 2b127fd67e7c0eef59efdff907dcf63da4dfcbe1 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 3 Oct 2025 20:59:22 +0200 Subject: [PATCH 168/196] Highlight code examples in user docs (#440) * Highlight code examples in user docs * Add missing quotes to archive_source example --- docs/src/config.md | 8 +++++-- docs/src/config_directories.md | 12 +++++++---- docs/src/config_display.md | 20 +++++++++++------ docs/src/config_search.md | 16 ++++++++------ docs/src/config_style.md | 12 ++++++++--- docs/src/config_updates.md | 39 +++++++++++++++++++++------------- docs/src/installing.md | 16 ++++++++++---- docs/src/usage_custom_pages.md | 16 ++++++++++---- 8 files changed, 94 insertions(+), 45 deletions(-) diff --git a/docs/src/config.md b/docs/src/config.md index b0bf922..a662b57 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -9,11 +9,15 @@ The configuration file path follows OS conventions (e.g. `$XDG_CONFIG_HOME/tealdeer/config.toml` on Linux). The paths can be queried with the following command: - $ tldr --show-paths +```shell +$ tldr --show-paths +``` Creating the config file can be done manually or with the help of `tldr`: - $ tldr --seed-config +```shell +$ tldr --seed-config +``` On Linux, this will usually be `~/.config/tealdeer/config.toml`. diff --git a/docs/src/config_directories.md b/docs/src/config_directories.md index b194dbb..507bd27 100644 --- a/docs/src/config_directories.md +++ b/docs/src/config_directories.md @@ -8,8 +8,10 @@ Override the cache directory. Remember to use an absolute path. Variable expansion will not be performed on the path. If the directory does not yet exist, it will be created. - [directories] - cache_dir = "/home/myuser/.tealdeer-cache/" +```toml +[directories] +cache_dir = "/home/myuser/.tealdeer-cache/" +``` If no `cache_dir` is specified, tealdeer will fall back to a location that follows OS conventions. On Linux, it will usually be at `~/.cache/tealdeer/`. @@ -21,5 +23,7 @@ Set the directory to be used to look up [custom pages](usage_custom_pages.html). Remember to use an absolute path. Variable expansion will not be performed on the path. - [directories] - custom_pages_dir = "/home/myuser/custom-tldr-pages/" +```toml +[directories] +custom_pages_dir = "/home/myuser/custom-tldr-pages/" +``` diff --git a/docs/src/config_display.md b/docs/src/config_display.md index 56b5cd3..78656a4 100644 --- a/docs/src/config_display.md +++ b/docs/src/config_display.md @@ -6,8 +6,10 @@ In the `display` section you can configure the output format. Specifies whether the pager should be used by default or not (default `false`). - [display] - use_pager = true +```toml +[display] +use_pager = true +``` When enabled, `less -R` is used as pager. To override the pager command used, set the `PAGER` environment variable. @@ -19,15 +21,19 @@ NOTE: This feature is not available on Windows. Set this to enforce more compact output, where empty lines are stripped out (default `false`). - [display] - compact = true +```toml +[display] +compact = true +``` ## `show_title` Display the command name at the top of the page output (default `false`). - [display] - show_title = true +```toml +[display] +show_title = true +``` When enabled, the command name will be displayed at the top of the output, -styled with the `command_name` style configuration. \ No newline at end of file +styled with the `command_name` style configuration. diff --git a/docs/src/config_search.md b/docs/src/config_search.md index d368159..28e00d6 100644 --- a/docs/src/config_search.md +++ b/docs/src/config_search.md @@ -9,9 +9,11 @@ The list of languages that should be considered when searching. If unspecified, the list of languages will be inferred from the `LANG` and `LANGUAGE` environment variables. Either way, the language used can be overwritten using the `--language` command line flag. - [search] - # Show pages in German if available, otherwise show in English - languages = ["de", "en"] +```toml +[search] +# Show pages in German if available, otherwise show in English +languages = ["de", "en"] +``` ## `platforms` @@ -24,6 +26,8 @@ Tealdeer searches the platforms in order of appearance in this list. The default list of platforms is `["current", "common", "all"]`. The list of platforms can be overwritten using the `--platform` command line flag. - [search] - # Search for linux and common, and then search windows before trying the remaining platforms - platforms = ["linux", "common", "windows", "all"] +```toml +[search] +# Search for linux and common, and then search windows before trying the remaining platforms +platforms = ["linux", "common", "windows", "all"] +``` diff --git a/docs/src/config_style.md b/docs/src/config_style.md index 190df4c..593a5b5 100644 --- a/docs/src/config_style.md +++ b/docs/src/config_style.md @@ -26,16 +26,22 @@ Colors can be specified in one of three ways: Example: - foreground = "green" + ```toml + foreground = "green" + ``` - 256 color ANSI code (*tealdeer v1.5.0+*) Example: - foreground = { ansi = 4 } + ```toml + foreground = { ansi = 4 } + ``` - 24-bit RGB color (*tealdeer v1.5.0+*) Example: - background = { rgb = { r = 255, g = 255, b = 255 } } + ```toml + background = { rgb = { r = 255, g = 255, b = 255 } } + ``` diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index cc5868e..9acba55 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -13,8 +13,10 @@ default. Specifies whether the auto-update feature should be enabled (defaults to `false`). - [updates] - auto_update = true +```toml +[updates] +auto_update = true +``` ### `auto_update_interval_hours` @@ -22,9 +24,11 @@ Duration, since the last cache update, after which the cache will be refreshed (defaults to 720 hours). This parameter is ignored if `auto_update` is set to `false`. - [updates] - auto_update = true - auto_update_interval_hours = 24 +```toml +[updates] +auto_update = true +auto_update_interval_hours = 24 +``` ## Download configuration @@ -35,20 +39,24 @@ If unspecified, the languages listed in the `search.languages` setting are used. Thus, this setting is the most useful to instruct tealdeer to download pages in additional languages that are not searched by default. Either way, the language used can be overwritten using the `--language` command line flag. - [search] - languages = ["de", "en"] +```toml +[search] +languages = ["de", "en"] - [updates] - # sometimes I like to read the Italian description - download_languages = ["de", "en", "it"] +[updates] +# sometimes I like to read the Italian description +download_languages = ["de", "en", "it"] +``` ### `archive_source` URL for the location of the tldr pages archive. By default the pages are fetched from the latest `tldr-pages/tldr` GitHub release. - [updates] - archive_source = https://my-company.example.com/tldr/ +```toml +[updates] +archive_source = "https://my-company.example.com/tldr/" +``` ### `tls_backend` @@ -62,9 +70,10 @@ Available options: - Secure Transport on macOS - OpenSSL on other platforms - [updates] - tls_backend = "native-tls" - +```toml +[updates] +tls_backend = "native-tls" +``` [rustls]: https://github.com/rustls/rustls [rustls-webpki]: https://github.com/rustls/webpki diff --git a/docs/src/installing.md b/docs/src/installing.md index 39de050..0bee062 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -38,21 +38,29 @@ Simply download the binary for your platform and run it! Build and install the tool via cargo... - $ cargo install tealdeer +```shell +$ cargo install tealdeer +``` ## Build From Source Release build: - $ cargo build --release +```shell +$ cargo build --release +``` Release build with bundled CA roots: - $ cargo build --release --no-default-features --features rustls-with-webpki-roots +```shell +$ cargo build --release --no-default-features --features rustls-with-webpki-roots +``` Debug build with logging support: - $ cargo build --features logging +```shell +$ cargo build --features logging +``` (To enable logging at runtime, export the `RUST_LOG=tldr=debug` env variable.) diff --git a/docs/src/usage_custom_pages.md b/docs/src/usage_custom_pages.md index d5d0f89..c73bf90 100644 --- a/docs/src/usage_custom_pages.md +++ b/docs/src/usage_custom_pages.md @@ -28,11 +28,15 @@ your custom page will be shown instead of the upstream version in the cache. Path: - $CUSTOM_PAGES_DIR/.page.md +```plain +$CUSTOM_PAGES_DIR/.page.md +``` Example: - ~/.local/share/tealdeer/pages/ufw.page.md +```plain +~/.local/share/tealdeer/pages/ufw.page.md +``` ## Custom Patches @@ -43,8 +47,12 @@ pages. Path: - $CUSTOM_PAGES_DIR/.patch.md +```plain +$CUSTOM_PAGES_DIR/.patch.md +``` Example: - ~/.local/share/tealdeer/pages/ufw.patch.md +```plain +~/.local/share/tealdeer/pages/ufw.patch.md +``` From 9a83b58d5110a6134546a9e1be227394c055caa2 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 3 Oct 2025 22:38:02 +0200 Subject: [PATCH 169/196] Bump MSRV to 1.85 and update dependencies (#441) The latest version of base64ct requires 1.85, and I don't want to think about whether older versions of crypto libraries are safe. --- .github/workflows/ci.yml | 2 +- Cargo.lock | 773 +++++++++++++++++++++++---------------- Cargo.toml | 4 +- 3 files changed, 463 insertions(+), 316 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f20709e..93b83e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - toolchain: [stable, 1.80.1] + toolchain: [stable, 1.85.0] include: - platform: windows-latest exe_suffix: .exe diff --git a/Cargo.lock b/Cargo.lock index 4da46ef..1ac11fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -34,43 +34,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "app_dirs2" @@ -78,7 +79,7 @@ version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7e7b35733e3a8c1ccb90385088dd5b6eaa61325cb4d1ad56e683b5224ff352e" dependencies = [ - "jni 0.21.1", + "jni", "ndk-context", "winapi", "xdg", @@ -86,18 +87,18 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] name = "assert_cmd" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" +checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" dependencies = [ "anstyle", "bstr", @@ -111,9 +112,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -123,21 +124,21 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bstr" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -146,22 +147,23 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytes" -version = "1.7.2" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.6" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ + "find-msvc-tools", "shlex", ] @@ -173,15 +175,15 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "clap" -version = "4.5.19" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -189,9 +191,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -201,9 +203,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", @@ -213,15 +215,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -243,6 +245,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -251,24 +263,18 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "pem-rfc7468", "zeroize", @@ -276,9 +282,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", @@ -291,17 +297,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "doc-comment" version = "0.3.3" @@ -310,9 +305,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "env_filter" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", "regex", @@ -320,22 +315,22 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.5" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -350,12 +345,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -370,49 +365,55 @@ dependencies = [ [[package]] name = "escargot" -version = "0.5.12" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000f23e9d459aef148b7267e02b03b94a0aaacf4ec64c65612f67e02f525fb6" +checksum = "11c3aea32bc97b500c9ca6a72b768a26e558264303d101d3409cf6d57a9ed0cf" dependencies = [ "log", - "once_cell", "serde", "serde_json", ] [[package]] name = "fastrand" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] -name = "flate2" -version = "1.0.34" +name = "find-msvc-tools" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", + "libz-rs-sys", "miniz_oxide", ] [[package]] name = "float-cmp" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ "num-traits", ] @@ -440,20 +441,32 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "heck" @@ -463,9 +476,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -474,21 +487,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "indexmap" -version = "2.6.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", "hashbrown", @@ -502,22 +509,32 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] -name = "jni" -version = "0.19.0" +name = "jiff" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ - "cesu8", - "combine", - "jni-sys", + "jiff-static", "log", - "thiserror 1.0.64", - "walkdir", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -531,7 +548,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror 1.0.64", + "thiserror", "walkdir", "windows-sys 0.45.0", ] @@ -544,15 +561,15 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags", "libc", @@ -560,43 +577,46 @@ dependencies = [ ] [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "libz-rs-sys" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" +dependencies = [ + "zlib-rs", +] [[package]] -name = "lockfree-object-pool" -version = "0.1.6" +name = "linux-raw-sys" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "log" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "native-tls" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -604,7 +624,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -621,25 +641,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -651,15 +652,21 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags", "cfg-if", @@ -689,9 +696,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -720,21 +727,36 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "predicates" -version = "3.1.2" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" dependencies = [ "anstyle", "difflib", @@ -746,15 +768,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" [[package]] name = "predicates-tree" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" dependencies = [ "predicates-core", "termtree", @@ -762,36 +784,42 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] [[package]] -name = "redox_syscall" -version = "0.5.7" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -801,9 +829,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -812,43 +840,42 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.16", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rustix" -version = "0.38.37" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", - "errno 0.3.9", + "errno 0.3.14", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "log", "once_cell", @@ -861,15 +888,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.5.1", ] [[package]] @@ -883,29 +909,32 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-platform-verifier" -version = "0.3.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0" dependencies = [ - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", - "jni 0.19.0", + "jni", "log", "once_cell", "rustls", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 3.5.1", "security-framework-sys", - "webpki-roots", - "winapi", + "webpki-root-certs", + "windows-sys 0.59.0", ] [[package]] @@ -916,9 +945,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -927,9 +956,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -942,11 +971,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -956,18 +985,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", "core-foundation-sys", "libc", - "num-bigint", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -975,18 +1016,28 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -995,21 +1046,22 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -1026,12 +1078,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "subtle" version = "2.6.1" @@ -1040,9 +1086,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -1074,67 +1120,47 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] name = "terminal_size" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ "rustix", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "termtree" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.64", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -1143,9 +1169,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", @@ -1155,31 +1181,38 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] [[package]] -name = "unicode-ident" -version = "1.0.13" +name = "toml_write" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "untrusted" @@ -1189,9 +1222,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.0.8" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06f78313c985f2fba11100dd06d60dd402d0cabb458af4d94791b8e09c025323" +checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" dependencies = [ "base64", "der", @@ -1211,9 +1244,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.3.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64adb55464bad1ab1aa9229133d0d59d2f679180f4d15f0d9debe616f541f25e" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" dependencies = [ "base64", "http", @@ -1241,9 +1274,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -1260,24 +1293,42 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "webpki-root-certs" -version = "0.26.8" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4" +checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "0.26.8" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] @@ -1300,11 +1351,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -1313,6 +1364,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-sys" version = "0.45.0" @@ -1340,6 +1397,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.4", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -1364,13 +1439,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -1383,6 +1475,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -1395,6 +1493,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -1407,12 +1511,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -1425,6 +1541,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -1437,6 +1559,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -1449,6 +1577,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -1462,14 +1596,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.6.20" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "xdg" version = "2.5.2" @@ -1484,37 +1630,38 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zip" -version = "2.4.1" +version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938cc23ac49778ac8340e366ddc422b2227ea176edb447e23fc0627608dddadd" +checksum = "2f852905151ac8d4d06fdca66520a661c09730a74c6d4e2b0f27b436b382e532" dependencies = [ "arbitrary", "crc32fast", - "crossbeam-utils", - "displaydoc", "flate2", "indexmap", "memchr", - "thiserror 2.0.12", "zopfli", ] [[package]] -name = "zopfli" -version = "0.8.1" +name = "zlib-rs" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" + +[[package]] +name = "zopfli" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" dependencies = [ "bumpalo", "crc32fast", - "lockfree-object-pool", "log", - "once_cell", "simd-adler32", ] diff --git a/Cargo.toml b/Cargo.toml index 3447307..1123a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" version = "1.7.2" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] -rust-version = "1.80" +rust-version = "1.85" edition = "2021" [[bin]] @@ -30,7 +30,7 @@ serde_derive = "1.0.21" ureq = { version = "3.0.8", default-features = false, features = ["gzip"] } toml = "0.8.19" yansi = "1" -zip = { version = "2.3.0", default-features = false, features = ["deflate"] } +zip = { version = "5.1.1", default-features = false, features = ["deflate"] } [target.'cfg(not(windows))'.dependencies] pager = "0.16" From 49626977ffc42b8445dddebde078028357ae3125 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 3 Oct 2025 22:44:39 +0200 Subject: [PATCH 170/196] Run `cargo +nightly clippy --fix` and formatting (#442) --- src/cache.rs | 5 +---- src/cli.rs | 2 +- src/formatter.rs | 2 +- src/line_iterator.rs | 4 ++-- src/main.rs | 1 + src/types.rs | 8 ++------ 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 23fd668..b181310 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -369,10 +369,7 @@ impl Cache<'_> { } Ok(response) if response.status() == StatusCode::NOT_FOUND => Ok(None), _ => { - bail!( - "Could not download tldr pages from {archive_url}: {:?}", - response, - ) + bail!("Could not download tldr pages from {archive_url}: {response:?}",) } } } diff --git a/src/cli.rs b/src/cli.rs index 55fe74f..d461a3e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; -use clap::{arg, builder::ArgAction, command, ArgGroup, Parser}; +use clap::{builder::ArgAction, ArgGroup, Parser}; use crate::types::{ColorOptions, PlatformType}; diff --git a/src/formatter.rs b/src/formatter.rs index d86de9b..5270124 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -68,7 +68,7 @@ where process_snippet(PageSnippet::Linebreak)?; } - LineType::Other(text) => debug!("Unknown line type: {:?}", text), + LineType::Other(text) => debug!("Unknown line type: {text:?}"), } } process_snippet(PageSnippet::Linebreak)?; diff --git a/src/line_iterator.rs b/src/line_iterator.rs index 2e11378..98088c0 100644 --- a/src/line_iterator.rs +++ b/src/line_iterator.rs @@ -53,7 +53,7 @@ impl Iterator for LineIterator { match bytes_read { Ok(0) => None, Err(e) => { - warn!("Could not read line from reader: {:?}", e); + warn!("Could not read line from reader: {e:?}"); None } Ok(_) => { @@ -68,7 +68,7 @@ impl Iterator for LineIterator { .find(|b| matches!(b, Ok(b'\n') | Err(_))) .transpose() { - warn!("Could not read line from reader: {:?}", e); + warn!("Could not read line from reader: {e:?}"); return None; } self.first_line = false; diff --git a/src/main.rs b/src/main.rs index fcf3273..a0cd593 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ #![allow(clippy::similar_names)] #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_lines)] +#![allow(clippy::unnecessary_debug_formatting)] #[cfg(not(any( feature = "native-tls", diff --git a/src/types.rs b/src/types.rs index 69c7599..7ca6e2d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -118,18 +118,14 @@ impl PlatformType { #[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize, clap::ValueEnum)] #[serde(rename_all = "lowercase")] +#[derive(Default)] pub enum ColorOptions { Always, + #[default] Auto, Never, } -impl Default for ColorOptions { - fn default() -> Self { - Self::Auto - } -} - #[derive(Debug, Eq, PartialEq)] pub enum LineType { Empty, From d49c4a9e05eab5018e322c03da01279040def538 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 3 Oct 2025 22:59:18 +0200 Subject: [PATCH 171/196] Release v1.8.0 --- CHANGELOG.md | 142 ++++++++++++++++++++++++++++++++++++----- Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/installing.md | 4 +- docs/src/usage.txt | 2 +- 5 files changed, 131 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c8af3a..a1c479f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,86 @@ Possible log types: - `[docs]` for documentation changes. - `[chore]` for maintenance work. +### [v1.8.0][v1.8.0] (2025-10-03) + +One year and one day have passed since tealdeer version 1.7.0 was released, so +it's time for an update! Tealdeer 1.8 comes with a complete rewrite of the page +cache and contains many long awaited improvements around it. + +Firstly, tealdeer now supports language-specific downloads. This means that only +the pages matching the configured languages are downloaded when updating the +cache. The languages used for searching pages can be configured separately to +the ones used for updating, so it is possible to download pages in languages +that are not usually queried. + +Next to configuring which languages are used for searching, it is now also +possible to specify which platforms are used in the config file. Importantly, +the default behavior for page search has changed so that all platforms are +searched if no page is found for the platform that tealdeer is running on. To +restore the behavior of tealdeer 1.7, users should set +```toml +[search] +platforms = ["current", "common"] +``` +in their config file. + +Coming back to updating, the default build configuration of tealdeer now +includes multiple TLS backends. This means that tealdeer does not have to be +rebuilt to try out a different TLS backend. The used backend can be chosen in +the config file. By default, tealdeer comes with support for rustls using webpki +certificates or system certificates. Native TLS is supported, but not enabled by +default to avoid build troubles with OpenSSL and musl. + +For details, please refer to the [user documentation]. + +#### Changes: + +- [added] Resolve paths in config `[directories]` relative to the config directory ([#306]) +- [added] Add `common` platform to CLI ([#401]) +- [added] Add configuration option for `archive_source` ([#337]) +- [added] Allows configuring TLS backend ([#386]) +- [added] Add args: `--edit-page` and `--edit-patch` ([#388]) +- [added] Add an option to specify a custom config file to be used ([#422]) +- [added] Upload binaries from build step as artifact ([#423]) +- [added] Add `search.languages` and `updates.download_languages` settings ([#430]) +- [added] Add `search.platforms` config option and search all platforms by default ([#435]) +- [added] Add `display.show_title` option to display command titles in output ([#439]) +- [chore] Various test improvements ([#399]) +- [chore] Add tests for osx/macos alias ([#407]) +- [chore] Move most of `main` to `try_main` ([#400]) +- [chore] Only create a single temporary directory in integration tests ([#411]) +- [chore] Replace reqwest with ureq ([#417]) +- [chore] Introduce Language struct ([#425]) +- [chore] Cache rewrite ([#416]) +- [chore] Allow references in `Config` ([#429]) +- [docs] Highlight code examples in user docs ([#440]) +- [removed] Remove native-tls from default feature set ([#436]) + +#### Contributors to this version: + +- [Christoph Loy][@beatbrot] +- [Erick Guan][@erickguan] +- [@MHS-0][@MHS-0] +- [Matěj Kafka][@MatejKafka] +- [Nachiket Kanore][@nachiketkanore] +- [Niklas Mohrin][@niklasmohrin] +- [Predrag Minic][@mipedja] +- [@hex1c][@hex1c] +- [lyj][@lengyijun] + +Thanks! + +#### Notes to package maintainers + +1. The MSRV has been bumped to 1.85. +2. Consider whether you want to include the `native-tls` feature in your build + of tealdeer. The feature is disabled for the binaries in the GitHub release + because we target musl, but it might work out of the box for your + distribution. +3. We have added the `ignore-online-tests` feature to automatically mark all + tests that require an internet connection as skipped, so you can use this + feature instead of maintaining a list of these tests yourself. + ### [v1.7.2][v1.7.2] (2025-03-18) This patch release updates the `zip` dependency to mitigate a potential security @@ -34,11 +114,11 @@ This patch release updates the `yansi` dependency to version 1, so that the previous versions of `yansi` can be removed from the package sets of Linux distributions. This change should not impact the behavior of tealdeer. -Changes: +#### Changes: - [chore] Upgrade yansi: 0.5.1 -> 1.0.1 ([#389]) -Contributors to this version: +#### Contributors to this version: - [Blair Noctis][@nc7s] @@ -74,7 +154,7 @@ On a personal note, this will be the last release from me ([Danilo](https://github.com/dbrgn/)) as primary maintainer of tealdeer. For details, see [#376](https://github.com/tealdeer-rs/tealdeer/issues/376). -Changes: +#### Changes: - [added] Allow querying multiple platforms ([#300]) - [added] Add BSD platform support ([#354]) @@ -94,7 +174,7 @@ Changes: - [chore] Update Cargo.toml license field following SPDX 2.1 ([#336]) - [chore] Dependency updates -Contributors to this version: +#### Contributors to this version: - [Adam Henley][@adamazing] - [Andrea Frigido][@frisoft] @@ -118,12 +198,12 @@ Thanks! ### [v1.6.1][v1.6.1] (2022-10-24) -Changes: +#### Changes: - [fixed] Fix path source for custom pages dir ([#297]) - [chore] Update dependendencies ([#299]) -Contributors to this version: +#### Contributors to this version: - [Cyrus Yip][@CyrusYip] - [Danilo Bargen][@dbrgn] @@ -142,7 +222,7 @@ The `TEALDEER_CACHE_DIR` env variable is now deprecated. A note to packagers: Shell completions have been moved to the `completion/` subdirectory! Packaging scripts might need to be updated. -Changes: +#### Changes: - [added] Allow overriding cache directory through config ([#276]) - [added] Add `--no-auto-update` CLI flag ([#257]) @@ -163,7 +243,7 @@ Changes: - [chore] Use anyhow for error handling ([#249]) - [chore] Switch to Rust 2021 edition ([#284]) -Contributors to this version: +#### Contributors to this version: - [@bagohart][@bagohart] - [@cyqsimon][@cyqsimon] @@ -212,7 +292,7 @@ Note that the MSRV (Minimal Supported Rust Version) of the project > When publishing a tealdeer release, the Rust version required to build it > should be stable for at least a month. -Changes: +#### Changes: - [added] Support custom pages and patches ([#142][i142]) - [added] Multi-language support ([#125][i125], [#161][i161]) @@ -243,7 +323,7 @@ Changes: - [chore] All release binaries are now generated in CI. Binaries for macOS and Windows are also provided. ([#240][i240]) - [chore] Update all dependencies -Contributors to this version: +#### Contributors to this version: - [@bl-ue][@bl-ue] - [Cameron Tod][@cam8001] @@ -272,7 +352,7 @@ co-maintainer. Thank you for your help! - [fixed] Syntax error in zsh completion file ([#138][i138]) -Contributors to this version: +#### Contributors to this version: - [Danilo Bargen][@dbrgn] - [Bruno A. Muciño][@mucinoab] @@ -289,7 +369,7 @@ Thanks! - [changed] Make `--list` option comply with official spec ([#112][i112]) - [changed] Move cache age warning to stderr ([#113][i113]) -Contributors to this version: +#### Contributors to this version: - [Atul Bhosale][@Atul9] - [Danilo Bargen][@dbrgn] @@ -315,7 +395,7 @@ Thanks! - [fixed] Fix Fish autocompletion on macOS ([#87][i87]) - [fixed] Fix compilation on Windows by disabling pager ([#99][i99]) -Contributors to this version: +#### Contributors to this version: - [Bruno Heridet][@Delapouite] - [Danilo Bargen][@dbrgn] @@ -341,7 +421,7 @@ Thanks! - [changed] Move to Rust 2018, require Rust 1.32 ([#69][i69] / [#84][i84]) - [fixed] Add (back) support for proxies ([#68][i68]) -Contributors to this version: +#### Contributors to this version: - [Bar Hatsor][@Bassets] - [Danilo Bargen][@dbrgn] @@ -364,7 +444,7 @@ Thanks! - [changed] Require at least Rust 1.28 to build (previous: 1.19) - [fixed] Fix building on systems with openssl 1.1.1 ([#47][i47]) -Contributors to this version: +#### Contributors to this version: - [Danilo Bargen][@dbrgn] - [@equal-l2][@equal-l2] @@ -397,7 +477,7 @@ Thanks! - First crates.io release - +[user documentation]: https://tealdeer-rs.github.io/tealdeer/ [@0ndorio]: https://github.com/0ndorio [@adamazing]: https://github.com/adamazing @@ -460,6 +540,14 @@ Thanks! [@Walker-00]: https://github.com/Walker-00 [@YDX-2147483647]: https://github.com/YDX-2147483647 [@zedseven]: https://github.com/zedseven +[@beatbrot]: https://github.com/beatbrot +[@erickguan]: https://github.com/erickguan +[@MHS-0]: https://github.com/MHS-0 +[@MatejKafka]: https://github.com/MatejKafka +[@nachiketkanore]: https://github.com/nachiketkanore +[@mipedja]: https://github.com/mipedja +[@hex1c]: https://github.com/hex1c +[@lengyijun]: https://github.com/lengyijun [v1.0.0]: https://github.com/tealdeer-rs/tealdeer/compare/v0.4.0...v1.0.0 [v1.1.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.0.0...v1.1.0 @@ -473,6 +561,7 @@ Thanks! [v1.7.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.7.0 [v1.7.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.0...v1.7.1 [v1.7.2]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.1...v1.7.2 +[v1.8.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.2...v1.8.0 [i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 [i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 @@ -544,6 +633,7 @@ Thanks! [#300]: https://github.com/tealdeer-rs/tealdeer/pull/300 [#303]: https://github.com/tealdeer-rs/tealdeer/pull/303 [#305]: https://github.com/tealdeer-rs/tealdeer/pull/305 +[#306]: https://github.com/tealdeer-rs/tealdeer/pull/306 [#314]: https://github.com/tealdeer-rs/tealdeer/pull/314 [#315]: https://github.com/tealdeer-rs/tealdeer/pull/315 [#322]: https://github.com/tealdeer-rs/tealdeer/pull/322 @@ -552,8 +642,28 @@ Thanks! [#331]: https://github.com/tealdeer-rs/tealdeer/pull/331 [#333]: https://github.com/tealdeer-rs/tealdeer/pull/333 [#336]: https://github.com/tealdeer-rs/tealdeer/pull/336 +[#337]: https://github.com/tealdeer-rs/tealdeer/pull/337 [#342]: https://github.com/tealdeer-rs/tealdeer/pull/342 [#354]: https://github.com/tealdeer-rs/tealdeer/pull/354 [#355]: https://github.com/tealdeer-rs/tealdeer/pull/355 [#362]: https://github.com/tealdeer-rs/tealdeer/pull/362 +[#386]: https://github.com/tealdeer-rs/tealdeer/pull/386 +[#388]: https://github.com/tealdeer-rs/tealdeer/pull/388 [#389]: https://github.com/tealdeer-rs/tealdeer/pull/389 +[#399]: https://github.com/tealdeer-rs/tealdeer/pull/399 +[#400]: https://github.com/tealdeer-rs/tealdeer/pull/400 +[#401]: https://github.com/tealdeer-rs/tealdeer/pull/401 +[#407]: https://github.com/tealdeer-rs/tealdeer/pull/407 +[#411]: https://github.com/tealdeer-rs/tealdeer/pull/411 +[#416]: https://github.com/tealdeer-rs/tealdeer/pull/416 +[#417]: https://github.com/tealdeer-rs/tealdeer/pull/417 +[#422]: https://github.com/tealdeer-rs/tealdeer/pull/422 +[#423]: https://github.com/tealdeer-rs/tealdeer/pull/423 +[#425]: https://github.com/tealdeer-rs/tealdeer/pull/425 +[#426]: https://github.com/tealdeer-rs/tealdeer/pull/426 +[#429]: https://github.com/tealdeer-rs/tealdeer/pull/429 +[#430]: https://github.com/tealdeer-rs/tealdeer/pull/430 +[#435]: https://github.com/tealdeer-rs/tealdeer/pull/435 +[#436]: https://github.com/tealdeer-rs/tealdeer/pull/436 +[#439]: https://github.com/tealdeer-rs/tealdeer/pull/439 +[#440]: https://github.com/tealdeer-rs/tealdeer/pull/440 diff --git a/Cargo.lock b/Cargo.lock index 1ac11fe..661c998 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1097,7 +1097,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.7.2" +version = "1.8.0" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index 1123a69..44c13ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" -version = "1.7.2" +version = "1.8.0" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.85" edition = "2021" diff --git a/docs/src/installing.md b/docs/src/installing.md index 0bee062..f0ca823 100644 --- a/docs/src/installing.md +++ b/docs/src/installing.md @@ -50,10 +50,10 @@ Release build: $ cargo build --release ``` -Release build with bundled CA roots: +Release build with native TLS support: ```shell -$ cargo build --release --no-default-features --features rustls-with-webpki-roots +$ cargo build --release --features native-tls ``` Debug build with logging support: diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 33e6020..7618ac4 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.7.2: A fast TLDR client +tealdeer 1.8.0: A fast TLDR client Danilo Bargen , Niklas Mohrin Usage: tldr [OPTIONS] [COMMAND]... From 6c1d7027696530f30d5ce47f57a8b6ad1e6552d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:18:45 +0100 Subject: [PATCH 172/196] Bump actions/download-artifact from 5 to 6 (#448) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 360dd94..ee63de1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -135,7 +135,7 @@ jobs: - windows-x86_64-msvc steps: - uses: actions/checkout@v5 - - uses: actions/download-artifact@v5 + - uses: actions/download-artifact@v6 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | From e1213158e45679680540eaec32648ca19d704393 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:19:23 +0100 Subject: [PATCH 173/196] Bump actions/upload-artifact from 4 to 5 (#447) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93b83e4..2fc4485 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: # expects runners have the proper Native SSL library cargo build --features native-tls --no-default-features cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-native-tls${{ matrix.exe_suffix}} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: tldr-debug-build-${{ matrix.platform }}-rust-${{ matrix.toolchain }} path: artifacts/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee63de1..539f2ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,7 +73,7 @@ jobs: run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" @@ -94,7 +94,7 @@ jobs: targets: "${{ matrix.arch }}-apple-darwin" - name: Build run: cargo build --release --target ${{ matrix.arch }}-apple-darwin - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: "tealdeer-macos-${{ matrix.arch }}" path: "target/${{ matrix.arch }}-apple-darwin/release/tldr" @@ -109,7 +109,7 @@ jobs: toolchain: stable - name: Build run: cargo build --release --target x86_64-pc-windows-msvc - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: "tealdeer-windows-x86_64-msvc" path: "target/x86_64-pc-windows-msvc/release/tldr.exe" From e769114d8b2dd35096dd00a0bf3e7584a57815fb Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 11 Nov 2025 17:33:19 +0100 Subject: [PATCH 174/196] Enable ureq's socks-proxy feature (#451) --- Cargo.lock | 18 ++++++++++++++++++ Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 661c998..dbd9a3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,12 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.1" @@ -1078,6 +1084,17 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "socks" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" +dependencies = [ + "byteorder", + "libc", + "winapi", +] + [[package]] name = "subtle" version = "2.6.1" @@ -1236,6 +1253,7 @@ dependencies = [ "rustls-pemfile", "rustls-pki-types", "rustls-platform-verifier", + "socks", "ureq-proto", "utf-8", "webpki-root-certs", diff --git a/Cargo.toml b/Cargo.toml index 44c13ef..e9aff22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ env_logger = { version = "0.11", optional = true } log = "0.4" serde = "1.0.21" serde_derive = "1.0.21" -ureq = { version = "3.0.8", default-features = false, features = ["gzip"] } +ureq = { version = "3.0.8", default-features = false, features = ["gzip", "socks-proxy"] } toml = "0.8.19" yansi = "1" zip = { version = "5.1.1", default-features = false, features = ["deflate"] } From b3cd7b1c216656ea3416a86104363589157477dc Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Tue, 11 Nov 2025 22:27:52 +0100 Subject: [PATCH 175/196] Release v1.8.1 --- CHANGELOG.md | 12 ++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- docs/src/usage.txt | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1c479f..5a80bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,16 @@ Possible log types: - `[docs]` for documentation changes. - `[chore]` for maintenance work. +### [v1.8.1][v1.8.1] (2025-11-11) + +This patch release tweaks the enabled features for ureq, the library we use to +perform HTTP requests when updating the cache. In particular, support for socks +proxies is now enabled. + +#### Changes: + +- [added] Enable ureq's socks-proxy feature ([#451]) + ### [v1.8.0][v1.8.0] (2025-10-03) One year and one day have passed since tealdeer version 1.7.0 was released, so @@ -562,6 +572,7 @@ Thanks! [v1.7.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.0...v1.7.1 [v1.7.2]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.1...v1.7.2 [v1.8.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.2...v1.8.0 +[v1.8.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.8.0...v1.8.1 [i34]: https://github.com/tealdeer-rs/tealdeer/issues/34 [i43]: https://github.com/tealdeer-rs/tealdeer/issues/43 @@ -667,3 +678,4 @@ Thanks! [#436]: https://github.com/tealdeer-rs/tealdeer/pull/436 [#439]: https://github.com/tealdeer-rs/tealdeer/pull/439 [#440]: https://github.com/tealdeer-rs/tealdeer/pull/440 +[#451]: https://github.com/tealdeer-rs/tealdeer/pull/451 diff --git a/Cargo.lock b/Cargo.lock index dbd9a3f..be9bd24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1114,7 +1114,7 @@ dependencies = [ [[package]] name = "tealdeer" -version = "1.8.0" +version = "1.8.1" dependencies = [ "anyhow", "app_dirs2", diff --git a/Cargo.toml b/Cargo.toml index e9aff22..aa7ae49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "tealdeer" readme = "README.md" repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" -version = "1.8.0" +version = "1.8.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] rust-version = "1.85" edition = "2021" diff --git a/docs/src/usage.txt b/docs/src/usage.txt index 7618ac4..f7fcc46 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -1,4 +1,4 @@ -tealdeer 1.8.0: A fast TLDR client +tealdeer 1.8.1: A fast TLDR client Danilo Bargen , Niklas Mohrin Usage: tldr [OPTIONS] [COMMAND]... From c5d62e5987b38705814b72354373c50fe165dbb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 20:32:38 +0100 Subject: [PATCH 176/196] Bump actions/checkout from 5 to 6 (#454) Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/gh-pages.yml | 2 +- .github/workflows/release.yml | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2fc4485..b557674 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: exe_suffix: .exe runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} @@ -50,7 +50,7 @@ jobs: name: run clippy lints runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -62,7 +62,7 @@ jobs: name: run rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -74,7 +74,7 @@ jobs: name: build docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 with: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 8746d42..f841705 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -8,7 +8,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 539f2ab..e48fc17 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: create-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Create release for tag if: startsWith(github.ref, 'refs/tags/') run: | @@ -24,7 +24,7 @@ jobs: matrix: target: ["bash", "fish", "zsh"] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | @@ -40,7 +40,7 @@ jobs: matrix: target: ["MIT", "APACHE"] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | @@ -66,7 +66,7 @@ jobs: - arch: "arm" libc: "musleabihf" steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - name: Build in Docker @@ -86,7 +86,7 @@ jobs: - arch: "x86_64" - arch: "aarch64" steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -102,7 +102,7 @@ jobs: build-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -134,7 +134,7 @@ jobs: - macos-aarch64 - windows-x86_64-msvc steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/download-artifact@v6 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') From 3a6fd99c859a28c1913963d8d25303b43d5fcce0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 18:55:41 +0100 Subject: [PATCH 177/196] Bump actions/download-artifact from 6 to 7 (#457) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e48fc17..1d978e6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -135,7 +135,7 @@ jobs: - windows-x86_64-msvc steps: - uses: actions/checkout@v6 - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | From 5ee1f28021a563ab9d2ec06cc9d07c80254164a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 18:55:53 +0100 Subject: [PATCH 178/196] Bump actions/upload-artifact from 5 to 6 (#456) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b557674..a0b20ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: # expects runners have the proper Native SSL library cargo build --features native-tls --no-default-features cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-native-tls${{ matrix.exe_suffix}} - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: tldr-debug-build-${{ matrix.platform }}-rust-${{ matrix.toolchain }} path: artifacts/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d978e6..9813f00 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,7 +73,7 @@ jobs: run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" @@ -94,7 +94,7 @@ jobs: targets: "${{ matrix.arch }}-apple-darwin" - name: Build run: cargo build --release --target ${{ matrix.arch }}-apple-darwin - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: "tealdeer-macos-${{ matrix.arch }}" path: "target/${{ matrix.arch }}-apple-darwin/release/tldr" @@ -109,7 +109,7 @@ jobs: toolchain: stable - name: Build run: cargo build --release --target x86_64-pc-windows-msvc - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: "tealdeer-windows-x86_64-msvc" path: "target/x86_64-pc-windows-msvc/release/tldr.exe" From 75e5462312e91cd55831067219560dedb234473f Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 25 Jan 2026 18:13:31 +0100 Subject: [PATCH 179/196] Update CHANGELOG.md --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a80bbb..644a30a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,46 @@ Possible log types: - `[docs]` for documentation changes. - `[chore]` for maintenance work. +### [v1.5.1][v1.5.1], [v1.6.2][v1.6.2], [v1.7.3][v1.7.3] (2026-01-25) + +Today I am releasing three patch updates for outdated versions of tealdeer. +They are minimal patches for Linux distributions that ship old versions of +tealdeer which recently broke due to an upstream change. If you can choose +freely which version of tealdeer to use, I recommend using the latest version of +tealdeer, 1.8.1. For more details, see the "Notes to package maintainers" +section below. + +All three updates contain only a single change compared to their respective +previous versions which changes the `ARCHIVE_URL` constant used for updating the +page cache. The reason for this change is that the upstream tldr-pages +repository shut down the domain that clients were previously required to use. + +Note that this issue is already fixed in tealdeer 1.8.0 where we introduced a +config file option for changing the URL used at runtime. The versions 1.8.0 and +1.8.1 also use the new domain of the tldr-pages archive by default, so no action +is needed for users of those versions. + +#### Changes + +- [fixed] Update `ARCHIVE_URL` + +#### Notes to package maintainers + +I have _not_ updated the lockfile for any of these releases, so the locked +dependency versions are still the same as they were for the previous release in +the respective v1.x series. Updating the lockfile for tealdeer 1.5.0 to remove +any `cargo audit` warnings while also maintaining compatibility with Rust 1.54 +also brings larger changes through transitive dependencies, which contradicts my +plan to make this update easy to plug into existing build pipelines. + +If you want to build / distribute tealdeer v1.5.1, v1.6.2, or v1.7.3, please use +an up to date Rust toolchain to permit updates to newer versions of (transitive) +dependencies. Do not use the lockfile, instead update to the newest available +dependency versions. + +For the same reason, there are no artifacts attached to the GitHub releases of +these versions. + ### [v1.8.1][v1.8.1] (2025-11-11) This patch release tweaks the enabled features for ureq, the library we use to @@ -566,11 +606,14 @@ Thanks! [v1.4.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.3.0...v1.4.0 [v1.4.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.4.0...v1.4.1 [v1.5.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.4.1...v1.5.0 +[v1.5.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.5.0...v1.5.1 [v1.6.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.5.0...v1.6.0 [v1.6.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.0...v1.6.1 +[v1.6.2]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.6.2 [v1.7.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.6.1...v1.7.0 [v1.7.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.0...v1.7.1 [v1.7.2]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.1...v1.7.2 +[v1.7.3]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.2...v1.7.3 [v1.8.0]: https://github.com/tealdeer-rs/tealdeer/compare/v1.7.2...v1.8.0 [v1.8.1]: https://github.com/tealdeer-rs/tealdeer/compare/v1.8.0...v1.8.1 From 8b97afe7aa305feaff1a31e6364eae42aa30f439 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 25 Jan 2026 18:39:52 +0100 Subject: [PATCH 180/196] Add workflow_dispatch trigger for GitHub Pages workflow --- .github/workflows/gh-pages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f841705..f8b6f6e 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -3,6 +3,7 @@ on: push: tags: - "v[1-9]*" # push events matching `v` followed by anything larger than 0, e.g. v1.0, v20.15.10 + workflow_dispatch: jobs: deploy: From 593e9309b9a78dfbc5a1ad5db9d5982b817151be Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 20 Feb 2026 23:44:36 +0100 Subject: [PATCH 181/196] Placeholder escaping (#414) Closes #402 This adds special handling for escaped placeholders as required by the client spec. The added tests include examples from current pages that rely on this behavior. The text replacements use `str::replace` which constructs a new allocated `String`. I considered using a custom `replace_inplace` method on `&mut str` (which works if the replacement string is at most as long as the pattern to be replaced), but decided against it because I think that the performance improvement is not significant enough to justify adding `unsafe` code. It is also possible to avoid `unsafe` by re-checking UTF-8 validity after all modifications, but the code still felt a bit out of place for tealdeer. We can always add these optimizations later if we want to. --- src/formatter.rs | 361 ++++++++++++++++++++++++++++++++++++----------- src/output.rs | 4 +- 2 files changed, 278 insertions(+), 87 deletions(-) diff --git a/src/formatter.rs b/src/formatter.rs index 5270124..1b504dd 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -4,19 +4,52 @@ use log::debug; use crate::{extensions::FindFrom, types::LineType}; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Eq)] /// Represents a snippet from a page of a specific highlighting class. -pub enum PageSnippet<'a> { - CommandName(&'a str), - Variable(&'a str), - NormalCode(&'a str), - Description(&'a str), - Text(&'a str), - Title(&'a str), +pub enum PageSnippet { + CommandName(T), + Variable(T), + NormalCode(T), + Description(T), + Text(T), + Title(T), Linebreak, } -impl PageSnippet<'_> { +#[cfg_attr(not(test), allow(dead_code))] +impl PageSnippet { + pub fn map(self, f: F) -> PageSnippet + where + F: FnOnce(T) -> U, + { + match self { + PageSnippet::CommandName(s) => PageSnippet::CommandName(f(s)), + PageSnippet::Variable(s) => PageSnippet::Variable(f(s)), + PageSnippet::NormalCode(s) => PageSnippet::NormalCode(f(s)), + PageSnippet::Description(s) => PageSnippet::Description(f(s)), + PageSnippet::Text(s) => PageSnippet::Text(f(s)), + PageSnippet::Title(s) => PageSnippet::Title(f(s)), + PageSnippet::Linebreak => PageSnippet::Linebreak, + } + } +} + +impl, U> PartialEq> for PageSnippet { + fn eq(&self, other: &PageSnippet) -> bool { + match (self, other) { + (PageSnippet::CommandName(s), PageSnippet::CommandName(t)) + | (PageSnippet::Variable(s), PageSnippet::Variable(t)) + | (PageSnippet::NormalCode(s), PageSnippet::NormalCode(t)) + | (PageSnippet::Description(s), PageSnippet::Description(t)) + | (PageSnippet::Text(s), PageSnippet::Text(t)) + | (PageSnippet::Title(s), PageSnippet::Title(t)) => s == t, + (PageSnippet::Linebreak, PageSnippet::Linebreak) => true, + _ => false, + } + } +} + +impl PageSnippet<&str> { pub fn is_empty(&self) -> bool { use PageSnippet::*; @@ -38,7 +71,7 @@ pub fn highlight_lines( ) -> Result<(), E> where L: Iterator, - F: for<'snip> FnMut(PageSnippet<'snip>) -> Result<(), E>, + F: for<'snip> FnMut(PageSnippet<&'snip str>) -> Result<(), E>, { let mut command = String::new(); for line in lines { @@ -75,29 +108,82 @@ where Ok(()) } -/// Highlight code examples including user variables in {{ curly braces }}. -fn highlight_code<'a, E>( - command: &'a str, - text: &'a str, - process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>, +/// Highlight code examples. +/// - parse placeholders (`{{ curly braces }}`) +/// - replace escaped placeholder markers (`\{\{` and `\}\}`) +fn highlight_code( + command: &str, + mut text: &str, + process_snippet: &mut impl FnMut(PageSnippet<&str>) -> Result<(), E>, ) -> Result<(), E> { - let variable_splits = text - .split("}}") - .map(|s| s.split_once("{{").unwrap_or((s, ""))); - for (code_segment, variable) in variable_splits { - highlight_code_segment(command, code_segment, process_snippet)?; - process_snippet(PageSnippet::Variable(variable))?; + // We replace escaped placeholder markers at the end so that our replacing does not interfere + // with finding the actual markers. + // NOTE: This is not optimal, as it allocates one String for each `replace` + let replace_escaped = |s: &str| s.replace(r"\{\{", "{{").replace(r"\}\}", "}}"); + + loop { + // Find placeholder markers and split into code and placeholder accordingly + + let Some(start_marker) = find_marker(text, "{{", r"\{\{") else { + break; + }; + let Some(mut end_marker) = find_marker(&text[start_marker + 2..], "}}", r"\}\}") else { + break; + }; + end_marker += start_marker + 2; + + // Greedily extend matched range + while end_marker + 2 < text.len() && text.as_bytes()[end_marker + 2] == b'}' { + end_marker += 1; + } + + let placeholder_content = &text[start_marker + 2..end_marker]; + + if start_marker > 0 { + highlight_code_segment( + command, + &replace_escaped(&text[..start_marker]), + process_snippet, + )?; + } + process_snippet(PageSnippet::Variable(&replace_escaped(placeholder_content)))?; + + text = &text[end_marker + 2..]; } + + if !text.is_empty() { + highlight_code_segment(command, &replace_escaped(text), process_snippet)?; + } + Ok(()) } +/// Find a "{{" (or "}}") substring that does not overlap with a preceding "\{\{" (or "\}\}"). +fn find_marker(s: &str, marker: &str, forbidden_prefix: &str) -> Option { + let mut search_start = 0; + loop { + let marker_index = s.find_from(marker, search_start)?; + + let overlaps_with_prefix = (forbidden_prefix.len() <= marker_index + 1) && { + let prefix_start = marker_index + 1 - forbidden_prefix.len(); + &s[prefix_start..=marker_index] == forbidden_prefix + }; + if !overlaps_with_prefix { + return Some(marker_index); + } + + // The next valid marker cannot include the first character of the current match + search_start = marker_index + 1; + } +} + /// Yields `NormalCode` and `CommandName` in alternating order according to the occurrences of /// `command_name` in `segment`. Variables are not detected here, see `highlight_code` /// instead. fn highlight_code_segment<'a, E>( command_name: &'a str, mut segment: &'a str, - process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>, + process_snippet: &mut impl FnMut(PageSnippet<&'a str>) -> Result<(), E>, ) -> Result<(), E> { if !command_name.is_empty() { let mut search_start = 0; @@ -140,7 +226,6 @@ fn is_freestanding_substring(surrounding: &str, substring: (usize, usize)) -> bo #[cfg(test)] mod tests { use super::*; - use PageSnippet::*; #[test] fn test_is_freestanding_substring() { @@ -167,80 +252,186 @@ mod tests { )); } - fn run<'a>(cmd: &'a str, segment: &'a str) -> Vec> { + fn run<'a>(cmd: &'a str, segment: &'a str) -> Vec> { let mut yielded = Vec::new(); - let mut process_snippet = |snip: PageSnippet<'a>| { + let mut process_snippet = |snip: PageSnippet<&str>| { if !snip.is_empty() { - yielded.push(snip); + yielded.push(snip.map(str::to_string)); } Ok::<(), ()>(()) }; - highlight_code_segment(cmd, segment, &mut process_snippet) - .expect("highlight code segment failed"); + highlight_code(cmd, segment, &mut process_snippet).expect("highlight code segment failed"); yielded } - #[test] - fn test_highlight_code_segment() { - assert!(run("make", "").is_empty()); - assert_eq!( - &run("make", "make all CC=clang -q"), - &[CommandName("make"), NormalCode(" all CC=clang -q")] - ); - assert_eq!( - &run("make", " make money --always-make"), - &[ - NormalCode(" "), - CommandName("make"), - NormalCode(" money --always-make") - ] - ); - assert_eq!( - &run("git commit", "git commit -m 'git commit'"), - &[CommandName("git commit"), NormalCode(" -m 'git commit'"),] - ); + mod highlight_code_segment { + use super::*; + use PageSnippet::*; + + #[test] + fn test_highlight_code_segment() { + assert!(run("make", "").is_empty()); + assert_eq!( + &run("make", "make all CC=clang -q"), + &[CommandName("make"), NormalCode(" all CC=clang -q")] + ); + assert_eq!( + &run("make", " make money --always-make"), + &[ + NormalCode(" "), + CommandName("make"), + NormalCode(" money --always-make") + ] + ); + assert_eq!( + &run("git commit", "git commit -m 'git commit'"), + &[CommandName("git commit"), NormalCode(" -m 'git commit'"),] + ); + } + + #[test] + fn test_i18n() { + assert_eq!( + &run("mäke", "mäke höhlenrätselbücher"), + &[CommandName("mäke"), NormalCode(" höhlenrätselbücher")] + ); + assert_eq!( + &run( + "Müll", + "1000 Gründe warum Müll heute größer ist als Müll früher, ärgerlich" + ), + &[ + NormalCode("1000 Gründe warum "), + CommandName("Müll"), + NormalCode(" heute größer ist als "), + CommandName("Müll"), + NormalCode(" früher, ärgerlich") + ] + ); + assert_eq!( + &run( + "übergang", + "die Zustandsübergangsfunktion übergang Änderungen", + ), + &[ + NormalCode("die Zustandsübergangsfunktion "), + CommandName("übergang"), + NormalCode(" Änderungen") + ], + ); + } + + #[test] + fn test_empty_command() { + let segment = "some code"; + let snippets = [NormalCode(segment)]; + + assert_eq!(run("", segment), snippets); + assert_eq!(run(" ", segment), snippets); + assert_eq!(run(" \t ", segment), snippets); + } } - #[test] - fn test_i18n() { - assert_eq!( - &run("mäke", "mäke höhlenrätselbücher"), - &[CommandName("mäke"), NormalCode(" höhlenrätselbücher")] - ); - assert_eq!( - &run( - "Müll", - "1000 Gründe warum Müll heute größer ist als Müll früher, ärgerlich" - ), - &[ - NormalCode("1000 Gründe warum "), - CommandName("Müll"), - NormalCode(" heute größer ist als "), - CommandName("Müll"), - NormalCode(" früher, ärgerlich") - ] - ); - assert_eq!( - &run( - "übergang", - "die Zustandsübergangsfunktion übergang Änderungen", - ), - &[ - NormalCode("die Zustandsübergangsfunktion "), - CommandName("übergang"), - NormalCode(" Änderungen") - ], - ); - } + mod placeholders { + use super::*; + use PageSnippet::*; - #[test] - fn test_empty_command() { - let segment = "some code"; - let snippets = [NormalCode(segment)]; + #[test] + fn variable_vs_escaped() { + assert_eq!( + run("ping", "ping {{example.com}}"), + [ + CommandName("ping"), + NormalCode(" "), + Variable("example.com"), + ], + ); + assert_eq!( + run( + "docker inspect", + r"docker inspect --format '\{\{range.NetworkSettings.Networks\}\}\{\{.IPAddress\}\}\{\{end\}\}' {{container}}" + ), + [ + CommandName("docker inspect"), + NormalCode( + " --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' " + ), + Variable("container"), + ], + ); + assert_eq!( + run("mount", r"mount \\{{computer_name}}\{{share_name}} Z:"), + [ + CommandName("mount"), + NormalCode(r" \\"), + Variable("computer_name"), + NormalCode(r"\"), + Variable("share_name"), + NormalCode(" Z:"), + ], + ); - assert_eq!(run("", segment), snippets); - assert_eq!(run(" ", segment), snippets); - assert_eq!(run(" \t ", segment), snippets); + assert_eq!(run("", r"\{"), [NormalCode(r"\{")]); + assert_eq!(run("", r"\{{a"), [NormalCode(r"\{{a")]); + assert_eq!(run("", r"\{{a}}"), [NormalCode(r"\"), Variable("a")]); + + // Placeholder has begin marker, but no end marker + assert_eq!(run("", r"{{\}\}}"), [NormalCode("{{}}}")]); + } + + #[test] + fn outer_precedence() { + assert_eq!( + run("git stash", "git stash show --patch {{stash@{0}}}"), + [ + CommandName("git stash"), + NormalCode(" show --patch "), + Variable("stash@{0}"), + ], + ); + + // The following is not listed in the specification, but this is the highlighting I would expect. + assert_eq!( + run("rg", "rg {{}}}"), + [CommandName("rg"), NormalCode(" "), Variable("}")] + ); + + // And these are just to document the current behavior + assert_eq!(run("", "{{{}}}"), [Variable("{}")]); + assert_eq!(run("", "{{{{}}}"), [Variable("{{}")]); + assert_eq!(run("", "{{{}}}}"), [Variable("{}}")]); + } + + #[test] + fn escaped_inside_placeholder() { + assert_eq!( + run( + "playerctl", + r#"playerctl metadata {{[-f|--format]}} "{{Now playing: \{\{artist\}\} - \{\{album\}\} - \{\{title\}\}}}""# + ), + [ + CommandName("playerctl"), + NormalCode(" metadata "), + Variable("[-f|--format]"), + NormalCode(" \""), + Variable("Now playing: {{artist}} - {{album}} - {{title}}"), + NormalCode("\""), + ], + ); + } + + #[test] + fn placeholder_inside_escaped() { + assert_eq!( + run("test", r#"test \{\{{{var}} normal\}\}"#), + [ + CommandName("test"), + NormalCode(" {{"), + Variable("var"), + NormalCode(" normal}}"), + ], + ); + } } } diff --git a/src/output.rs b/src/output.rs index 5f1aeae..927d20e 100644 --- a/src/output.rs +++ b/src/output.rs @@ -56,7 +56,7 @@ pub fn print_page( } } else { // Closure that processes a page snippet and writes it to stdout - let mut process_snippet = |snip: PageSnippet<'_>| { + let mut process_snippet = |snip: PageSnippet<&str>| { if snip.is_empty() { Ok(()) } else { @@ -82,7 +82,7 @@ pub fn print_page( fn print_snippet( writer: &mut impl Write, - snip: PageSnippet<'_>, + snip: PageSnippet<&str>, style: &StyleConfig, ) -> io::Result<()> { use PageSnippet::*; From 47a936e7363ca2afd6a8513862cceccf044d6bf8 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sat, 21 Feb 2026 00:32:23 +0100 Subject: [PATCH 182/196] Suggest trying different TLS backend when update fails (#465) Closes #453 - Add note about changing tls_backend setting - impl Display for TlsBackend - Remove trailing slash in default archive source to make URL in error look nicer --- src/config.rs | 31 +++++++++++++++++++++++++++++-- src/main.rs | 32 +++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index e5e85e8..2c39235 100644 --- a/src/config.rs +++ b/src/config.rs @@ -31,6 +31,14 @@ const SUPPORTED_TLS_BACKENDS: &[RawTlsBackend] = &[ RawTlsBackend::RustlsWithNativeRoots, ]; +pub(crate) fn supported_tls_backends_string() -> String { + SUPPORTED_TLS_BACKENDS + .iter() + .map(std::string::ToString::to_string) + .collect::>() + .join(", ") +} + fn default_underline() -> bool { false } @@ -184,7 +192,7 @@ const fn default_auto_update_interval_hours() -> u64 { } fn default_archive_source() -> String { - "https://github.com/tldr-pages/tldr/releases/latest/download/".to_owned() + "https://github.com/tldr-pages/tldr/releases/latest/download".to_owned() } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -460,12 +468,31 @@ impl TryFrom for TlsBackend { _ => Err(anyhow!( "Unsupported TLS backend: {}. This tealdeer build has support for the following options: {}", raw, - SUPPORTED_TLS_BACKENDS.iter().map(std::string::ToString::to_string).collect::>().join(", ") + supported_tls_backends_string(), )) } } } +impl TlsBackend { + const fn as_raw(self) -> RawTlsBackend { + match self { + #[cfg(feature = "native-tls")] + Self::NativeTls => RawTlsBackend::NativeTls, + #[cfg(feature = "rustls-with-webpki-roots")] + Self::RustlsWithWebpkiRoots => RawTlsBackend::RustlsWithWebpkiRoots, + #[cfg(feature = "rustls-with-native-roots")] + Self::RustlsWithNativeRoots => RawTlsBackend::RustlsWithNativeRoots, + } + } +} + +impl fmt::Display for TlsBackend { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_raw().fmt(f) + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct Config<'a> { pub style: StyleConfig, diff --git a/src/main.rs b/src/main.rs index a0cd593..1d1b5fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,9 @@ mod utils; use crate::{ cache::{Cache, PageLookupResult, TLDR_PAGES_DIR}, cli::Cli, - config::{get_config_dir, make_default_config, Config, PathWithSource}, + config::{ + get_config_dir, make_default_config, supported_tls_backends_string, Config, PathWithSource, + }, output::print_page, types::ColorOptions, utils::{print_error, print_warning}, @@ -305,12 +307,36 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { let cache = if args.update || config.updates.auto_update && !args.no_auto_update { let (mut cache, was_created) = Cache::open_or_create(cache_config)?; if was_created || args.update || cache.age()? >= config.updates.auto_update_interval { - update_cache( + let result = update_cache( &mut cache, config.updates.archive_source, config.updates.tls_backend, args.quiet, - )?; + ); + + if let Err(e) = result { + print_error(enable_styles, &e); + + eprintln!(); + eprintln!("Note: Update errors are often caused by unexpected or missing TLS certificates."); + eprintln!( + "You are currently using the following TLS backend: {}", + config.updates.tls_backend, + ); + eprintln!( + "Try changing the updates.tls_backend setting in the config file, for example:" + ); + eprintln!(); + eprintln!(" [updates]"); + eprintln!(" tls_backend = \"rustls-with-native-roots\""); + eprintln!(); + eprintln!( + "This build of tealdeer has support for the following options: {}", + supported_tls_backends_string(), + ); + + return Ok(ExitCode::FAILURE); + } } cache From 41739c5bf9599d71f6ee1d35f0dab4a4e8ce580c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 14:52:53 +0100 Subject: [PATCH 183/196] Bump actions/upload-artifact from 6 to 7 (#468) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.

Release notes

Sourced from actions/upload-artifact's releases.

v7.0.0

v7 What's new

Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can set the new archive parameter to false to skip zipping the file during upload. Right now, we only support single files. The action will fail if the glob passed resolves to multiple files. The name parameter is also ignored with this setting. Instead, the name of the artifact will be the name of the uploaded file.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

New Contributors

Full Changelog: https://github.com/actions/upload-artifact/compare/v6...v7.0.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0b20ce..a17ba90 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: # expects runners have the proper Native SSL library cargo build --features native-tls --no-default-features cp target/debug/tldr${{ matrix.exe_suffix}} artifacts/tldr-native-tls${{ matrix.exe_suffix}} - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: tldr-debug-build-${{ matrix.platform }}-rust-${{ matrix.toolchain }} path: artifacts/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9813f00..316208e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,7 +73,7 @@ jobs: run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" @@ -94,7 +94,7 @@ jobs: targets: "${{ matrix.arch }}-apple-darwin" - name: Build run: cargo build --release --target ${{ matrix.arch }}-apple-darwin - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: "tealdeer-macos-${{ matrix.arch }}" path: "target/${{ matrix.arch }}-apple-darwin/release/tldr" @@ -109,7 +109,7 @@ jobs: toolchain: stable - name: Build run: cargo build --release --target x86_64-pc-windows-msvc - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: "tealdeer-windows-x86_64-msvc" path: "target/x86_64-pc-windows-msvc/release/tldr.exe" From 6f91c3a765513c1030723e2ab96a8c6d5ea1dca0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 14:53:06 +0100 Subject: [PATCH 184/196] Bump actions/download-artifact from 7 to 8 (#469) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
Release notes

Sourced from actions/download-artifact's releases.

v8.0.0

v8 - What's new

Direct downloads

To support direct uploads in actions/upload-artifact, the action will no longer attempt to unzip all downloaded files. Instead, the action checks the Content-Type header ahead of unzipping and skips non-zipped files. Callers wishing to download a zipped file as-is can also set the new skip-decompress parameter to false.

Enforced checks (breaking)

A previous release introduced digest checks on the download. If a download hash didn't match the expected hash from the server, the action would log a warning. Callers can now configure the behavior on mismatch with the digest-mismatch parameter. To be secure by default, we are now defaulting the behavior to error which will fail the workflow run.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

Full Changelog: https://github.com/actions/download-artifact/compare/v7...v8.0.0

Commits
  • 70fc10c Merge pull request #461 from actions/danwkennedy/digest-mismatch-behavior
  • f258da9 Add change docs
  • ccc058e Fix linting issues
  • bd7976b Add a setting to specify what to do on hash mismatch and default it to error
  • ac21fcf Merge pull request #460 from actions/danwkennedy/download-no-unzip
  • 15999bf Add note about package bumps
  • 974686e Bump the version to v8 and add release notes
  • fbe48b1 Update test names to make it clearer what they do
  • 96bf374 One more test fix
  • b8c4819 Fix skip decompress test
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=7&new-version=8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 316208e..41de665 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -135,7 +135,7 @@ jobs: - windows-x86_64-msvc steps: - uses: actions/checkout@v6 - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | From b19517097ae0a5f9015794030b782ae9fd54535c Mon Sep 17 00:00:00 2001 From: Pavel Timofeev Date: Mon, 13 Apr 2026 18:31:31 -0400 Subject: [PATCH 185/196] Add builtin `tldr tealdeer` page (#472) Fixes #218. --- docs/src/usage.txt | 2 ++ pages/tealdeer.md | 42 ++++++++++++++++++++++++++++++++++++++++++ src/cache.rs | 10 +++++----- src/cli.rs | 4 +++- src/main.rs | 29 ++++++++++++++++++++++++----- src/output.rs | 8 +++----- tests/lib.rs | 10 ++++++++++ 7 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 pages/tealdeer.md diff --git a/docs/src/usage.txt b/docs/src/usage.txt index f7fcc46..6a04de7 100644 --- a/docs/src/usage.txt +++ b/docs/src/usage.txt @@ -29,3 +29,5 @@ Options: -h, --help Print help To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/. + +To view usage examples, run tldr tldr or tldr tealdeer. diff --git a/pages/tealdeer.md b/pages/tealdeer.md new file mode 100644 index 0000000..948b278 --- /dev/null +++ b/pages/tealdeer.md @@ -0,0 +1,42 @@ +# tldr + +> This is a builtin page that shows information for your installed tealdeer version. +> More information: . + +> This page shows tealdeer specific functionality. See tldr tldr for more examples. + +- Render a local markdown file as a tldr page: + +`tldr --render {{path/to/file.md}}` + +- Show the raw markdown source of a page instead of rendering it: + +`tldr --raw {{command}}` + +- Show file and directory paths used by tealdeer: + +`tldr --show-paths` + +- Create an initial config file: + +`tldr --seed-config` + +- Override config file location: + +`tldr --config-path ` + +- Open a custom page for a command in `$EDITOR` (creates it if it doesn't exist): + +`tldr --edit-page {{command}}` + +- Open a custom patch for a command in `$EDITOR` (appended to the existing page): + +`tldr --edit-patch {{command}}` + +- Clear the local cache: + +`tldr --clear-cache` + +- If auto update is configured, disable it for this run: + +`tldr --no-auto-update` diff --git a/src/cache.rs b/src/cache.rs index b181310..a77036d 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,6 +1,6 @@ use std::{ fs::{self, File}, - io::{BufReader, Cursor, ErrorKind, Read}, + io::{Cursor, ErrorKind, Read}, path::{Path, PathBuf}, time::{Duration, SystemTime}, }; @@ -277,12 +277,12 @@ impl PageLookupResult { self } - /// Create a buffered reader that sequentially reads from the page and the + /// Create a reader that sequentially reads from the page and the /// patch, as if they were concatenated. /// /// This will return an error if either the page file or the patch file /// cannot be opened. - pub fn reader(&self) -> Result>> { + pub fn reader(&self) -> Result> { // Open page file let page_file = File::open(&self.page_path) .with_context(|| format!("Could not open page file at {}", self.page_path.display()))?; @@ -302,11 +302,11 @@ impl PageLookupResult { // the page and patch files and that will read them sequentially, // because it avoids the boxing below. However, the performance impact // would first need to be shown to be significant using a benchmark. - Ok(BufReader::new(if let Some(patch_file) = patch_file_opt { + Ok(if let Some(patch_file) = patch_file_opt { Box::new(page_file.chain(&b"\n"[..]).chain(patch_file)) as Box } else { Box::new(page_file) as Box - })) + }) } } diff --git a/src/cli.rs b/src/cli.rs index d461a3e..161d69d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -18,7 +18,9 @@ use crate::types::{ColorOptions, PlatformType}; {usage-heading} {usage} {all-args}{after-help}", - after_help = "To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.", + after_help = "To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/. + +To view usage examples, run tldr tldr or tldr tealdeer.", arg_required_else_help = true, help_expected = true, group = ArgGroup::new("command_or_file").args(&["command", "render"]), diff --git a/src/main.rs b/src/main.rs index 1d1b5fc..5b12613 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,6 +68,8 @@ const APP_INFO: AppInfo = AppInfo { name: NAME, author: NAME, }; +static TEALDEER_PAGE: &str = + include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/pages/tealdeer.md")); /// Clear the cache fn clear_cache(cache: Cache, quietly: bool) -> Result<()> { @@ -258,8 +260,20 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { // If a local file was passed in, render it and exit if let Some(file) = args.render { - let path = PageLookupResult::with_page(file); - print_page(&path, args.raw, enable_styles, args.pager, &config)?; + let reader = PageLookupResult::with_page(file).reader()?; + print_page(reader, args.raw, enable_styles, args.pager, &config)?; + return Ok(ExitCode::SUCCESS); + } + + // The tealdeer page is embedded in the binary, no cache needed + if command == "tealdeer" { + print_page( + TEALDEER_PAGE.as_bytes(), + args.raw, + enable_styles, + args.pager, + &config, + )?; return Ok(ExitCode::SUCCESS); } @@ -407,7 +421,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { ); } - let Some(lookup_result) = cache.find_page(&command) else { + let Some(result) = cache.find_page(&command) else { if !args.quiet { print_warning( enable_styles, @@ -419,11 +433,16 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { ), ); } - return Ok(ExitCode::FAILURE); }; - print_page(&lookup_result, args.raw, enable_styles, args.pager, &config)?; + print_page( + result.reader()?, + args.raw, + enable_styles, + args.pager, + &config, + )?; } Ok(ExitCode::SUCCESS) diff --git a/src/output.rs b/src/output.rs index 927d20e..9305c20 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,12 +1,11 @@ //! Functions for printing pages to the terminal -use std::io::{self, BufRead, Write}; +use std::io::{self, BufRead, BufReader, Read, Write}; use anyhow::{Context, Result}; use yansi::Paint; use crate::{ - cache::PageLookupResult, config::{Config, StyleConfig}, formatter::{highlight_lines, PageSnippet}, line_iterator::LineIterator, @@ -30,14 +29,13 @@ fn configure_pager(enable_styles: bool) { /// Print page by path pub fn print_page( - lookup_result: &PageLookupResult, + reader: impl Read, enable_markdown: bool, enable_styles: bool, use_pager: bool, config: &Config, ) -> Result<()> { - // Create reader from file(s) - let reader = lookup_result.reader()?; + let reader = BufReader::new(reader); // Configure pager if applicable if use_pager || config.display.use_pager { diff --git a/tests/lib.rs b/tests/lib.rs index cb987db..40cb7e9 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -301,6 +301,16 @@ fn test_missing_cache() { .stderr(contains("Page cache not found. Please run `tldr --update`")); } +#[test] +fn test_tealdeer_page_works_without_cache() { + TestEnv::new() + .command() + .args(["tealdeer"]) + .assert() + .success() + .stdout(contains("for your installed tealdeer version")); +} + #[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_update_cache_default_features() { From b8f7c0cc2d96a5d2c6be4c374b4893285bbf6e39 Mon Sep 17 00:00:00 2001 From: Pavel Timofeev Date: Fri, 17 Apr 2026 15:59:34 -0400 Subject: [PATCH 186/196] Add `display.indent` config option (#471) Fixes #394. --- docs/src/config_display.md | 32 ++++++++++++++++ src/config.rs | 38 +++++++++++++++++++ src/formatter.rs | 21 ++++++++-- src/output.rs | 7 ++-- tests/lib.rs | 18 +++++++++ tests/rendered/apt.ja.expected | 16 ++++---- .../inkscape-compact-no-color.expected | 32 ++++++++++++++++ tests/rendered/inkscape-default.expected | 14 +++---- tests/rendered/inkscape-with-config.expected | 14 +++---- tests/rendered/inkscape-with-title.expected | 16 ++++---- 10 files changed, 171 insertions(+), 37 deletions(-) create mode 100644 tests/rendered/inkscape-compact-no-color.expected diff --git a/docs/src/config_display.md b/docs/src/config_display.md index 78656a4..007d64b 100644 --- a/docs/src/config_display.md +++ b/docs/src/config_display.md @@ -37,3 +37,35 @@ show_title = true When enabled, the command name will be displayed at the top of the output, styled with the `command_name` style configuration. + +## `indent` + +Controls the indentation of the output via two sub-keys. + +### `indent.base` + +Specifies the number of spaces used to indent descriptions, example text, and titles (default `2`). + +```toml +[display.indent] +base = 2 +``` + +### `indent.command` + +Specifies the number of spaces used to indent example code lines (default `6`). + +```toml +[display.indent] +command = 6 +``` + +You can also configure both subkeys in a single line like this: + +```toml +[display] +indent = { + base = 2, + command = 6, +} +``` diff --git a/src/config.rs b/src/config.rs index 2c39235..b31f422 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,6 +43,14 @@ fn default_underline() -> bool { false } +const fn default_base_indent() -> usize { + 2 +} + +const fn default_command_indent() -> usize { + 6 +} + fn default_bold() -> bool { false } @@ -171,6 +179,25 @@ struct RawDisplayConfig { pub use_pager: bool, #[serde(default)] pub show_title: bool, + #[serde(default)] + pub indent: RawIndent, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +struct RawIndent { + #[serde(default = "default_base_indent")] + base: usize, + #[serde(default = "default_command_indent")] + command: usize, +} + +impl Default for RawIndent { + fn default() -> Self { + Self { + base: 2, + command: 6, + } + } } impl From<&RawDisplayConfig> for DisplayConfig { @@ -179,6 +206,10 @@ impl From<&RawDisplayConfig> for DisplayConfig { compact: raw_display_config.compact, use_pager: raw_display_config.use_pager, show_title: raw_display_config.show_title, + indent: Indent { + base: raw_display_config.indent.base, + command: raw_display_config.indent.command, + }, } } } @@ -331,6 +362,13 @@ pub struct DisplayConfig { pub compact: bool, pub use_pager: bool, pub show_title: bool, + pub indent: Indent, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct Indent { + pub base: usize, + pub command: usize, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/formatter.rs b/src/formatter.rs index 1b504dd..1cdc681 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -2,7 +2,7 @@ use log::debug; -use crate::{extensions::FindFrom, types::LineType}; +use crate::{config::Indent, extensions::FindFrom, types::LineType}; #[derive(Debug, Clone, Copy, Eq)] /// Represents a snippet from a page of a specific highlighting class. @@ -68,11 +68,14 @@ pub fn highlight_lines( process_snippet: &mut F, keep_empty_lines: bool, show_title: bool, + indent: Indent, ) -> Result<(), E> where L: Iterator, F: for<'snip> FnMut(PageSnippet<&'snip str>) -> Result<(), E>, { + let base_indent = " ".repeat(indent.base); + let command_indent = " ".repeat(indent.command); let mut command = String::new(); for line in lines { match line { @@ -84,7 +87,9 @@ where LineType::Title(title) => { if show_title { process_snippet(PageSnippet::Linebreak)?; + process_snippet(PageSnippet::Title(&base_indent))?; process_snippet(PageSnippet::Title(&title))?; + process_snippet(PageSnippet::Linebreak)?; } else { debug!("Ignoring title"); } @@ -93,10 +98,18 @@ where command = title; debug!("Detected command name: {}", &command); } - LineType::Description(text) => process_snippet(PageSnippet::Description(&text))?, - LineType::ExampleText(text) => process_snippet(PageSnippet::Text(&text))?, + LineType::Description(text) => { + process_snippet(PageSnippet::Description(&base_indent))?; + process_snippet(PageSnippet::Description(&text))?; + process_snippet(PageSnippet::Linebreak)?; + } + LineType::ExampleText(text) => { + process_snippet(PageSnippet::Text(&base_indent))?; + process_snippet(PageSnippet::Text(&text))?; + process_snippet(PageSnippet::Linebreak)?; + } LineType::ExampleCode(text) => { - process_snippet(PageSnippet::NormalCode(" "))?; + process_snippet(PageSnippet::NormalCode(&command_indent))?; highlight_code(&command, &text, process_snippet)?; process_snippet(PageSnippet::Linebreak)?; } diff --git a/src/output.rs b/src/output.rs index 9305c20..117ed1e 100644 --- a/src/output.rs +++ b/src/output.rs @@ -68,6 +68,7 @@ pub fn print_page( &mut process_snippet, !config.display.compact, config.display.show_title, + config.display.indent, ) .context("Could not write to stdout")?; } @@ -89,9 +90,9 @@ fn print_snippet( CommandName(s) => write!(writer, "{}", s.paint(style.command_name)), Variable(s) => write!(writer, "{}", s.paint(style.example_variable)), NormalCode(s) => write!(writer, "{}", s.paint(style.example_code)), - Description(s) => writeln!(writer, " {}", s.paint(style.description)), - Text(s) => writeln!(writer, " {}", s.paint(style.example_text)), - Title(s) => writeln!(writer, " {}", s.paint(style.command_name)), + Description(s) => write!(writer, "{}", s.paint(style.description)), + Text(s) => write!(writer, "{}", s.paint(style.example_text)), + Title(s) => write!(writer, "{}", s.paint(style.command_name)), Linebreak => writeln!(writer), } } diff --git a/tests/lib.rs b/tests/lib.rs index 40cb7e9..acdd048 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -821,6 +821,24 @@ fn test_rendering_color_never() { ); } +/// An end-to-end integration test for the indent config option +#[test] +fn test_rendering_with_indentation() { + let testenv = TestEnv::new().install_default_cache(); + let expected_custom_indentation = include_str!("rendered/inkscape-compact-no-color.expected"); + + // Configure to set base and command indents + testenv.append_to_config("display.indent.base = 3\n"); + testenv.append_to_config("display.indent.command = 1\n"); + + testenv + .command() + .args(["--color", "never", "inkscape-v2"]) + .assert() + .success() + .stdout(diff(expected_custom_indentation)); +} + #[test] fn test_rendering_i18n() { _test_correct_rendering( diff --git a/tests/rendered/apt.ja.expected b/tests/rendered/apt.ja.expected index 22424e3..efdd35d 100644 --- a/tests/rendered/apt.ja.expected +++ b/tests/rendered/apt.ja.expected @@ -3,35 +3,35 @@ Ubuntuのバージョンが16.04か、それ以降で対話モードを使う場合`apt-get`の代わりとして使用します。 詳しくはこちら: - 利用可能なパーケージとバージョンのリストの更新(他の`apt`コマンドの前での実行を推奨): + 利用可能なパーケージとバージョンのリストの更新(他の`apt`コマンドの前での実行を推奨):  sudo apt update - 指定されたパッケージの検索: + 指定されたパッケージの検索:  apt search パッケージ - パッケージの情報を出力: + パッケージの情報を出力:  apt show パッケージ - パッケージのインストール、または利用可能な最新バージョンに更新: + パッケージのインストール、または利用可能な最新バージョンに更新:  sudo apt install パッケージ - パッケージの削除(`sudo apt remove --purge`の場合設定ファイルも削除): + パッケージの削除(`sudo apt remove --purge`の場合設定ファイルも削除):  sudo apt remove パッケージ - インストールされている全てのパッケージを最新のバージョンにアップグレード: + インストールされている全てのパッケージを最新のバージョンにアップグレード:  sudo apt upgrade - インストールできるすべてのパッケージを表示: + インストールできるすべてのパッケージを表示:  apt list - インストールされた全てのパッケージを表示(依存関係も表示): + インストールされた全てのパッケージを表示(依存関係も表示):  apt list --installed diff --git a/tests/rendered/inkscape-compact-no-color.expected b/tests/rendered/inkscape-compact-no-color.expected new file mode 100644 index 0000000..473bbe9 --- /dev/null +++ b/tests/rendered/inkscape-compact-no-color.expected @@ -0,0 +1,32 @@ + + An SVG (Scalable Vector Graphics) editing program. + Use -z to not open the GUI and only process files in the console. + + Open an SVG file in the Inkscape GUI: + + inkscape filename.svg + + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + + inkscape filename.svg -e filename.png + + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + + inkscape filename.svg -e filename.png -w 600 -h 400 + + Export a single object, given its ID, into a bitmap: + + inkscape filename.svg -i id -e object.png + + Export an SVG document to PDF, converting all texts to paths: + + inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path + + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + + inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit + + Some invalid command just to test the correct highlighting of the command name: + + inkscape --use-inkscape=v3.0 file + diff --git a/tests/rendered/inkscape-default.expected b/tests/rendered/inkscape-default.expected index da909f2..3b37f0e 100644 --- a/tests/rendered/inkscape-default.expected +++ b/tests/rendered/inkscape-default.expected @@ -2,31 +2,31 @@ An SVG (Scalable Vector Graphics) editing program. Use -z to not open the GUI and only process files in the console. - Open an SVG file in the Inkscape GUI: + Open an SVG file in the Inkscape GUI:  inkscape filename.svg - Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI):  inkscape filename.svg -e filename.png - Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur):  inkscape filename.svg -e filename.png -w 600 -h 400 - Export a single object, given its ID, into a bitmap: + Export a single object, given its ID, into a bitmap:  inkscape filename.svg -i id -e object.png - Export an SVG document to PDF, converting all texts to paths: + Export an SVG document to PDF, converting all texts to paths:  inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path - Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape:  inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit - Some invalid command just to test the correct highlighting of the command name: + Some invalid command just to test the correct highlighting of the command name:  inkscape --use-inkscape=v3.0 file diff --git a/tests/rendered/inkscape-with-config.expected b/tests/rendered/inkscape-with-config.expected index e79b219..33540a3 100644 --- a/tests/rendered/inkscape-with-config.expected +++ b/tests/rendered/inkscape-with-config.expected @@ -2,31 +2,31 @@ An SVG (Scalable Vector Graphics) editing program. Use -z to not open the GUI and only process files in the console. - Open an SVG file in the Inkscape GUI: + Open an SVG file in the Inkscape GUI: inkscape filename.svg - Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): inkscape filename.svg -e filename.png - Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): inkscape filename.svg -e filename.png -w 600 -h 400 - Export a single object, given its ID, into a bitmap: + Export a single object, given its ID, into a bitmap: inkscape filename.svg -i id -e object.png - Export an SVG document to PDF, converting all texts to paths: + Export an SVG document to PDF, converting all texts to paths: inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path - Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit - Some invalid command just to test the correct highlighting of the command name: + Some invalid command just to test the correct highlighting of the command name: inkscape --use-inkscape=v3.0 file diff --git a/tests/rendered/inkscape-with-title.expected b/tests/rendered/inkscape-with-title.expected index 7e7d428..ff2de4a 100644 --- a/tests/rendered/inkscape-with-title.expected +++ b/tests/rendered/inkscape-with-title.expected @@ -1,34 +1,34 @@ - inkscape + inkscape An SVG (Scalable Vector Graphics) editing program. Use -z to not open the GUI and only process files in the console. - Open an SVG file in the Inkscape GUI: + Open an SVG file in the Inkscape GUI:  inkscape filename.svg - Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI): + Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI):  inkscape filename.svg -e filename.png - Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur): + Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur):  inkscape filename.svg -e filename.png -w 600 -h 400 - Export a single object, given its ID, into a bitmap: + Export a single object, given its ID, into a bitmap:  inkscape filename.svg -i id -e object.png - Export an SVG document to PDF, converting all texts to paths: + Export an SVG document to PDF, converting all texts to paths:  inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path - Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape: + Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape:  inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit - Some invalid command just to test the correct highlighting of the command name: + Some invalid command just to test the correct highlighting of the command name:  inkscape --use-inkscape=v3.0 file From 6c65c8f71c7e062507abee4fee8d3773c3f6aa68 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 17 Apr 2026 22:01:45 +0200 Subject: [PATCH 187/196] Fix off-boundary string access in formatter (#474) Closes #473 This regression was introduced in 593e9309b9a78dfbc5a1ad5db9d5982b817151be (#414) and leads to a panic when trying to display pages where characters line up like in the issue or the test. I checked other places and found that a similar panic could occur when parsing language strings, so I added code to ignore them instead. - Add regression test - Fix prefix check - Skip non-ASCII locales --- src/config.rs | 6 ++++++ src/formatter.rs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index b31f422..7c29ed4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ use std::{ use anyhow::{anyhow, bail, ensure, Context, Result}; use app_dirs::{get_app_root, AppDataType}; use clap::ValueEnum; +use log::info; use serde::Serialize as _; use serde_derive::{Deserialize, Serialize}; use yansi::{Color, Style}; @@ -429,6 +430,11 @@ fn get_languages<'a>( let mut lang_list = Vec::new(); for locale in locales { + if !locale.is_ascii() { + info!("Skipping non-ASCII locale string: {}", locale); + continue; + } + // Language plus country code (e.g. `en_US`) if locale.len() >= 5 && locale.chars().nth(2) == Some('_') { lang_list.push(Language(&locale[..5])); diff --git a/src/formatter.rs b/src/formatter.rs index 1cdc681..c0d3a91 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -179,7 +179,11 @@ fn find_marker(s: &str, marker: &str, forbidden_prefix: &str) -> Option { let overlaps_with_prefix = (forbidden_prefix.len() <= marker_index + 1) && { let prefix_start = marker_index + 1 - forbidden_prefix.len(); - &s[prefix_start..=marker_index] == forbidden_prefix + // NOTE: The indices might not be valid character offsets, so we should do this + // comparison on raw bytes. If prefix_start is indeed not a character offset than the + // comparison is guaranteed to return false because forbidden_prefix[0] definitely _is_ + // the start of a (single byte, ASCII) character. + &s.as_bytes()[prefix_start..=marker_index] == forbidden_prefix.as_bytes() }; if !overlaps_with_prefix { return Some(marker_index); @@ -446,5 +450,12 @@ mod tests { ], ); } + + #[test] + /// Regression test for https://github.com/tealdeer-rs/tealdeer/issues/473 + fn prefix_check_character_boundary() { + assert_eq!("Ä".len(), 2); + assert_eq!(run("", r#"Äxx{{x}}"#), [NormalCode("Äxx"), Variable("x")],); + } } } From 24e7f383b8ada277c2ab6ac5c954263daab38679 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Fri, 17 Apr 2026 22:08:42 +0200 Subject: [PATCH 188/196] Fix Rust 1.95 clippy lints --- src/cache.rs | 2 +- src/config.rs | 2 +- src/formatter.rs | 6 ++---- src/main.rs | 1 + src/output.rs | 3 +-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index a77036d..afa3603 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -369,7 +369,7 @@ impl Cache<'_> { } Ok(response) if response.status() == StatusCode::NOT_FOUND => Ok(None), _ => { - bail!("Could not download tldr pages from {archive_url}: {response:?}",) + bail!("Could not download tldr pages from {archive_url}: {response:?}") } } } diff --git a/src/config.rs b/src/config.rs index 7c29ed4..212c1e2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -431,7 +431,7 @@ fn get_languages<'a>( let mut lang_list = Vec::new(); for locale in locales { if !locale.is_ascii() { - info!("Skipping non-ASCII locale string: {}", locale); + info!("Skipping non-ASCII locale string: {locale}"); continue; } diff --git a/src/formatter.rs b/src/formatter.rs index c0d3a91..b2d6b8e 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -230,13 +230,11 @@ fn is_freestanding_substring(surrounding: &str, substring: (usize, usize)) -> bo let char_before_is_okay = surrounding[..start] .chars() .last() - .filter(|prev_char| !prev_char.is_whitespace()) - .is_none(); + .is_none_or(char::is_whitespace); let char_after_is_okay = surrounding[end..] .chars() .next() - .filter(|next_char| !next_char.is_whitespace()) - .is_none(); + .is_none_or(char::is_whitespace); char_before_is_okay && char_after_is_okay } diff --git a/src/main.rs b/src/main.rs index 5b12613..29dad95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_lines)] #![allow(clippy::unnecessary_debug_formatting)] +#![allow(clippy::while_let_loop)] #[cfg(not(any( feature = "native-tls", diff --git a/src/output.rs b/src/output.rs index 117ed1e..6243b44 100644 --- a/src/output.rs +++ b/src/output.rs @@ -87,12 +87,11 @@ fn print_snippet( use PageSnippet::*; match snip { - CommandName(s) => write!(writer, "{}", s.paint(style.command_name)), + CommandName(s) | Title(s) => write!(writer, "{}", s.paint(style.command_name)), Variable(s) => write!(writer, "{}", s.paint(style.example_variable)), NormalCode(s) => write!(writer, "{}", s.paint(style.example_code)), Description(s) => write!(writer, "{}", s.paint(style.description)), Text(s) => write!(writer, "{}", s.paint(style.example_text)), - Title(s) => write!(writer, "{}", s.paint(style.command_name)), Linebreak => writeln!(writer), } } From 1252261d662fcedecce229f08bf23277da8bf51e Mon Sep 17 00:00:00 2001 From: Ellis Clayton Date: Mon, 4 May 2026 05:47:29 +1000 Subject: [PATCH 189/196] Support tilde (`~`) expansion on config paths (#476) Allows directories in the configuration file (cache & custom pages) to be relative to the user's home directory by expanding the common `~` path prefix notation. Works for the current user only (`~diferentUser/` syntax is not supported, and will cause an error if attempted). Works for Linux/Unix (via `HOME` env var) and Windows (via `USERPROFILE` env var). Examples (assuming a user called "foo" on a Linux system): ``` ~/my/custom-pages # /home/foo/custom-pages ~ # /home/foo ~bar/cache # error ``` --- src/config.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 212c1e2..89c5d8f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,9 @@ use std::{ + borrow::Cow, env, fmt, fs::{self, File}, io::{ErrorKind, Write}, - path::{Path, PathBuf}, + path::{Component, Path, PathBuf}, sync::LazyLock, time::Duration, }; @@ -574,6 +575,7 @@ impl<'a> Config<'a> { .path() .parent() .context("Failed to get config directory")?; + let home_path = env::home_dir(); // Determine directories config. For this, we need to take some // additional factory into account, like env variables, or the @@ -589,11 +591,13 @@ impl<'a> Config<'a> { source: PathSource::EnvVar, } } else if let Some(config_value) = &raw_config.directories.cache_dir { - // If the user explicitly configured a cache directory, use that. + // Resolve possible ~ prefixed path + let expanded_path = expand_home(config_value, home_path.as_deref())?; + // Resolve possible relative path. + let resolved_path = relative_path_root.join(expanded_path); + PathWithSource { - // Resolve possible relative path. It would be nicer to clean up the path, but Rust stdlib - // does not give any method for that that does not need the paths to exist. - path: relative_path_root.join(config_value), + path: resolved_path, source: PathSource::ConfigFile, } } else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) { @@ -610,11 +614,18 @@ impl<'a> Config<'a> { .directories .custom_pages_dir .as_ref() - .map(|path| PathWithSource { + .map(|path| -> Result { + // Resolve possible ~ prefixed path + let expanded_path = expand_home(path, home_path.as_deref())?; // Resolve possible relative path. - path: relative_path_root.join(path), - source: PathSource::ConfigFile, + let resolved_path = relative_path_root.join(expanded_path); + + Ok(PathWithSource { + path: resolved_path, + source: PathSource::ConfigFile, + }) }) + .transpose()? .or_else(|| { get_app_root(AppDataType::UserData, &crate::APP_INFO) .map(|path| { @@ -642,6 +653,29 @@ impl<'a> Config<'a> { } } +/// Expands tilde (~) prefixed directories into its absolute version +fn expand_home<'a>(input_path: &'a Path, home_path: Option<&Path>) -> Result> { + let mut components = input_path.components(); + + if let Some(Component::Normal(first_component_raw)) = components.next() { + let first_component = first_component_raw + .to_str() + .ok_or(anyhow!("Path contains invalid UTF-8"))?; + + if first_component == "~" { + let home_path = home_path.ok_or(anyhow!("Unable to find user home directory"))?; + let rest: PathBuf = components.collect(); + let expanded = home_path.join(rest); + + return Ok(Cow::Owned(expanded)); + } else if first_component.starts_with('~') { + return Err(anyhow!("Tilde expansion with a login name not supported")); + } + } + + Ok(Cow::Borrowed(input_path)) +} + /// The [`ConfigLoader`] is used to load a [`Config`] from a file. /// /// Since the rich [`Config`] keeps references to [`RawConfig`], the raw config needs to be kept alive outside of the @@ -790,6 +824,63 @@ mod test { assert_eq!(raw_config, deserialized); } + #[test] + fn expand_path_with_valid_home() { + let home = Some(PathBuf::from("/foo/bar")); + let path_to_expand = PathBuf::from("~/baz"); + + assert_eq!( + *expand_home(&path_to_expand, home.as_deref()).unwrap(), + PathBuf::from("/foo/bar/baz") + ); + } + + #[test] + fn expand_path_with_absolute_path() { + let home = Some(PathBuf::from("/foo/bar")); + let dir_to_expand = PathBuf::from("/one/two"); + + assert_eq!( + *expand_home(&dir_to_expand, home.as_deref()).unwrap(), + dir_to_expand + ); + } + + #[test] + fn error_with_tilde_username() { + let home = Some(PathBuf::from("/foo/bar")); + let dir_to_expand = PathBuf::from("~baz/foo"); + + assert!(expand_home(&dir_to_expand, home.as_deref()).is_err()); + } + + #[test] + fn expand_tilde_in_config_file() { + let mut raw_config = RawConfig::default(); + raw_config.directories.cache_dir = Some("~/my/custom_cache".into()); + raw_config.directories.custom_pages_dir = Some("~/custom_pages".into()); + + let config = Config::from_raw( + &raw_config, + PathWithSource { + path: PathBuf::from("/path/to/config/config.toml"), + source: PathSource::OsConvention, + }, + ) + .unwrap(); + + let home_dir = env::home_dir().unwrap(); + + assert_eq!( + config.directories.cache_dir.path(), + home_dir.join("my/custom_cache") + ); + assert_eq!( + config.directories.custom_pages_dir.unwrap().path(), + home_dir.join("custom_pages") + ); + } + #[test] fn relative_path_resolution() { let mut raw_config = RawConfig::default(); From 4d33e8a2790b9c53ed4bba91fd5ed1fb4ee103da Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Wed, 6 May 2026 15:36:37 +0100 Subject: [PATCH 190/196] Remove `tldr-c` entry from benchmark results in README.md (#480) `tldr-c-client` is unmaintained. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 230dfa8..3d22e0a 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ Docker container using sharkdp's [`hyperfine`][hyperfine-gh] | [`fast-tldr`][fast-tldr-gh] | Haskell | 17.0 | 0.6 | no example highlighting | | [`tldr-hs`][hs-gh] | Haskell | 25.1 | 0.5 | no example highlighting | | [`tldr-bash`][bash-gh] | Bash | 30.0 | 0.8 | | -| [`tldr-c`][c-gh] | C | 38.4 | 1.0 | | | [`tldr-python-client`][python-gh] | Python | 87.0 | 2.4 | | | [`tldr-node-client`][node-gh] | JavaScript / NodeJS | 407.1 | 12.9 | | @@ -113,7 +112,6 @@ Thanks to @severen for coming up with the name "tealdeer"! [node-gh]: https://github.com/tldr-pages/tldr-node-client -[c-gh]: https://github.com/tldr-pages/tldr-c-client [hs-gh]: https://github.com/psibi/tldr-hs [fast-tldr-gh]: https://github.com/gutjuri/fast-tldr [bash-gh]: https://4e4.win/tldr From d0108b23e450dddd59f79f4f2d693ce787aed5e4 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Thu, 7 May 2026 14:07:27 +0100 Subject: [PATCH 191/196] Fix clippy lints on all targets (#481) --- .github/workflows/ci.yml | 2 +- src/formatter.rs | 6 +++--- tests/lib.rs | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a17ba90..78a27ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: toolchain: stable components: clippy - name: run clippy lints - run: cargo clippy --features logging + run: cargo clippy --all-targets --features logging fmt: name: run rustfmt diff --git a/src/formatter.rs b/src/formatter.rs index b2d6b8e..06d575e 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -439,7 +439,7 @@ mod tests { #[test] fn placeholder_inside_escaped() { assert_eq!( - run("test", r#"test \{\{{{var}} normal\}\}"#), + run("test", r"test \{\{{{var}} normal\}\}"), [ CommandName("test"), NormalCode(" {{"), @@ -450,10 +450,10 @@ mod tests { } #[test] - /// Regression test for https://github.com/tealdeer-rs/tealdeer/issues/473 + /// Regression test for fn prefix_check_character_boundary() { assert_eq!("Ä".len(), 2); - assert_eq!(run("", r#"Äxx{{x}}"#), [NormalCode("Äxx"), Variable("x")],); + assert_eq!(run("", r"Äxx{{x}}"), [NormalCode("Äxx"), Variable("x")],); } } } diff --git a/tests/lib.rs b/tests/lib.rs index acdd048..30254e9 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -555,7 +555,7 @@ fn test_cache_location_permission_denied() { // Make cache directory unreadable let cache_dir = testenv.cache_dir(); let mut permissions = cache_dir.metadata().unwrap().permissions(); - permissions.set_mode(0); + permissions.set_mode(0o0); fs::set_permissions(cache_dir, permissions).unwrap(); testenv @@ -1047,6 +1047,7 @@ fn test_search_language_precedence() { testenv.add_lang_entry(lang, lang, ""); } + #[expect(clippy::type_complexity)] let run = |cases: &[(Vec<(&str, &str)>, Vec<&str>, &str)]| { for (extra_env, extra_args, expected) in cases { let mut cmd = testenv.command(); From 51593d27ebc2f76931c4a1ee01cded12620ac717 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:59:46 +0200 Subject: [PATCH 192/196] Bump actions/checkout from 6 to 7 (#493) --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/gh-pages.yml | 2 +- .github/workflows/release.yml | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78a27ca..62eb86d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: exe_suffix: .exe runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} @@ -50,7 +50,7 @@ jobs: name: run clippy lints runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -62,7 +62,7 @@ jobs: name: run rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -74,7 +74,7 @@ jobs: name: build docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 with: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f8b6f6e..ae9ae93 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -9,7 +9,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41de665..9337d6f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: create-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Create release for tag if: startsWith(github.ref, 'refs/tags/') run: | @@ -24,7 +24,7 @@ jobs: matrix: target: ["bash", "fish", "zsh"] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | @@ -40,7 +40,7 @@ jobs: matrix: target: ["MIT", "APACHE"] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | @@ -66,7 +66,7 @@ jobs: - arch: "arm" libc: "musleabihf" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - name: Build in Docker @@ -86,7 +86,7 @@ jobs: - arch: "x86_64" - arch: "aarch64" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -102,7 +102,7 @@ jobs: build-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup toolchain uses: dtolnay/rust-toolchain@master with: @@ -134,7 +134,7 @@ jobs: - macos-aarch64 - windows-x86_64-msvc steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: actions/download-artifact@v8 - name: Upload binary if: startsWith(github.ref, 'refs/tags/') From df5113ddaa045ce87654ea17482a3778ae58833d Mon Sep 17 00:00:00 2001 From: RedHare <74206389+RedHare-Exe@users.noreply.github.com> Date: Sat, 4 Jul 2026 17:05:15 -0400 Subject: [PATCH 193/196] Added AI Policy to README (#489) Addresses #479, and adds a section for an AI policy based on what is outlined by @niklasmohrin in that issue. The AI Policy is located below the "Development" section. --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 3d22e0a..859d06f 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,17 @@ To run lints: $ cargo clean && cargo clippy +### AI Policy + +Using AI is generally discouraged. However, if it is used as part of a contribution, the contributor MUST: + +1. Clearly mark what parts (if any) of a contribution were created with the help of AI tools. This includes issue and pull request comments. +2. Check all output of AI tools before sharing it with others in the tealdeer project. +3. Not post slop, spam, or low quality contributions. This includes pull request descriptions and comments with excessive text and markdown flair. +4. Leave small or easy tasks to new contributors who want to learn without the use of AI. This is to maintain the presence of the `good-first-issue` tag. +5. Be respectful of everyone's time: *maintainers and other contributors will be reviewing your PRs.* + + ## MSRV (Minimally Supported Rust Version) When publishing a tealdeer release, the Rust version required to build it From f8a2003bc28a67f8f17809699716c0d7b92b479b Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Tue, 7 Jul 2026 13:24:06 +0100 Subject: [PATCH 194/196] Add `updates.warn_cache_age` config option (#492) This is useful when the cache is managed externally, e.g. provisioned from a Nix store path or by a package manager, where the directory's mtime doesn't reflect the cache's real age, causing a spurious warning on every invocation. Today the only way to silence it is `--quiet`, which must be passed every call and hides all other output too. --- docs/src/config_updates.md | 12 ++++++++++++ src/config.rs | 19 +++++++++++++++++++ src/main.rs | 22 ++++++++++++---------- tests/lib.rs | 20 ++++++++++++++++++++ 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/docs/src/config_updates.md b/docs/src/config_updates.md index 9acba55..a8a10c8 100644 --- a/docs/src/config_updates.md +++ b/docs/src/config_updates.md @@ -30,6 +30,18 @@ auto_update = true auto_update_interval_hours = 24 ``` +### `warn_cache_age` + +Controls when a warning is printed if the cache has not been updated in a while. +By default, the warning is shown once the cache is older than 30 days. Set this +to `"never"` to silence the warning. This is useful if, for some reason, the +modification time does not reflect its actual age. + +```toml +[updates] +warn_cache_age = "never" +``` + ## Download configuration ### `download_languages` diff --git a/src/config.rs b/src/config.rs index 89c5d8f..498b49f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -228,6 +228,17 @@ fn default_archive_source() -> String { "https://github.com/tldr-pages/tldr/releases/latest/download".to_owned() } +/// Controls when a warning about an outdated cache is printed. +/// +/// Currently, the only nameable option is `"never"`. In the future, this may +/// be extended to also accept a duration (e.g. `"60d"`), after which the +/// warning should be shown. +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "lowercase")] +enum RawWarnCacheAge { + Never, +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] struct RawUpdatesConfig { #[serde(default)] @@ -240,6 +251,8 @@ struct RawUpdatesConfig { pub tls_backend: RawTlsBackend, #[serde(default)] pub download_languages: Option>, + #[serde(default)] + pub warn_cache_age: Option, } impl Default for RawUpdatesConfig { @@ -250,6 +263,7 @@ impl Default for RawUpdatesConfig { archive_source: default_archive_source(), tls_backend: RawTlsBackend::default(), download_languages: None, + warn_cache_age: None, } } } @@ -380,6 +394,7 @@ pub struct UpdatesConfig<'a> { pub archive_source: &'a str, pub tls_backend: TlsBackend, pub download_languages: Vec>, + pub warn_cache_age: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -569,6 +584,10 @@ impl<'a> Config<'a> { || search.languages.clone(), |languages| languages.iter().map(|lang| Language(lang)).collect(), ), + warn_cache_age: match raw_config.updates.warn_cache_age { + None => Some(MAX_CACHE_AGE), + Some(RawWarnCacheAge::Never) => None, + }, }; let relative_path_root = config_file_path diff --git a/src/main.rs b/src/main.rs index 29dad95..9a7c423 100644 --- a/src/main.rs +++ b/src/main.rs @@ -376,16 +376,18 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { return Ok(ExitCode::FAILURE); }; - let age = cache.age()?; - if age > config::MAX_CACHE_AGE && !args.quiet { - print_warning( - enable_styles, - &format!( - "The cache hasn't been updated for {} days.\n\ - You should probably run `tldr --update` soon.", - age.as_secs() / 24 / 3600 - ), - ); + if let Some(max_cache_age) = config.updates.warn_cache_age { + let age = cache.age()?; + if age > max_cache_age && !args.quiet { + print_warning( + enable_styles, + &format!( + "The cache hasn't been updated for {} days.\n\ + You should probably run `tldr --update` soon.", + age.as_secs() / 24 / 3600 + ), + ); + } } cache diff --git a/tests/lib.rs b/tests/lib.rs index 30254e9..d431b5f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -493,6 +493,26 @@ fn test_quiet_old_cache() { .stderr(contains("The cache hasn't been updated for ").not()); } +#[test] +fn test_warn_cache_age_never() { + let testenv = TestEnv::new().install_default_cache(); + + filetime::set_file_mtime( + testenv.cache_dir().join(TLDR_PAGES_DIR), + filetime::FileTime::from_unix_time(1, 0), + ) + .unwrap(); + + testenv.append_to_config("[updates]\nwarn_cache_age = \"never\"\n"); + + testenv + .command() + .args(["which"]) + .assert() + .success() + .stderr(contains("The cache hasn't been updated for ").not()); +} + #[cfg_attr(feature = "ignore-online-tests", ignore = "online test")] #[test] fn test_create_cache_directory_path() { From 28ed7850016813a5a6625c2748794cd7045d3055 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 26 Jul 2026 23:52:43 +0200 Subject: [PATCH 195/196] Fix 1.97 clippy lints --- src/formatter.rs | 2 +- src/main.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/formatter.rs b/src/formatter.rs index 06d575e..082f436 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -96,7 +96,7 @@ where // This is safe as long as the parsed title is only the command, // and the iterator yields values in order of appearance. command = title; - debug!("Detected command name: {}", &command); + debug!("Detected command name: {command}"); } LineType::Description(text) => { process_snippet(PageSnippet::Description(&base_indent))?; diff --git a/src/main.rs b/src/main.rs index 9a7c423..cc03d01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -429,10 +429,9 @@ fn try_main(args: Cli, enable_styles: bool) -> Result { print_warning( enable_styles, &format!( - "Page `{}` not found in cache.\n\ + "Page `{command}` not found in cache.\n\ Try updating with `tldr --update`, or submit a pull request to:\n\ - https://github.com/tldr-pages/tldr", - &command + https://github.com/tldr-pages/tldr" ), ); } From 37b0dee39ffc7eeb95ad8e3dfda3b70991338b0f Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Thu, 6 Aug 2026 00:37:37 +0200 Subject: [PATCH 196/196] Support XDG directory spec on macOS by switching `app_dirs2` to `etcetera` (#467) Closes #311 Similar to how `bat` does it, we now have a global struct which holds all the queried system directories. We prefer the XDG directories, but use the "native" directories as a fallback. This should ensure that when MacOs users upgrade from an older version, their existing config and cache are still used. After deleting the old directories, the new ones should be used by tealdeer automatically. --- .github/workflows/ci.yml | 2 +- Cargo.lock | 36 +++++----------- Cargo.toml | 4 +- src/config.rs | 93 ++++++++++++++++++++++++++-------------- src/main.rs | 23 ++++------ 5 files changed, 83 insertions(+), 75 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62eb86d..faf3111 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - toolchain: [stable, 1.85.0] + toolchain: [stable, 1.87.0] # MSRV include: - platform: windows-latest exe_suffix: .exe diff --git a/Cargo.lock b/Cargo.lock index be9bd24..4fba42b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,18 +73,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "app_dirs2" -version = "2.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e7b35733e3a8c1ccb90385088dd5b6eaa61325cb4d1ad56e683b5224ff352e" -dependencies = [ - "jni", - "ndk-context", - "winapi", - "xdg", -] - [[package]] name = "arbitrary" version = "1.4.2" @@ -380,6 +368,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "etcetera" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" +dependencies = [ + "cfg-if", + "windows-sys 0.61.1", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -635,12 +633,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -1117,11 +1109,11 @@ name = "tealdeer" version = "1.8.1" dependencies = [ "anyhow", - "app_dirs2", "assert_cmd", "clap", "env_logger", "escargot", + "etcetera", "filetime", "log", "pager", @@ -1634,12 +1626,6 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" -[[package]] -name = "xdg" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" - [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index aa7ae49..1d98992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/tealdeer-rs/tealdeer/" documentation = "https://tealdeer-rs.github.io/tealdeer/" version = "1.8.1" include = ["/src/**/*", "/tests/**/*", "/Cargo.toml", "/README.md", "/LICENSE-*", "/screenshot.png", "completion/*"] -rust-version = "1.85" +rust-version = "1.87" # MSRV edition = "2021" [[bin]] @@ -21,9 +21,9 @@ path = "src/main.rs" [dependencies] anyhow = "1" -app_dirs = { version = "2", package = "app_dirs2" } clap = { version = "4", features = ["std", "derive", "help", "usage", "cargo", "error-context", "color", "wrap_help"], default-features = false } env_logger = { version = "0.11", optional = true } +etcetera = "0.11.0" log = "0.4" serde = "1.0.21" serde_derive = "1.0.21" diff --git a/src/config.rs b/src/config.rs index 498b49f..f0feeb4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,8 +8,7 @@ use std::{ time::Duration, }; -use anyhow::{anyhow, bail, ensure, Context, Result}; -use app_dirs::{get_app_root, AppDataType}; +use anyhow::{anyhow, ensure, Context, Result}; use clap::ValueEnum; use log::info; use serde::Serialize as _; @@ -33,6 +32,50 @@ const SUPPORTED_TLS_BACKENDS: &[RawTlsBackend] = &[ RawTlsBackend::RustlsWithNativeRoots, ]; +struct SystemDirectories { + config: PathBuf, + cache: PathBuf, + data: PathBuf, +} + +impl SystemDirectories { + fn discover() -> Result { + use etcetera::{ + app_strategy::choose_native_strategy, choose_app_strategy, AppStrategy, AppStrategyArgs, + }; + + let args = AppStrategyArgs { + top_level_domain: String::new(), + author: String::new(), + app_name: crate::NAME.to_string(), + }; + + // The app strategy prefers XDG on MacOs, whereas the native strategy returns paths which + // are used by installed applications. On Linux and Windows, the strategies are the same. + let app_dirs = choose_app_strategy(args.clone())?; + let native_dirs = choose_native_strategy(args)?; + + // We prefer the XDG paths, but before tealdeer 1.9, we used only the native paths on MacOs. + // So if we find files in these locations, we keep using them. + let fallback = |app_dir: PathBuf, native_dir: PathBuf| { + if !app_dir.exists() && native_dir.exists() { + native_dir + } else { + app_dir + } + }; + + Ok(Self { + config: fallback(app_dirs.config_dir(), native_dirs.config_dir()), + cache: fallback(app_dirs.cache_dir(), native_dirs.cache_dir()), + data: fallback(app_dirs.data_dir(), native_dirs.data_dir()), + }) + } +} +static SYSTEM_DIRECTORIES: LazyLock = LazyLock::new(|| { + SystemDirectories::discover().expect("Failed to initialize system directories.") +}); + pub(crate) fn supported_tls_backends_string() -> String { SUPPORTED_TLS_BACKENDS .iter() @@ -619,15 +662,11 @@ impl<'a> Config<'a> { path: resolved_path, source: PathSource::ConfigFile, } - } else if let Ok(default_dir) = get_app_root(AppDataType::UserCache, &crate::APP_INFO) { - // Otherwise, fall back to the default user cache directory. + } else { PathWithSource { - path: default_dir, + path: SYSTEM_DIRECTORIES.cache.clone(), source: PathSource::OsConvention, } - } else { - // If everything fails, give up - bail!("Could not determine user cache directory"); }; let custom_pages_dir = raw_config .directories @@ -646,15 +685,11 @@ impl<'a> Config<'a> { }) .transpose()? .or_else(|| { - get_app_root(AppDataType::UserData, &crate::APP_INFO) - .map(|path| { - // Note: The `join("")` call ensures that there's a trailing slash - PathWithSource { - path: path.join("pages").join(""), - source: PathSource::OsConvention, - } - }) - .ok() + // Note: The `join("")` call ensures that there's a trailing slash + Some(PathWithSource { + path: SYSTEM_DIRECTORIES.data.join("pages").join(""), + source: PathSource::OsConvention, + }) }); let directories = DirectoriesConfig { cache_dir, @@ -743,7 +778,7 @@ impl ConfigLoader { /// Create a loader that uses the default config file location. If no file is present at the default location, the /// default configuration is used. pub fn read_default_path() -> Result { - let path = get_default_config_path().context("Could not determine default config path.")?; + let path = get_default_config_path(); Self::read_internal(path, true) } @@ -761,30 +796,24 @@ impl ConfigLoader { /// /// Note that this function does not verify whether the directory at that /// location exists, or is a directory. -pub fn get_config_dir() -> Result<(PathBuf, PathSource)> { +pub fn get_config_dir() -> (PathBuf, PathSource) { // Allow overriding the config directory by setting the // $TEALDEER_CONFIG_DIR env variable. if let Ok(value) = env::var("TEALDEER_CONFIG_DIR") { - return Ok((PathBuf::from(value), PathSource::EnvVar)); + return (PathBuf::from(value), PathSource::EnvVar); } - // Otherwise, fall back to the user config directory. - let dirs = get_app_root(AppDataType::UserConfig, &crate::APP_INFO) - .context("Failed to determine the user config directory")?; - Ok((dirs, PathSource::OsConvention)) + (SYSTEM_DIRECTORIES.config.clone(), PathSource::OsConvention) } /// Return the path to the config file. /// /// Note that this function does not verify whether the file at that location /// exists, or is a file. -pub fn get_default_config_path() -> Result { - let (config_dir, source) = get_config_dir()?; - let config_file_path = config_dir.join(CONFIG_FILE_NAME); - Ok(PathWithSource { - path: config_file_path, - source, - }) +pub fn get_default_config_path() -> PathWithSource { + let (mut path, source) = get_config_dir(); + path.push(CONFIG_FILE_NAME); + PathWithSource { path, source } } /// Create default config file. @@ -794,7 +823,7 @@ pub fn make_default_config(path: Option<&Path>) -> Result { let config_file_path = if let Some(p) = path { p.into() } else { - let (config_dir, _) = get_config_dir()?; + let (config_dir, _) = get_config_dir(); // Ensure that config directory exists if config_dir.exists() { diff --git a/src/main.rs b/src/main.rs index cc03d01..6678ceb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,6 @@ use std::{ }; use anyhow::{anyhow, Context, Result}; -use app_dirs::AppInfo; use cache::{CacheConfig, TLDR_OLD_PAGES_DIR}; use clap::Parser; use config::{ConfigLoader, Language, StyleConfig, TlsBackend}; @@ -65,10 +64,6 @@ use crate::{ }; const NAME: &str = "tealdeer"; -const APP_INFO: AppInfo = AppInfo { - name: NAME, - author: NAME, -}; static TEALDEER_PAGE: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/pages/tealdeer.md")); @@ -110,16 +105,14 @@ fn update_cache( /// Show file paths fn show_paths(config: &Config) { - let config_dir = get_config_dir().map_or_else( - |e| format!("[Error: {e}]"), - |(mut path, source)| { - path.push(""); // Trailing path separator - match path.to_str() { - Some(path) => format!("{path} ({source})"), - None => "[Invalid]".to_string(), - } - }, - ); + let config_dir = { + let (mut path, source) = get_config_dir(); + path.push(""); // Trailing path separator + match path.to_str() { + Some(path) => format!("{path} ({source})"), + None => "[Invalid]".to_string(), + } + }; let config_path = config.file_path.to_string(); let cache_dir = config.directories.cache_dir.to_string(); let pages_dir = {