Skip to content

Commit

Permalink
Allow querying multiple platforms (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
jj-style authored Aug 27, 2023
1 parent 1764cee commit 9e1489b
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 36 deletions.
33 changes: 17 additions & 16 deletions docs/src/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/.
36 changes: 22 additions & 14 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ static TLDR_OLD_PAGES_DIR: &str = "tldr-master";

#[derive(Debug)]
pub struct Cache {
platform: PlatformType,
cache_dir: PathBuf,
}

Expand Down Expand Up @@ -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(),
}
}
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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"
Expand All @@ -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.
Expand All @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::path::PathBuf;

use clap::{AppSettings, ArgGroup, Parser};
use clap::{AppSettings, ArgAction, ArgGroup, Parser};

use crate::types::{ColorOptions, PlatformType};

Expand Down Expand Up @@ -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")]
Expand Down
15 changes: 11 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
}

Expand All @@ -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)
Expand Down
138 changes: 138 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 9e1489b

Please sign in to comment.