Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(helper): add more external help providers to plz menu #56

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2bb7962
[feature/add] Create the base implementation for
0x61nas Jun 22, 2023
d842d12
[refactor] Rename the `cheat.rs` to `cheatt_sh.rs`
0x61nas Jun 22, 2023
6e22178
Merge branch 'main' into add-more-options-to-plz-menu
0x61nas Jun 22, 2023
6662942
Merge branch 'main' into add-more-options-to-plz-menu
0x61nas Jun 24, 2023
40cd8cc
Merge branch 'main' into add-more-options-to-plz-menu
0x61nas Jul 30, 2023
1107309
fix(eg): update the args
0x61nas Jul 30, 2023
47f1dd6
feat(help provider): create the initial implementation
0x61nas Jul 30, 2023
69397dc
refactor(docs): improve `get_docs_help` function
0x61nas Jul 30, 2023
5e26640
feat(help provider): improve the implementation
0x61nas Jul 30, 2023
5e73f1f
fix(config): rename import to match renamed module
0x61nas Jul 30, 2023
741b73f
refactor(help provider): refactor error handling in docs module
0x61nas Jul 30, 2023
1dcb4d2
refactor(cheat.sh): Implement HelpProvider for cheat.sh
0x61nas Jul 30, 2023
81f2ba1
feat(config):aAllow optional cheat.sh url in config
0x61nas Jul 30, 2023
2ea0a3c
refactor(help provider): separate the default fetch implementation in…
0x61nas Jul 30, 2023
023154a
refactor(cheat.sh): update the cheat.sh implementation for HelpProvider
0x61nas Jul 30, 2023
a418c5f
docs(cheat.sh): add the struct docs
0x61nas Jul 30, 2023
d552f27
test(cheat.sh): update the fetch test
0x61nas Jul 30, 2023
6ee7e64
refactor(eg): create the `eg` provider struct and implement HelpProvi…
0x61nas Jul 30, 2023
b0da6f2
refactor(help provider): removes the default implementation of the 'b…
0x61nas Jul 30, 2023
6bcc47e
feat(config): add custom URL option for `eg` provider
0x61nas Jul 30, 2023
67d52db
feat(cli): add custom URL option for `eg` provider
0x61nas Jul 30, 2023
472541f
test(eg): create the fetch test
0x61nas Jul 30, 2023
3b2acc0
test(config): update the test
0x61nas Jul 30, 2023
a46ec0a
test(cli): fix the `update_conf` test
0x61nas Jul 30, 2023
45ce960
refactor(format): Run cargo fmt
0x61nas Jul 30, 2023
adebfd3
refactor(lint): remoove unused imports
0x61nas Jul 30, 2023
b211076
refactor(help provider): make the methods name cleare
0x61nas Aug 1, 2023
a653da7
feat(cheatsheets): create the cheatsheets provider
0x61nas Aug 1, 2023
21e1f9b
docs(cheatsheets): add the missing docs
0x61nas Aug 1, 2023
bea22ec
feat(config): add cheatsheets provider url var
0x61nas Aug 1, 2023
4a5c0ca
feat(cli): add the --cheat-url option to plz subcommand
0x61nas Aug 1, 2023
facc820
test(cheatsheets): create the fetch test
0x61nas Aug 1, 2023
24d896d
refactor(format): Run cargo fmt
0x61nas Aug 1, 2023
e6e8484
Merge pull request #2 from anas-forks/feat/add-chatsheets-provider
0x61nas Aug 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/cli.rs
Expand Up @@ -51,6 +51,12 @@ pub enum CliCommands {
/// Use a custom URL for cheat.sh.
#[arg(long, env = "CHEAT_SH_URL", value_name = "URL")]
cheat_sh_url: Option<String>,
/// Use a custom provider URL for `eg` pages.
#[arg(long, env = "EG_PAGES_URL", value_name = "URL")]
eg_url: Option<String>,
/// Use a custom URL for cheat sheets.
#[arg(long, env = "CHEATSHEETS_URL", value_name = "URL")]
cheat_url: Option<String>,
/// Sets the pager to use.
#[arg(short, long)]
pager: Option<String>,
Expand All @@ -76,6 +82,7 @@ impl CliArgs {
if let Some(CliCommands::Plz {
ref man_cmd,
ref cheat_sh_url,
ref eg_url,
no_pager,
ref pager,
..
Expand All @@ -85,7 +92,10 @@ impl CliArgs {
config.man_command = man_cmd.clone();
}
if let Some(cheat_sh_url) = cheat_sh_url {
config.cheat_sh_url = cheat_sh_url.clone();
config.cheat_sh_url = Some(cheat_sh_url.clone());
}
if let Some(eg_url) = eg_url {
config.eg_url = Some(eg_url.to_owned());
}
if no_pager {
config.pager_command = None;
Expand Down Expand Up @@ -116,6 +126,8 @@ mod tests {
cmd: "ps".to_string(),
pager: Some("bat".to_string()),
cheat_sh_url: None,
cheat_url: None,
eg_url: None,
man_cmd: None,
no_pager: false,
}),
Expand Down
19 changes: 15 additions & 4 deletions src/config.rs
@@ -1,7 +1,9 @@
use crate::error::Result;
use crate::helper::args::common::{HelpArg, VersionArg};
use crate::helper::args::FOUND_EMOTICON;
use crate::helper::docs::cheat::DEFAULT_CHEAT_SHEET_PROVIDER;
use crate::helper::docs::cheat_sh::DEFAULT_CHEAT_SHEET_PROVIDER;
use crate::helper::docs::cheatsheets::DEFAULT_CHEATSHEETS_PROVIDER;
use crate::helper::docs::eg::DEFAULT_EG_PAGES_PROVIDER;
use colored::*;
use serde::{Deserialize, Serialize};
use std::env;
Expand All @@ -24,7 +26,11 @@ pub struct Config {
/// Pager to use for command outputs, None to disable.
pub pager_command: Option<String>,
/// Use a custom URL for cheat.sh.
pub cheat_sh_url: String,
pub cheat_sh_url: Option<String>,
/// Use a custom URL for `eg` pages provider.
pub eg_url: Option<String>,
/// Use a custom URL for cheatsheets provider.
pub cheatsheets_url: Option<String>,
}

impl Default for Config {
Expand All @@ -44,7 +50,9 @@ impl Default for Config {
]),
man_command: "man".to_string(),
pager_command: Some("less -R".to_string()),
cheat_sh_url: DEFAULT_CHEAT_SHEET_PROVIDER.to_string(),
cheat_sh_url: Some(DEFAULT_CHEAT_SHEET_PROVIDER.to_string()),
eg_url: Some(DEFAULT_EG_PAGES_PROVIDER.to_string()),
cheatsheets_url: Some(DEFAULT_CHEATSHEETS_PROVIDER.to_string()),
}
}
}
Expand Down Expand Up @@ -128,7 +136,10 @@ mod tests {
let config = Config::parse(&path)?;
assert!(config.check_help);
assert!(config.check_version);
assert_eq!(config.cheat_sh_url, DEFAULT_CHEAT_SHEET_PROVIDER);
assert_eq!(
config.cheat_sh_url,
Some(DEFAULT_CHEAT_SHEET_PROVIDER.to_string())
);
Ok(())
}
}
3 changes: 3 additions & 0 deletions src/error.rs
Expand Up @@ -18,6 +18,9 @@ pub enum Error {
/// Error that might occur while serializing the configuration into TOML.
#[error("TOML serialization error: `{0}`")]
TomlSerializeError(#[from] toml::ser::Error),
/// Error that might occur when tray to get help from an external provider
#[error("External help provider error: `{0}`")]
ProviderError(String),
}

/// Type alias for the standard [`Result`] type.
Expand Down
72 changes: 0 additions & 72 deletions src/helper/docs/cheat.rs

This file was deleted.

54 changes: 54 additions & 0 deletions src/helper/docs/cheat_sh.rs
@@ -0,0 +1,54 @@
use crate::error::{Error, Result};
use crate::helper::docs::HelpProvider;
use ureq::{AgentBuilder, Request};

/// Default cheat sheet provider URL.
pub const DEFAULT_CHEAT_SHEET_PROVIDER: &str = "https://cheat.sh";

/// User agent for the cheat sheet provider.
///
/// See <https://github.com/chubin/cheat.sh/blob/83bffa587b6c1048cbcc40ea8fa6af675203fd5f/bin/app.py#L76>
const CHEAT_SHEET_USER_AGENT: &str = "fetch";

/// The `cheat.sh` provider
pub struct CheatDotSh;

impl HelpProvider for CheatDotSh {
fn url(&self) -> &'static str {
DEFAULT_CHEAT_SHEET_PROVIDER
}

fn build_request(&self, cmd: &str, url: &str) -> Request {
AgentBuilder::new()
.user_agent(CHEAT_SHEET_USER_AGENT)
.build()
.get(&format!("{}/{}", url, cmd))
}

fn fetch(&self, cmd: &str, custom_url: &Option<String>) -> Result<String> {
let response = self._fetch(cmd, custom_url);
if let Ok(page) = &response {
if page.starts_with("Unknown topic.") {
return Err(Error::ProviderError(page.to_owned()));
}
}
response
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_fetch_cheat_sheet() -> Result<()> {
let output = CheatDotSh.fetch("ls", &None)?;
assert!(output.contains(
"# To display all files, along with the size (with unit suffixes) and timestamp:"
));
assert!(output.contains(
"# Long format list with size displayed using human-readable units (KiB, MiB, GiB):"
));
Ok(())
}
}
43 changes: 43 additions & 0 deletions src/helper/docs/cheatsheets.rs
@@ -0,0 +1,43 @@
use crate::helper::docs::HelpProvider;
use ureq::{AgentBuilder, Request};

/// The default cheatsheets provider URL.
pub const DEFAULT_CHEATSHEETS_PROVIDER: &str =
"https://raw.githubusercontent.com/cheat/cheatsheets/master";

/// The `cheatsheets` provider
pub struct Cheatsheets;

impl HelpProvider for Cheatsheets {
fn url(&self) -> &'static str {
DEFAULT_CHEATSHEETS_PROVIDER
}

fn build_request(&self, cmd: &str, url: &str) -> Request {
AgentBuilder::new().build().get(&format!("{}/{}", url, cmd))
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::error::Result;

#[test]
fn test_fetch_cheatsheets() -> Result<()> {
let output = Cheatsheets.fetch("ls", &None)?;

assert!(output.contains(
r##"# To display everything in <dir>, including hidden files:
ls -a <dir>
"##
));
assert!(output.contains(
r##"# To display directories only, include hidden:
ls -d .*/ */ <dir>
"##
));

Ok(())
}
}
41 changes: 41 additions & 0 deletions src/helper/docs/eg.rs
@@ -0,0 +1,41 @@
use crate::helper::docs::HelpProvider;
use ureq::{AgentBuilder, Request};

/// EG page provider URL.
pub const DEFAULT_EG_PAGES_PROVIDER: &str =
"https://raw.githubusercontent.com/srsudar/eg/master/eg/examples";

/// The `eg` pages provider
pub struct Eg;

impl HelpProvider for Eg {
fn url(&self) -> &'static str {
DEFAULT_EG_PAGES_PROVIDER
}

fn build_request(&self, cmd: &str, url: &str) -> Request {
AgentBuilder::new()
.build()
.get(&format!("{}/{}.md", url, cmd))
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::error::Result;

#[test]
fn test_eg_page_fetch() -> Result<()> {
let output = Eg.fetch("ls", &None)?;

assert!(output.contains("show contents of current directory"));
assert!(output.contains("ls -alh"));
assert!(output.contains(
r##"`ls` is often aliased to make the defaults a bit more useful. Here are three
basic aliases. The second two can be remembered by "list long" and "list all":
"##
));
Ok(())
}
}