summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJJ Style <style.jj@protonmail.com>2023-08-27 21:52:20 +0000
committerGitHub <noreply@github.com>2023-08-27 21:52:20 +0000
commit9e1489bbc549dc86f8efe47d924512d48add10ed (patch)
tree592418af2fd2dc9b0b5fb656de3f6824ba8cb9e6
parent1764cee1bd0b857889cea9feaa79d52aeb697e3f (diff)
Allow querying multiple platforms (#300)
-rw-r--r--docs/src/usage.txt33
-rw-r--r--src/cache.rs36
-rw-r--r--src/cli.rs5
-rw-r--r--src/main.rs15
-rw-r--r--tests/lib.rs138
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;
}
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<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();