diff options
author | JJ Style <style.jj@protonmail.com> | 2023-08-27 21:52:20 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-27 21:52:20 +0000 |
commit | 9e1489bbc549dc86f8efe47d924512d48add10ed (patch) | |
tree | 592418af2fd2dc9b0b5fb656de3f6824ba8cb9e6 | |
parent | 1764cee1bd0b857889cea9feaa79d52aeb697e3f (diff) |
Allow querying multiple platforms (#300)
-rw-r--r-- | docs/src/usage.txt | 33 | ||||
-rw-r--r-- | src/cache.rs | 36 | ||||
-rw-r--r-- | src/cli.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 15 | ||||
-rw-r--r-- | 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: <COMMAND>... The command to show (e.g. `tar` or `git log`) OPTIONS: - -l, --list List all commands in the cache - -f, --render <FILE> Render a specific markdown file - -p, --platform <PLATFORM> Override the operating system [possible values: linux, macos, - windows, sunos, osx, android] - -L, --language <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 <WHEN> 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 <FILE> Render a specific markdown file + -p, --platform <PLATFORMS> Override the operating system [possible values: linux, macos, + windows, sunos, osx, android] + -L, --language <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 <WHEN> 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<P>(platform: PlatformType, cache_dir: P) -> Self + pub fn new<P>(cache_dir: P) -> Self where P: Into<PathBuf>, { 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<PageLookupResult> { 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<String> { + pub fn list_pages( + &self, + custom_pages_dir: Option<&Path>, + platforms: &[PlatformType], + ) -> Vec<String> { // 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; } @@ -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<PlatformType>, + pub platforms: Option<Vec<PlatformType>>, /// 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 @@ -563,6 +563,71 @@ fn test_pager_flag_enable() { } #[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(); @@ -605,6 +670,79 @@ 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() + )); + + 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(); |