From c82f3bb3b13b2ae82775e112413554b8ba7fadfb Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Tue, 25 Oct 2022 19:10:14 +0200 Subject: [PATCH 01/30] implemented a rough concept for generating shelll completion scripts for a number of common shells --- Cargo.lock | 10 ++++++++++ Cargo.toml | 2 ++ src/bin/huak/commands/completion.rs | 13 +++++++++++++ src/bin/huak/commands/mod.rs | 7 +++++++ 4 files changed, 32 insertions(+) create mode 100644 src/bin/huak/commands/completion.rs diff --git a/Cargo.lock b/Cargo.lock index 43a24530..59f730dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "clap_complete" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfe581a2035db4174cdbdc91265e1aba50f381577f0510d0ad36c7bc59cc84a3" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.0.13" @@ -401,6 +410,7 @@ name = "huak" version = "0.0.7-alpha.3" dependencies = [ "clap", + "clap_complete", "expectrl", "fs_extra", "git2", diff --git a/Cargo.toml b/Cargo.toml index 2b089a65..b32b7732 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ path = "./src/huak/lib.rs" [dependencies] clap = {version = "4.0.15", features = ["cargo", "derive"]} +clap_complete = "4.0" + thiserror = "1.0.36" fs_extra = "1.2.0" glob = "0.3.0" diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs new file mode 100644 index 00000000..5343c806 --- /dev/null +++ b/src/bin/huak/commands/completion.rs @@ -0,0 +1,13 @@ +use crate::errors::CliResult; + +use clap::CommandFactory; +use clap_complete::{Shell, generate}; + + + +pub fn run(shell: Shell) -> CliResult<()> { + let mut cmd = crate::commands::Cli::command(); + + generate(shell, &mut cmd, "huak", &mut std::io::stdout()); + Ok(()) +} diff --git a/src/bin/huak/commands/mod.rs b/src/bin/huak/commands/mod.rs index 5d05c4e7..4fe137e3 100644 --- a/src/bin/huak/commands/mod.rs +++ b/src/bin/huak/commands/mod.rs @@ -1,11 +1,13 @@ use crate::errors::CliResult; use clap::{Parser, Subcommand}; +use clap_complete::Shell; pub(crate) mod activate; pub(crate) mod add; pub(crate) mod audit; pub(crate) mod build; pub(crate) mod clean; +pub(crate) mod completion; pub(crate) mod doc; pub(crate) mod fix; pub(crate) mod fmt; @@ -33,6 +35,10 @@ pub struct Cli { // List of commands. #[derive(Subcommand)] pub enum Commands { + Completion { + shell: Shell + }, + /// Activate the project's virtual environment. Activate, /// Add a dependency to the existing project. @@ -119,6 +125,7 @@ pub enum Commands { impl Cli { pub fn run(self) -> CliResult<()> { match self.command { + Commands::Completion { shell } => completion::run(shell), Commands::Activate => activate::run(), Commands::Add { dependency, dev } => add::run(dependency, dev), Commands::Audit => audit::run(), From 9570d4a0d24ecdabc4498b6bd13c2ec3b9009106 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Tue, 25 Oct 2022 19:16:50 +0200 Subject: [PATCH 02/30] ran cargo fmt --- src/bin/huak/commands/completion.rs | 4 +--- src/bin/huak/commands/mod.rs | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 5343c806..48f0cbf3 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -1,9 +1,7 @@ use crate::errors::CliResult; use clap::CommandFactory; -use clap_complete::{Shell, generate}; - - +use clap_complete::{generate, Shell}; pub fn run(shell: Shell) -> CliResult<()> { let mut cmd = crate::commands::Cli::command(); diff --git a/src/bin/huak/commands/mod.rs b/src/bin/huak/commands/mod.rs index 4fe137e3..8b8879bb 100644 --- a/src/bin/huak/commands/mod.rs +++ b/src/bin/huak/commands/mod.rs @@ -36,7 +36,7 @@ pub struct Cli { #[derive(Subcommand)] pub enum Commands { Completion { - shell: Shell + shell: Shell, }, /// Activate the project's virtual environment. @@ -104,7 +104,9 @@ pub enum Commands { /// Builds and uploads current project to a registry. Publish, /// Remove a dependency from the project. - Remove { dependency: String }, + Remove { + dependency: String, + }, /// Run a command within the project's environment context. Run { #[arg(trailing_var_arg = true)] From a94005748059e7cf58522cf2cc68fa427cc5ea65 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 08:03:35 +0200 Subject: [PATCH 03/30] added docstring for completion command and put it in alphabetic order --- src/bin/huak/commands/mod.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/bin/huak/commands/mod.rs b/src/bin/huak/commands/mod.rs index 8b8879bb..656ab49c 100644 --- a/src/bin/huak/commands/mod.rs +++ b/src/bin/huak/commands/mod.rs @@ -35,10 +35,6 @@ pub struct Cli { // List of commands. #[derive(Subcommand)] pub enum Commands { - Completion { - shell: Shell, - }, - /// Activate the project's virtual environment. Activate, /// Add a dependency to the existing project. @@ -52,6 +48,9 @@ pub enum Commands { Audit, /// Build tarball and wheel for the project. Build, + /// Generates a shell completion script for supported shells. + /// See the help menu for more information on supported shells. + Completion { shell: Shell }, /// Remove tarball and wheel from the built project. Clean { #[arg(long, required = false)] @@ -104,9 +103,7 @@ pub enum Commands { /// Builds and uploads current project to a registry. Publish, /// Remove a dependency from the project. - Remove { - dependency: String, - }, + Remove { dependency: String }, /// Run a command within the project's environment context. Run { #[arg(trailing_var_arg = true)] From feb6251531876c40ab7faf89ea8137a09b0d4396 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 08:42:59 +0200 Subject: [PATCH 04/30] implemented bash, fish powershell and zsh shell completion suggestions --- src/bin/huak/commands/completion.rs | 79 ++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 48f0cbf3..7ae12331 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -1,11 +1,86 @@ +use crate::commands::Cli; use crate::errors::CliResult; use clap::CommandFactory; use clap_complete::{generate, Shell}; pub fn run(shell: Shell) -> CliResult<()> { - let mut cmd = crate::commands::Cli::command(); + let mut cmd = Cli::command(); - generate(shell, &mut cmd, "huak", &mut std::io::stdout()); + // We can't take a reference to the cmd variable since we also need a mutable reference to this + // in the generate() function. + let cmd_name = String::from(Cli::command().get_name()); + + let help_output = match &shell { + Shell::Bash => completion_help_bash(&cmd_name), + Shell::Elvish => completion_help_elvish(&cmd_name), + Shell::Fish => completion_help_fish(&cmd_name), + Shell::PowerShell => completion_help_powershell(&cmd_name), + Shell::Zsh => completion_help_zsh(&cmd_name), + + // We need this since the Shell enum is marked as non exhaustive + _ => completion_help_unknown(&cmd_name), + }; + + eprintln!("{}", help_output); + + generate(shell, &mut cmd, &cmd_name, &mut std::io::stdout()); Ok(()) } + +fn completion_help_bash(cmd_name: &str) -> String { + format!( + r##""First, ensure that you install `bash-completion` using your package manager. +After, add this to your `~/.bash_profile`: + +`eval "$({cmd_name} completion bash --rename {cmd_name})"` +"## + ) +} + +// TODO +fn completion_help_elvish(_cmd_name: &str) -> String { + format!(r##""##) +} + +fn completion_help_fish(cmd_name: &str) -> String { + format!( + r##"Generate a `tool.fish` completion script: + +`{cmd_name} completion fish --rename {cmd_name} > ~/.config/fish/completions/{cmd_name}.fish` +"## + ) +} + +fn completion_help_powershell(cmd_name: &str) -> String { + format!( + r##"Open your profile script with: + +`mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue` +`notepad $profile` + +Add the line and save the file: +`Invoke-Expression -Command $({cmd_name} completion powershell --rename {cmd_name} | Out-String)` +"## + ) +} + +fn completion_help_zsh(cmd_name: &str) -> String { + format!( + r##"Generate a `_{cmd_name}` completion script and put it somewhere in your `$fpath`: +`{cmd_name} completion zsh --rename {cmd_name} > /usr/local/share/zsh/site-functions/_{cmd_name}` + +Ensure that the following is present in your `~/.zshrc`: + +`autoload -U compinit` +`compinit -i` +"## + ) +} + +// TODO +// There should probably be a link to the github issues page for this since if this is triggered it +// means clap_complete was upgraded but the added shell was not handled. +fn completion_help_unknown(_cmd_name: &str) -> String { + format!(r##""##) +} From fdfbba66f91a4c14e5dcf4d4609c9d99b83d9bec Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 10:43:18 +0200 Subject: [PATCH 05/30] updated help output in the README.md --- README.md | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 529e3085..f8f6e4f7 100644 --- a/README.md +++ b/README.md @@ -68,25 +68,26 @@ A Python package manager written in Rust inspired by Cargo. Usage: huak Commands: - activate Activate the project's virtual environment - add Add a dependency to the existing project - audit Check for vulnerable dependencies and license compatibility* - build Build tarball and wheel for the project - clean Remove tarball and wheel from the built project - doc Generates documenation for the project* - fix Auto-fix fixable lint conflicts - fmt Format the project's Python code - init Initialize the existing project - install Install the dependencies of an existing project - lint Lint the project's Python code - new Create a new project at - publish Builds and uploads current project to a registry* - remove Remove a dependency from the project - run Run a command within the project's environment context - test Test the project's Python code - update Update dependencies added to the project* - version Display the version of the project - help Print this message or the help of the given subcommand(s) + activate Activate the project's virtual environment + add Add a dependency to the existing project + audit Check for vulnerable dependencies and license compatibility* + build Build tarball and wheel for the project + completion Generates a shell completion script for supported shells. See the help menu for more information on supported shells + clean Remove tarball and wheel from the built project + doc Generates documentation for the project* + fix Auto-fix fixable lint conflicts + fmt Format the project's Python code + init Initialize the existing project + install Install the dependencies of an existing project + lint Lint the project's Python code + new Create a new project at + publish Builds and uploads current project to a registry* + remove Remove a dependency from the project + run Run a command within the project's environment context + test Test the project's Python code + update Update dependencies added to the project* + version Display the version of the project + help Print this message or the help of the given subcommand(s) ``` _"*" indicates first-pass of implementation is incomplete._ From cd65873224c3a2f42b5022a82199dc08d5553994 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 12:38:44 +0200 Subject: [PATCH 06/30] updated the catch all case for the shell match and added a docstring for the completion::run function --- src/bin/huak/commands/completion.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 7ae12331..8240a707 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -4,6 +4,9 @@ use crate::errors::CliResult; use clap::CommandFactory; use clap_complete::{generate, Shell}; +/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This +/// way if the user runs completion > completion.sh only the stdout will be redirected into +/// completion.sh. pub fn run(shell: Shell) -> CliResult<()> { let mut cmd = Cli::command(); @@ -82,5 +85,9 @@ Ensure that the following is present in your `~/.zshrc`: // There should probably be a link to the github issues page for this since if this is triggered it // means clap_complete was upgraded but the added shell was not handled. fn completion_help_unknown(_cmd_name: &str) -> String { - format!(r##""##) + format!( + r##"The completion script generation is not implemented for this shell. Head over to +https://github.com/cnpryer/huak/issues to file an issue to add support. +"## + ) } From e1cde1b8780a4a78a61eacfdc7fd300483811a3e Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 12:42:14 +0200 Subject: [PATCH 07/30] removed fixed comment --- src/bin/huak/commands/completion.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 8240a707..53e7297d 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -81,9 +81,6 @@ Ensure that the following is present in your `~/.zshrc`: ) } -// TODO -// There should probably be a link to the github issues page for this since if this is triggered it -// means clap_complete was upgraded but the added shell was not handled. fn completion_help_unknown(_cmd_name: &str) -> String { format!( r##"The completion script generation is not implemented for this shell. Head over to From d3b225e5a98b1e094eea92ebcf2629bb5bdf59f7 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 15:20:13 +0200 Subject: [PATCH 08/30] added elvish suggestion --- src/bin/huak/commands/completion.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 53e7297d..34c774f6 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -43,7 +43,11 @@ After, add this to your `~/.bash_profile`: // TODO fn completion_help_elvish(_cmd_name: &str) -> String { - format!(r##""##) + format!( + r##"This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. + +If you are able to test this please head over to https://github.com/cnpryer/huak/issues and file an issue"## + ) } fn completion_help_fish(cmd_name: &str) -> String { @@ -83,7 +87,7 @@ Ensure that the following is present in your `~/.zshrc`: fn completion_help_unknown(_cmd_name: &str) -> String { format!( - r##"The completion script generation is not implemented for this shell. Head over to + r##"The completion script generation is not implemented for this shell. Head over to https://github.com/cnpryer/huak/issues to file an issue to add support. "## ) From 7cb5a46fec5611e08fef97ee68abe2202b70217a Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 15:21:03 +0200 Subject: [PATCH 09/30] swapped the order of printing the script and printing the suggestion, it now prints the suggestion last --- src/bin/huak/commands/completion.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 34c774f6..89cf13cc 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -25,9 +25,9 @@ pub fn run(shell: Shell) -> CliResult<()> { _ => completion_help_unknown(&cmd_name), }; - eprintln!("{}", help_output); - generate(shell, &mut cmd, &cmd_name, &mut std::io::stdout()); + + eprintln!("{}", help_output); Ok(()) } From bfc379fc39333c4559ee7a887d75f8a89814a70c Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 17:29:11 +0200 Subject: [PATCH 10/30] fixed clippy lints --- src/bin/huak/commands/completion.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 89cf13cc..cabaaf43 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -43,11 +43,9 @@ After, add this to your `~/.bash_profile`: // TODO fn completion_help_elvish(_cmd_name: &str) -> String { - format!( - r##"This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. + r##"This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. -If you are able to test this please head over to https://github.com/cnpryer/huak/issues and file an issue"## - ) +If you are able to test this please head over to https://github.com/cnpryer/huak/issues and file an issue"##.to_string() } fn completion_help_fish(cmd_name: &str) -> String { @@ -86,9 +84,7 @@ Ensure that the following is present in your `~/.zshrc`: } fn completion_help_unknown(_cmd_name: &str) -> String { - format!( - r##"The completion script generation is not implemented for this shell. Head over to + r##"The completion script generation is not implemented for this shell. Head over to https://github.com/cnpryer/huak/issues to file an issue to add support. -"## - ) +"##.to_string() } From e8a250e3188aed2bc880361d9c12eb9f43c5004f Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 19:13:39 +0200 Subject: [PATCH 11/30] removed rename reference in suggestion text --- src/bin/huak/commands/completion.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index cabaaf43..5b159224 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -36,7 +36,7 @@ fn completion_help_bash(cmd_name: &str) -> String { r##""First, ensure that you install `bash-completion` using your package manager. After, add this to your `~/.bash_profile`: -`eval "$({cmd_name} completion bash --rename {cmd_name})"` +`eval "$({cmd_name} completion bash)"` "## ) } @@ -52,7 +52,7 @@ fn completion_help_fish(cmd_name: &str) -> String { format!( r##"Generate a `tool.fish` completion script: -`{cmd_name} completion fish --rename {cmd_name} > ~/.config/fish/completions/{cmd_name}.fish` +`{cmd_name} completion fish > ~/.config/fish/completions/{cmd_name}.fish` "## ) } @@ -65,7 +65,7 @@ fn completion_help_powershell(cmd_name: &str) -> String { `notepad $profile` Add the line and save the file: -`Invoke-Expression -Command $({cmd_name} completion powershell --rename {cmd_name} | Out-String)` +`Invoke-Expression -Command $({cmd_name} completion powershell| Out-String)` "## ) } @@ -73,7 +73,7 @@ Add the line and save the file: fn completion_help_zsh(cmd_name: &str) -> String { format!( r##"Generate a `_{cmd_name}` completion script and put it somewhere in your `$fpath`: -`{cmd_name} completion zsh --rename {cmd_name} > /usr/local/share/zsh/site-functions/_{cmd_name}` +`{cmd_name} completion zsh > /usr/local/share/zsh/site-functions/_{cmd_name}` Ensure that the following is present in your `~/.zshrc`: From 6e0cfee2339e02d0b1ba11a1c7ed43dd3726a08c Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 19:32:29 +0200 Subject: [PATCH 12/30] removed suggestion output --- src/bin/huak/commands/completion.rs | 71 ----------------------------- 1 file changed, 71 deletions(-) diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs index 5b159224..38129c83 100644 --- a/src/bin/huak/commands/completion.rs +++ b/src/bin/huak/commands/completion.rs @@ -14,77 +14,6 @@ pub fn run(shell: Shell) -> CliResult<()> { // in the generate() function. let cmd_name = String::from(Cli::command().get_name()); - let help_output = match &shell { - Shell::Bash => completion_help_bash(&cmd_name), - Shell::Elvish => completion_help_elvish(&cmd_name), - Shell::Fish => completion_help_fish(&cmd_name), - Shell::PowerShell => completion_help_powershell(&cmd_name), - Shell::Zsh => completion_help_zsh(&cmd_name), - - // We need this since the Shell enum is marked as non exhaustive - _ => completion_help_unknown(&cmd_name), - }; - generate(shell, &mut cmd, &cmd_name, &mut std::io::stdout()); - - eprintln!("{}", help_output); Ok(()) } - -fn completion_help_bash(cmd_name: &str) -> String { - format!( - r##""First, ensure that you install `bash-completion` using your package manager. -After, add this to your `~/.bash_profile`: - -`eval "$({cmd_name} completion bash)"` -"## - ) -} - -// TODO -fn completion_help_elvish(_cmd_name: &str) -> String { - r##"This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. - -If you are able to test this please head over to https://github.com/cnpryer/huak/issues and file an issue"##.to_string() -} - -fn completion_help_fish(cmd_name: &str) -> String { - format!( - r##"Generate a `tool.fish` completion script: - -`{cmd_name} completion fish > ~/.config/fish/completions/{cmd_name}.fish` -"## - ) -} - -fn completion_help_powershell(cmd_name: &str) -> String { - format!( - r##"Open your profile script with: - -`mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue` -`notepad $profile` - -Add the line and save the file: -`Invoke-Expression -Command $({cmd_name} completion powershell| Out-String)` -"## - ) -} - -fn completion_help_zsh(cmd_name: &str) -> String { - format!( - r##"Generate a `_{cmd_name}` completion script and put it somewhere in your `$fpath`: -`{cmd_name} completion zsh > /usr/local/share/zsh/site-functions/_{cmd_name}` - -Ensure that the following is present in your `~/.zshrc`: - -`autoload -U compinit` -`compinit -i` -"## - ) -} - -fn completion_help_unknown(_cmd_name: &str) -> String { - r##"The completion script generation is not implemented for this shell. Head over to -https://github.com/cnpryer/huak/issues to file an issue to add support. -"##.to_string() -} From f850f43e0fff666b93e9770f4f8a7f440cd26c57 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 19:32:49 +0200 Subject: [PATCH 13/30] added documentation for shell completion scripts --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/huak/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/README.md b/README.md index f8f6e4f7..8a88b5f5 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,61 @@ _"*" indicates first-pass of implementation is incomplete._ Note that `huak activate` is currently only partially supported on Windows. See the related [issue](https://github.com/cnpryer/huak/issues/302) for more details. + + +## Shell completion + +##### Bash +First, ensure that you install `bash-completion` using your package manager. +After, add this to your `~/.bash_profile`: + +```bash +eval "$(huak completion bash)" +``` + +##### Elvish +This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. + +If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue +##### Fish +Generate a `tool.fish` completion script: + +```bash +huak completion fish > ~/.config/fish/completions/huak.fish +``` + +##### Powershell +Open your profile script with: + +```bash +mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue +``` + +```bash +notepad $profile +``` + +Add the line and save the file: +```bash +Invoke-Expression -Command $(huak completion powershell| Out-String) +``` + +##### Zsh +Generate a `_huak` completion script and put it somewhere in your `$fpath`: +```bash +huak completion zsh > /usr/local/share/zsh/site-functions/_huak +``` + +Ensure that the following is present in your `~/.zshrc`: + +```bash +autoload -U compinit +``` + +```bash +compinit -i +``` + ## Documentation If you've cloned the repository, run `cargo doc --open`. diff --git a/src/huak/lib.rs b/src/huak/lib.rs index fb2c607e..f1a484d5 100644 --- a/src/huak/lib.rs +++ b/src/huak/lib.rs @@ -28,6 +28,60 @@ //! //!Around 0.1.0 you'll be able to install `huak` using `brew` or `pip`. Distribution plans will be finalized closer to 0.1.0. //! +//!## Shell completion +//! +//!##### Bash +//!First, ensure that you install `bash-completion` using your package manager. +//!After, add this to your `~/.bash_profile`: +//! +//!```bash +//! eval "$(huak completion bash)" +//!``` +//! +//!##### Elvish +//!This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. +//! +//!If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue +//!##### Fish +//!Generate a `tool.fish` completion script: +//! +//!```bash +//! huak completion fish > ~/.config/fish/completions/huak.fish +//!``` +//! +//!##### Powershell +//!Open your profile script with: +//! +//!```bash +//! mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue +//!``` +//! +//!```bash +//! notepad $profile +//!``` +//! +//!Add the line and save the file: +//!```bash +//! Invoke-Expression -Command $(huak completion powershell| Out-String) +//!``` +//! +//!##### Zsh +//!Generate a `_huak` completion script and put it somewhere in your `$fpath`: +//!```bash +//! huak completion zsh > /usr/local/share/zsh/site-functions/_huak +//!``` +//! +//!Ensure that the following is present in your `~/.zshrc`: +//! +//!```bash +//! autoload -U compinit +//!``` +//! +//!```bash +//! compinit -i +//!``` +//! +//! //!## Goals //! //!Besides some of my own experience with the Python ecosystem, there are a few additional guiding principles steering the development of Huak: From e29b630243bedca2e5e8f7f56faef00d206bbd27 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Wed, 26 Oct 2022 19:34:25 +0200 Subject: [PATCH 14/30] fixed copied typo --- README.md | 2 +- src/huak/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a88b5f5..8c8f582a 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ This shell is supported, but the suggestion as to how this should be added to yo If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue ##### Fish -Generate a `tool.fish` completion script: +Generate a `huak.fish` completion script: ```bash huak completion fish > ~/.config/fish/completions/huak.fish diff --git a/src/huak/lib.rs b/src/huak/lib.rs index f1a484d5..184b714c 100644 --- a/src/huak/lib.rs +++ b/src/huak/lib.rs @@ -43,7 +43,7 @@ //! //!If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue //!##### Fish -//!Generate a `tool.fish` completion script: +//!Generate a `huak.fish` completion script: //! //!```bash //! huak completion fish > ~/.config/fish/completions/huak.fish From d0e692b32d5c5e40cb98d3dee3a456492a4bddc6 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen <45570310+MitchellBerend@users.noreply.github.com> Date: Thu, 27 Oct 2022 10:11:07 +0200 Subject: [PATCH 15/30] Added extra newline in docs Co-authored-by: Chris Pryer <14341145+cnpryer@users.noreply.github.com> --- src/huak/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/huak/lib.rs b/src/huak/lib.rs index 184b714c..c5e66fbc 100644 --- a/src/huak/lib.rs +++ b/src/huak/lib.rs @@ -42,6 +42,7 @@ //!This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. //! //!If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue + //!##### Fish //!Generate a `huak.fish` completion script: //! From 363864d60fc497b5eb24a66a910987c96d33e26a Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Fri, 28 Oct 2022 11:19:15 +0200 Subject: [PATCH 16/30] added a config command and a completion sub command to that --- src/bin/huak/commands/completion.rs | 19 -------------- src/bin/huak/commands/config.rs | 40 +++++++++++++++++++++++++++++ src/bin/huak/commands/mod.rs | 11 ++++---- 3 files changed, 45 insertions(+), 25 deletions(-) delete mode 100644 src/bin/huak/commands/completion.rs create mode 100644 src/bin/huak/commands/config.rs diff --git a/src/bin/huak/commands/completion.rs b/src/bin/huak/commands/completion.rs deleted file mode 100644 index 38129c83..00000000 --- a/src/bin/huak/commands/completion.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::commands::Cli; -use crate::errors::CliResult; - -use clap::CommandFactory; -use clap_complete::{generate, Shell}; - -/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This -/// way if the user runs completion > completion.sh only the stdout will be redirected into -/// completion.sh. -pub fn run(shell: Shell) -> CliResult<()> { - let mut cmd = Cli::command(); - - // We can't take a reference to the cmd variable since we also need a mutable reference to this - // in the generate() function. - let cmd_name = String::from(Cli::command().get_name()); - - generate(shell, &mut cmd, &cmd_name, &mut std::io::stdout()); - Ok(()) -} diff --git a/src/bin/huak/commands/config.rs b/src/bin/huak/commands/config.rs new file mode 100644 index 00000000..583315fe --- /dev/null +++ b/src/bin/huak/commands/config.rs @@ -0,0 +1,40 @@ +use crate::commands::Cli; +use crate::errors::CliResult; + +use clap::{Args, CommandFactory, Subcommand}; +use clap_complete::{generate, Shell}; + +/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This +/// way if the user runs completion > completion.sh only the stdout will be redirected into +/// completion.sh. +pub fn run(config_command: Config) -> CliResult<()> { + match config_command.command { + ConfigCommand::Completion { shell } => { + generate_shell_completion_script(Some(shell)) + } + } + Ok(()) +} + +fn generate_shell_completion_script(shell: Option) { + let mut cmd = Cli::command(); + + // We can't take a reference to the cmd variable since we also need a mutable reference to this + // in the generate() function. + let cmd_name = String::from(Cli::command().get_name()); + + generate(shell.unwrap(), &mut cmd, &cmd_name, &mut std::io::stdout()) +} + +#[derive(Args)] +pub struct Config { + /// Generates a shell completion script for supported shells. + /// See the help menu for more information on supported shells. + #[command(subcommand)] + command: ConfigCommand, +} + +#[derive(Debug, Subcommand)] +pub enum ConfigCommand { + Completion { shell: Shell }, +} diff --git a/src/bin/huak/commands/mod.rs b/src/bin/huak/commands/mod.rs index 656ab49c..fbef6065 100644 --- a/src/bin/huak/commands/mod.rs +++ b/src/bin/huak/commands/mod.rs @@ -1,13 +1,13 @@ use crate::errors::CliResult; + use clap::{Parser, Subcommand}; -use clap_complete::Shell; pub(crate) mod activate; pub(crate) mod add; pub(crate) mod audit; pub(crate) mod build; pub(crate) mod clean; -pub(crate) mod completion; +pub(crate) mod config; pub(crate) mod doc; pub(crate) mod fix; pub(crate) mod fmt; @@ -48,9 +48,8 @@ pub enum Commands { Audit, /// Build tarball and wheel for the project. Build, - /// Generates a shell completion script for supported shells. - /// See the help menu for more information on supported shells. - Completion { shell: Shell }, + /// Interact with the configuration of huak. + Config(config::Config), /// Remove tarball and wheel from the built project. Clean { #[arg(long, required = false)] @@ -124,7 +123,7 @@ pub enum Commands { impl Cli { pub fn run(self) -> CliResult<()> { match self.command { - Commands::Completion { shell } => completion::run(shell), + Commands::Config(config_command) => config::run(config_command), Commands::Activate => activate::run(), Commands::Add { dependency, dev } => add::run(dependency, dev), Commands::Audit => audit::run(), From 9da5a62b865e75a624036f2a06bd70d166096c88 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen <45570310+MitchellBerend@users.noreply.github.com> Date: Fri, 28 Oct 2022 15:28:47 +0200 Subject: [PATCH 17/30] Deleting forgotten section from the README.md Co-authored-by: Chris Pryer <14341145+cnpryer@users.noreply.github.com> --- README.md | 55 ------------------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/README.md b/README.md index 8c8f582a..f8f6e4f7 100644 --- a/README.md +++ b/README.md @@ -93,61 +93,6 @@ _"*" indicates first-pass of implementation is incomplete._ Note that `huak activate` is currently only partially supported on Windows. See the related [issue](https://github.com/cnpryer/huak/issues/302) for more details. - - -## Shell completion - -##### Bash -First, ensure that you install `bash-completion` using your package manager. -After, add this to your `~/.bash_profile`: - -```bash -eval "$(huak completion bash)" -``` - -##### Elvish -This shell is supported, but the suggestion as to how this should be added to your shell init file is missing. - -If you are able to test this please head over to [github](https://github.com/cnpryer/huak/issues) and file an issue -##### Fish -Generate a `huak.fish` completion script: - -```bash -huak completion fish > ~/.config/fish/completions/huak.fish -``` - -##### Powershell -Open your profile script with: - -```bash -mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue -``` - -```bash -notepad $profile -``` - -Add the line and save the file: -```bash -Invoke-Expression -Command $(huak completion powershell| Out-String) -``` - -##### Zsh -Generate a `_huak` completion script and put it somewhere in your `$fpath`: -```bash -huak completion zsh > /usr/local/share/zsh/site-functions/_huak -``` - -Ensure that the following is present in your `~/.zshrc`: - -```bash -autoload -U compinit -``` - -```bash -compinit -i -``` - ## Documentation If you've cloned the repository, run `cargo doc --open`. From 9563d18a9cd585bebeec47e0eb781def4b4d56e4 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Fri, 28 Oct 2022 11:30:19 +0200 Subject: [PATCH 18/30] moved comment from config struct to the actual command enum --- src/bin/huak/commands/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/huak/commands/config.rs b/src/bin/huak/commands/config.rs index 583315fe..bd352c6f 100644 --- a/src/bin/huak/commands/config.rs +++ b/src/bin/huak/commands/config.rs @@ -28,13 +28,13 @@ fn generate_shell_completion_script(shell: Option) { #[derive(Args)] pub struct Config { - /// Generates a shell completion script for supported shells. - /// See the help menu for more information on supported shells. #[command(subcommand)] command: ConfigCommand, } #[derive(Debug, Subcommand)] pub enum ConfigCommand { + /// Generates a shell completion script for supported shells. + /// See the help menu for more information on supported shells. Completion { shell: Shell }, } From 45d62fe327883cb78db1b690482bd205305c8275 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Fri, 28 Oct 2022 15:33:32 +0200 Subject: [PATCH 19/30] updated file structure --- src/bin/huak/commands/{config.rs => config/completion.rs} | 0 src/bin/huak/commands/config/mod.rs | 2 ++ 2 files changed, 2 insertions(+) rename src/bin/huak/commands/{config.rs => config/completion.rs} (100%) create mode 100644 src/bin/huak/commands/config/mod.rs diff --git a/src/bin/huak/commands/config.rs b/src/bin/huak/commands/config/completion.rs similarity index 100% rename from src/bin/huak/commands/config.rs rename to src/bin/huak/commands/config/completion.rs diff --git a/src/bin/huak/commands/config/mod.rs b/src/bin/huak/commands/config/mod.rs new file mode 100644 index 00000000..a0bb649b --- /dev/null +++ b/src/bin/huak/commands/config/mod.rs @@ -0,0 +1,2 @@ +mod completion; +pub use completion::*; From 2a9dc6247d3a241f5f75fdfa9da3ff01145a4ea1 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sat, 29 Oct 2022 16:47:01 +0200 Subject: [PATCH 20/30] added install and uninstall commands to automatically add shell completion script to init files --- src/bin/huak/commands/config/completion.rs | 39 +++- src/huak/lib.rs | 8 +- src/huak/ops/config.rs | 260 +++++++++++++++++++++ src/huak/ops/mod.rs | 1 + test_files/test_bashrc | 2 + 5 files changed, 298 insertions(+), 12 deletions(-) create mode 100644 src/huak/ops/config.rs create mode 100644 test_files/test_bashrc diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index bd352c6f..c94af23f 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -1,7 +1,9 @@ use crate::commands::Cli; use crate::errors::CliResult; -use clap::{Args, CommandFactory, Subcommand}; +use huak::ops::config; + +use clap::{Args, Command, CommandFactory, Subcommand}; use clap_complete::{generate, Shell}; /// Prints the script to stdout and a way to add the script to the shell init file to stderr. This @@ -10,20 +12,37 @@ use clap_complete::{generate, Shell}; pub fn run(config_command: Config) -> CliResult<()> { match config_command.command { ConfigCommand::Completion { shell } => { - generate_shell_completion_script(Some(shell)) + generate_shell_completion_script(shell) + } + ConfigCommand::Install { shell } => { + let mut cmd: Command = Cli::command(); + let _result = match shell { + Shell::Bash => config::_add_completion_bash(), + Shell::Elvish => config::_add_completion_elvish(), + Shell::Fish => config::_add_completion_fish(&mut cmd), + Shell::PowerShell => config::_add_completion_powershell(), + Shell::Zsh => config::_add_completion_zsh(&mut cmd), + _ => Ok(()), + }; + } + ConfigCommand::Uninstall { shell } => { + let _result = match shell { + Shell::Bash => config::_remove_completion_bash(), + Shell::Elvish => config::_remove_completion_elvish(), + Shell::Fish => config::_remove_completion_fish(), + Shell::PowerShell => config::_remove_completion_powershell(), + Shell::Zsh => config::_remove_completion_zsh(), + _ => Ok(()), + }; } } Ok(()) } -fn generate_shell_completion_script(shell: Option) { +fn generate_shell_completion_script(shell: Shell) { let mut cmd = Cli::command(); - // We can't take a reference to the cmd variable since we also need a mutable reference to this - // in the generate() function. - let cmd_name = String::from(Cli::command().get_name()); - - generate(shell.unwrap(), &mut cmd, &cmd_name, &mut std::io::stdout()) + generate(shell, &mut cmd, "huak", &mut std::io::stdout()) } #[derive(Args)] @@ -37,4 +56,8 @@ pub enum ConfigCommand { /// Generates a shell completion script for supported shells. /// See the help menu for more information on supported shells. Completion { shell: Shell }, + /// Installs the completion script in your shell init file. + Install { shell: Shell }, + /// Uninstalls the completion script from your shell init file. + Uninstall { shell: Shell }, } diff --git a/src/huak/lib.rs b/src/huak/lib.rs index c5e66fbc..a56a4901 100644 --- a/src/huak/lib.rs +++ b/src/huak/lib.rs @@ -35,7 +35,7 @@ //!After, add this to your `~/.bash_profile`: //! //!```bash -//! eval "$(huak completion bash)" +//! eval "$(huak config completion bash)" //!``` //! //!##### Elvish @@ -47,7 +47,7 @@ //!Generate a `huak.fish` completion script: //! //!```bash -//! huak completion fish > ~/.config/fish/completions/huak.fish +//! huak config completion fish > ~/.config/fish/completions/huak.fish //!``` //! //!##### Powershell @@ -63,13 +63,13 @@ //! //!Add the line and save the file: //!```bash -//! Invoke-Expression -Command $(huak completion powershell| Out-String) +//! Invoke-Expression -Command $(huak config completion powershell| Out-String) //!``` //! //!##### Zsh //!Generate a `_huak` completion script and put it somewhere in your `$fpath`: //!```bash -//! huak completion zsh > /usr/local/share/zsh/site-functions/_huak +//! huak config completion zsh > /usr/local/share/zsh/site-functions/_huak //!``` //! //!Ensure that the following is present in your `~/.zshrc`: diff --git a/src/huak/ops/config.rs b/src/huak/ops/config.rs new file mode 100644 index 00000000..f5d1c2c3 --- /dev/null +++ b/src/huak/ops/config.rs @@ -0,0 +1,260 @@ +use std::fs::File; +use std::io::{Error, Write}; +use std::path::Path; + +use clap::Command; +use clap_complete::{generate, Shell}; + +/// Bash has a couple of files that can contain the actual completion script. +/// Only the line `eval "$(huak config completion bash)"` needs to be added +/// These files are loaded in the following order: +/// ~/.bash_profile +/// ~/.bash_login +/// ~/.profile +/// ~/.bashrc +pub fn _add_completion_bash() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") + } + }; + + let _file_path = format!("{}/.bashrc", home); + + #[cfg(test)] + let _file_path = format!("test_files/test_bashrc"); + + // opening file in append mode + let mut file: File = File::options().append(true).open(_file_path)?; + + // This needs to be a string since there will be a \n prepended if it is + file.write_all( + r##"eval "$(huak config completion bash)""## + .to_string() + .as_bytes(), + )?; + + Ok(()) +} + +// TODO +pub fn _add_completion_elvish() -> Result<(), Error> { + todo!() +} + +/// huak config completion fish > ~/.config/fish/completions/huak.fish +/// Fish has a completions directory in which all files are loaded on init. +/// The naming convention is $HOME/.config/fish/completions/huak.fish +pub fn _add_completion_fish(cli: &mut Command) -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") + } + }; + + let _target_file = format!("{}/.config/fish/completions/huak.fish", home); + + #[cfg(test)] + let _target_file = "test_files/test_fish".to_string(); + + generate_target_file(_target_file, cli)?; + Ok(()) +} + +// TODO +pub fn _add_completion_powershell() -> Result<(), Error> { + todo!() +} + +/// Zsh and fish are the same in the sense that the use an entire directory to collect shell init +/// scripts. +pub fn _add_completion_zsh(cli: &mut Command) -> Result<(), Error> { + let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); + + #[cfg(test)] + let _target_file = "test_files/test_zsh".to_string(); + + generate_target_file(_target_file, cli)?; + Ok(()) +} + +/// Reads the entire file and removes lines that match exactly with: +/// \neval "$(huak config completion) +pub fn _remove_completion_bash() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") + } + }; + + let _file_path = format!("{}/.bashrc", home); + + #[cfg(test)] + let _file_path = format!("test_files/test_bashrc"); + + let file_content = std::fs::read_to_string(&_file_path)?; + let new_content = file_content.replace( + &format!(r##"{}eval "$(huak config completion bash)""##, '\n'), + "", + ); + + std::fs::write(&_file_path, new_content)?; + + Ok(()) +} + +// TODO +pub fn _remove_completion_elvish() -> Result<(), Error> { + todo!() +} + +pub fn _remove_completion_fish() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") + } + }; + + let _target_file = format!("{}/.config/fish/completions/huak.fish", home); + + #[cfg(test)] + let _target_file = "test_files/test_fish".to_string(); + + std::fs::remove_file(_target_file)?; + + Ok(()) +} + +// TODO +pub fn _remove_completion_powershell() -> Result<(), Error> { + todo!() +} + +pub fn _remove_completion_zsh() -> Result<(), Error> { + let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); + + #[cfg(test)] + let _target_file = "test_files/test_zsh".to_string(); + + std::fs::remove_file(_target_file)?; + + Ok(()) +} + +fn generate_target_file

( + target_file: P, + cmd: &mut Command, +) -> Result<(), Error> +where + P: AsRef, +{ + let mut file: File = File::create(&target_file)?; + + generate(Shell::Fish, cmd, "huak", &mut file); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + use clap::{Command, CommandFactory, Parser}; + + #[derive(Parser)] + struct Cli {} + + #[test] + /// This test ensures the order of operations is always correct + fn test_bash_completion() { + test_adding_completion_bash(); + test_remove_completion_bash(); + } + + fn test_adding_completion_bash() { + let _ = _add_completion_bash(); + + let file_content = + fs::read_to_string("test_files/test_bashrc").unwrap(); + + assert_eq!( + format!( + r##"# This stuff is in here so there is something that should be left over after +# removing the bash completion script +eval "$(huak config completion bash)""## + ), + file_content + ) + } + + fn test_remove_completion_bash() { + let _ = _remove_completion_bash(); + + let file_content = + fs::read_to_string("test_files/test_bashrc").unwrap(); + + assert_eq!("# This stuff is in here so there is something that should be left over after +# removing the bash completion script", file_content) + } + + #[test] + /// This test ensures the order of operations is always correct + fn test_fish_completion() { + let mut cmd = Cli::command(); + + test_adding_completion_fish(&mut cmd); + test_remove_completion_fish(); + } + + fn test_adding_completion_fish(cmd: &mut Command) { + let _ = _add_completion_fish(cmd); + + let result = std::fs::read_to_string("test_files/test_fish"); + + assert_eq!(true, result.is_ok()); + } + + fn test_remove_completion_fish() { + let _ = _remove_completion_fish(); + + let result = std::fs::read("test_files/test_fish"); + assert_eq!(true, result.is_err()); + } + + #[test] + /// This test ensures the order of operations is always correct + fn test_zsh_completion() { + let mut cmd = Cli::command(); + + test_adding_completion_zsh(&mut cmd); + test_remove_completion_zsh(); + } + + fn test_adding_completion_zsh(cmd: &mut Command) { + let _ = _add_completion_zsh(cmd); + + let result = std::fs::read_to_string("test_files/test_zsh"); + + assert_eq!(true, result.is_ok()); + } + + fn test_remove_completion_zsh() { + let _ = _remove_completion_zsh(); + + let result = std::fs::read("test_files/test_zsh"); + assert_eq!(true, result.is_err()); + } +} diff --git a/src/huak/ops/mod.rs b/src/huak/ops/mod.rs index b7e58b36..280c73fc 100644 --- a/src/huak/ops/mod.rs +++ b/src/huak/ops/mod.rs @@ -2,6 +2,7 @@ pub mod activate; pub mod add; pub mod build; pub mod clean; +pub mod config; pub mod fix; pub mod fmt; pub mod init; diff --git a/test_files/test_bashrc b/test_files/test_bashrc new file mode 100644 index 00000000..abc3cc1a --- /dev/null +++ b/test_files/test_bashrc @@ -0,0 +1,2 @@ +# This stuff is in here so there is something that should be left over after +# removing the bash completion script \ No newline at end of file From 35a59a4f0368c8c2a5213b0250027872c2aef125 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen <45570310+MitchellBerend@users.noreply.github.com> Date: Sun, 30 Oct 2022 09:59:12 +0100 Subject: [PATCH 21/30] Update src/bin/huak/commands/config/completion.rs Co-authored-by: Chris Pryer <14341145+cnpryer@users.noreply.github.com> --- src/bin/huak/commands/config/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index c94af23f..1f3a4f52 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -52,7 +52,7 @@ pub struct Config { } #[derive(Debug, Subcommand)] -pub enum ConfigCommand { +pub enum Config { /// Generates a shell completion script for supported shells. /// See the help menu for more information on supported shells. Completion { shell: Shell }, From 10d5016614d01fec0cafbbd9b48830f3af27befb Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sun, 30 Oct 2022 10:34:58 +0100 Subject: [PATCH 22/30] added new line to end of file --- test_files/test_bashrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_files/test_bashrc b/test_files/test_bashrc index abc3cc1a..3611c4b3 100644 --- a/test_files/test_bashrc +++ b/test_files/test_bashrc @@ -1,2 +1,3 @@ # This stuff is in here so there is something that should be left over after -# removing the bash completion script \ No newline at end of file +# removing the bash completion script + From b7c81ea5fb59b791602b468a6bbadbeb6c01d410 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sun, 30 Oct 2022 10:35:40 +0100 Subject: [PATCH 23/30] removed config from ops --- src/huak/ops/config.rs | 260 ----------------------------------------- 1 file changed, 260 deletions(-) delete mode 100644 src/huak/ops/config.rs diff --git a/src/huak/ops/config.rs b/src/huak/ops/config.rs deleted file mode 100644 index f5d1c2c3..00000000 --- a/src/huak/ops/config.rs +++ /dev/null @@ -1,260 +0,0 @@ -use std::fs::File; -use std::io::{Error, Write}; -use std::path::Path; - -use clap::Command; -use clap_complete::{generate, Shell}; - -/// Bash has a couple of files that can contain the actual completion script. -/// Only the line `eval "$(huak config completion bash)"` needs to be added -/// These files are loaded in the following order: -/// ~/.bash_profile -/// ~/.bash_login -/// ~/.profile -/// ~/.bashrc -pub fn _add_completion_bash() -> Result<(), Error> { - let home = match std::env::var("HOME") { - Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } - }; - - let _file_path = format!("{}/.bashrc", home); - - #[cfg(test)] - let _file_path = format!("test_files/test_bashrc"); - - // opening file in append mode - let mut file: File = File::options().append(true).open(_file_path)?; - - // This needs to be a string since there will be a \n prepended if it is - file.write_all( - r##"eval "$(huak config completion bash)""## - .to_string() - .as_bytes(), - )?; - - Ok(()) -} - -// TODO -pub fn _add_completion_elvish() -> Result<(), Error> { - todo!() -} - -/// huak config completion fish > ~/.config/fish/completions/huak.fish -/// Fish has a completions directory in which all files are loaded on init. -/// The naming convention is $HOME/.config/fish/completions/huak.fish -pub fn _add_completion_fish(cli: &mut Command) -> Result<(), Error> { - let home = match std::env::var("HOME") { - Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } - }; - - let _target_file = format!("{}/.config/fish/completions/huak.fish", home); - - #[cfg(test)] - let _target_file = "test_files/test_fish".to_string(); - - generate_target_file(_target_file, cli)?; - Ok(()) -} - -// TODO -pub fn _add_completion_powershell() -> Result<(), Error> { - todo!() -} - -/// Zsh and fish are the same in the sense that the use an entire directory to collect shell init -/// scripts. -pub fn _add_completion_zsh(cli: &mut Command) -> Result<(), Error> { - let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); - - #[cfg(test)] - let _target_file = "test_files/test_zsh".to_string(); - - generate_target_file(_target_file, cli)?; - Ok(()) -} - -/// Reads the entire file and removes lines that match exactly with: -/// \neval "$(huak config completion) -pub fn _remove_completion_bash() -> Result<(), Error> { - let home = match std::env::var("HOME") { - Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } - }; - - let _file_path = format!("{}/.bashrc", home); - - #[cfg(test)] - let _file_path = format!("test_files/test_bashrc"); - - let file_content = std::fs::read_to_string(&_file_path)?; - let new_content = file_content.replace( - &format!(r##"{}eval "$(huak config completion bash)""##, '\n'), - "", - ); - - std::fs::write(&_file_path, new_content)?; - - Ok(()) -} - -// TODO -pub fn _remove_completion_elvish() -> Result<(), Error> { - todo!() -} - -pub fn _remove_completion_fish() -> Result<(), Error> { - let home = match std::env::var("HOME") { - Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } - }; - - let _target_file = format!("{}/.config/fish/completions/huak.fish", home); - - #[cfg(test)] - let _target_file = "test_files/test_fish".to_string(); - - std::fs::remove_file(_target_file)?; - - Ok(()) -} - -// TODO -pub fn _remove_completion_powershell() -> Result<(), Error> { - todo!() -} - -pub fn _remove_completion_zsh() -> Result<(), Error> { - let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); - - #[cfg(test)] - let _target_file = "test_files/test_zsh".to_string(); - - std::fs::remove_file(_target_file)?; - - Ok(()) -} - -fn generate_target_file

( - target_file: P, - cmd: &mut Command, -) -> Result<(), Error> -where - P: AsRef, -{ - let mut file: File = File::create(&target_file)?; - - generate(Shell::Fish, cmd, "huak", &mut file); - - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - use std::fs; - - use clap::{Command, CommandFactory, Parser}; - - #[derive(Parser)] - struct Cli {} - - #[test] - /// This test ensures the order of operations is always correct - fn test_bash_completion() { - test_adding_completion_bash(); - test_remove_completion_bash(); - } - - fn test_adding_completion_bash() { - let _ = _add_completion_bash(); - - let file_content = - fs::read_to_string("test_files/test_bashrc").unwrap(); - - assert_eq!( - format!( - r##"# This stuff is in here so there is something that should be left over after -# removing the bash completion script -eval "$(huak config completion bash)""## - ), - file_content - ) - } - - fn test_remove_completion_bash() { - let _ = _remove_completion_bash(); - - let file_content = - fs::read_to_string("test_files/test_bashrc").unwrap(); - - assert_eq!("# This stuff is in here so there is something that should be left over after -# removing the bash completion script", file_content) - } - - #[test] - /// This test ensures the order of operations is always correct - fn test_fish_completion() { - let mut cmd = Cli::command(); - - test_adding_completion_fish(&mut cmd); - test_remove_completion_fish(); - } - - fn test_adding_completion_fish(cmd: &mut Command) { - let _ = _add_completion_fish(cmd); - - let result = std::fs::read_to_string("test_files/test_fish"); - - assert_eq!(true, result.is_ok()); - } - - fn test_remove_completion_fish() { - let _ = _remove_completion_fish(); - - let result = std::fs::read("test_files/test_fish"); - assert_eq!(true, result.is_err()); - } - - #[test] - /// This test ensures the order of operations is always correct - fn test_zsh_completion() { - let mut cmd = Cli::command(); - - test_adding_completion_zsh(&mut cmd); - test_remove_completion_zsh(); - } - - fn test_adding_completion_zsh(cmd: &mut Command) { - let _ = _add_completion_zsh(cmd); - - let result = std::fs::read_to_string("test_files/test_zsh"); - - assert_eq!(true, result.is_ok()); - } - - fn test_remove_completion_zsh() { - let _ = _remove_completion_zsh(); - - let result = std::fs::read("test_files/test_zsh"); - assert_eq!(true, result.is_err()); - } -} From 8c3f749ff01bde4fdaf78c329759badd3e340f80 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sun, 30 Oct 2022 10:39:43 +0100 Subject: [PATCH 24/30] removed config --- src/huak/ops/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/huak/ops/mod.rs b/src/huak/ops/mod.rs index 280c73fc..b7e58b36 100644 --- a/src/huak/ops/mod.rs +++ b/src/huak/ops/mod.rs @@ -2,7 +2,6 @@ pub mod activate; pub mod add; pub mod build; pub mod clean; -pub mod config; pub mod fix; pub mod fmt; pub mod init; From 887c476b35f0dbb54bfa3ffdb813d4bb9b28afd0 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sun, 30 Oct 2022 10:40:09 +0100 Subject: [PATCH 25/30] moved config code to bin --- src/bin/huak/commands/config/completion.rs | 291 ++++++++++++++++++--- src/bin/huak/commands/config/mod.rs | 63 ++++- 2 files changed, 314 insertions(+), 40 deletions(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index 1f3a4f52..33e45409 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -1,54 +1,170 @@ -use crate::commands::Cli; -use crate::errors::CliResult; +use std::fs::File; +use std::io::{Error, Write}; +use std::path::Path; -use huak::ops::config; - -use clap::{Args, Command, CommandFactory, Subcommand}; +use clap::{Command, Subcommand}; use clap_complete::{generate, Shell}; -/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This -/// way if the user runs completion > completion.sh only the stdout will be redirected into -/// completion.sh. -pub fn run(config_command: Config) -> CliResult<()> { - match config_command.command { - ConfigCommand::Completion { shell } => { - generate_shell_completion_script(shell) +/// Bash has a couple of files that can contain the actual completion script. +/// Only the line `eval "$(huak config completion bash)"` needs to be added +/// These files are loaded in the following order: +/// ~/.bash_profile +/// ~/.bash_login +/// ~/.profile +/// ~/.bashrc +pub fn add_completion_bash() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") } - ConfigCommand::Install { shell } => { - let mut cmd: Command = Cli::command(); - let _result = match shell { - Shell::Bash => config::_add_completion_bash(), - Shell::Elvish => config::_add_completion_elvish(), - Shell::Fish => config::_add_completion_fish(&mut cmd), - Shell::PowerShell => config::_add_completion_powershell(), - Shell::Zsh => config::_add_completion_zsh(&mut cmd), - _ => Ok(()), - }; + }; + + let _file_path = format!("{}/.bashrc", home); + + #[cfg(test)] + let _file_path = format!("test_files/test_bashrc"); + + // opening file in append mode + let mut file: File = File::options().append(true).open(_file_path)?; + + // This needs to be a string since there will be a \n prepended if it is + file.write_all( + format!(r##"{}eval "$(huak config completion bash)"{}"##, '\n', '\n') + .to_string() + .as_bytes(), + )?; + + Ok(()) +} + +// TODO +pub fn add_completion_elvish() -> Result<(), Error> { + todo!() +} + +/// huak config completion fish > ~/.config/fish/completions/huak.fish +/// Fish has a completions directory in which all files are loaded on init. +/// The naming convention is $HOME/.config/fish/completions/huak.fish +pub fn add_completion_fish(cli: &mut Command) -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") } - ConfigCommand::Uninstall { shell } => { - let _result = match shell { - Shell::Bash => config::_remove_completion_bash(), - Shell::Elvish => config::_remove_completion_elvish(), - Shell::Fish => config::_remove_completion_fish(), - Shell::PowerShell => config::_remove_completion_powershell(), - Shell::Zsh => config::_remove_completion_zsh(), - _ => Ok(()), - }; + }; + + let _target_file = format!("{}/.config/fish/completions/huak.fish", home); + + #[cfg(test)] + let _target_file = "test_files/test_fish".to_string(); + + generate_target_file(_target_file, cli)?; + Ok(()) +} + +// TODO +pub fn add_completion_powershell() -> Result<(), Error> { + todo!() +} + +/// Zsh and fish are the same in the sense that the use an entire directory to collect shell init +/// scripts. +pub fn add_completion_zsh(cli: &mut Command) -> Result<(), Error> { + let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); + + #[cfg(test)] + let _target_file = "test_files/test_zsh".to_string(); + + generate_target_file(_target_file, cli)?; + Ok(()) +} + +/// Reads the entire file and removes lines that match exactly with: +/// \neval "$(huak config completion) +pub fn remove_completion_bash() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") } - } + }; + + let _file_path = format!("{}/.bashrc", home); + + #[cfg(test)] + let _file_path = format!("test_files/test_bashrc"); + + let file_content = std::fs::read_to_string(&_file_path)?; + let new_content = file_content.replace( + &format!(r##"{}eval "$(huak config completion bash)"{}"##, '\n', '\n'), + "", + ); + + std::fs::write(&_file_path, new_content)?; + Ok(()) } -fn generate_shell_completion_script(shell: Shell) { - let mut cmd = Cli::command(); +// TODO +pub fn remove_completion_elvish() -> Result<(), Error> { + todo!() +} + +pub fn remove_completion_fish() -> Result<(), Error> { + let home = match std::env::var("HOME") { + Ok(dir) => dir, + Err(e) => { + // defaulting to root, this might not be the right call + eprintln!("{}", e); + String::from("root") + } + }; - generate(shell, &mut cmd, "huak", &mut std::io::stdout()) + let _target_file = format!("{}/.config/fish/completions/huak.fish", home); + + #[cfg(test)] + let _target_file = "test_files/test_fish".to_string(); + + std::fs::remove_file(_target_file)?; + + Ok(()) +} + +// TODO +pub fn remove_completion_powershell() -> Result<(), Error> { + todo!() } -#[derive(Args)] -pub struct Config { - #[command(subcommand)] - command: ConfigCommand, +pub fn remove_completion_zsh() -> Result<(), Error> { + let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); + + #[cfg(test)] + let _target_file = "test_files/test_zsh".to_string(); + + std::fs::remove_file(_target_file)?; + + Ok(()) +} + +fn generate_target_file

( + target_file: P, + cmd: &mut Command, +) -> Result<(), Error> +where + P: AsRef, +{ + let mut file: File = File::create(&target_file)?; + + generate(Shell::Fish, cmd, "huak", &mut file); + + Ok(()) } #[derive(Debug, Subcommand)] @@ -61,3 +177,100 @@ pub enum Config { /// Uninstalls the completion script from your shell init file. Uninstall { shell: Shell }, } + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + use clap::{Command, CommandFactory, Parser}; + + #[derive(Parser)] + struct Cli {} + + #[test] + /// This test ensures the order of operations is always correct + fn test_bash_completion() { + test_adding_completion_bash(); + test_remove_completion_bash(); + } + + fn test_adding_completion_bash() { + let _ = add_completion_bash(); + + let file_content = + fs::read_to_string("test_files/test_bashrc").unwrap(); + + assert_eq!( + format!( + r##"# This stuff is in here so there is something that should be left over after +# removing the bash completion script + + +eval "$(huak config completion bash)" +"## + ), + file_content + ) + } + + fn test_remove_completion_bash() { + let _ = remove_completion_bash(); + + let file_content = + fs::read_to_string("test_files/test_bashrc").unwrap(); + + assert_eq!("# This stuff is in here so there is something that should be left over after +# removing the bash completion script + +", file_content) + } + + #[test] + /// This test ensures the order of operations is always correct + fn test_fish_completion() { + let mut cmd = Cli::command(); + + test_adding_completion_fish(&mut cmd); + test_remove_completion_fish(); + } + + fn test_adding_completion_fish(cmd: &mut Command) { + let _ = add_completion_fish(cmd); + + let result = std::fs::read_to_string("test_files/test_fish"); + + assert_eq!(true, result.is_ok()); + } + + fn test_remove_completion_fish() { + let _ = remove_completion_fish(); + + let result = std::fs::read("test_files/test_fish"); + assert_eq!(true, result.is_err()); + } + + #[test] + /// This test ensures the order of operations is always correct + fn test_zsh_completion() { + let mut cmd = Cli::command(); + + test_adding_completion_zsh(&mut cmd); + test_remove_completion_zsh(); + } + + fn test_adding_completion_zsh(cmd: &mut Command) { + let _ = add_completion_zsh(cmd); + + let result = std::fs::read_to_string("test_files/test_zsh"); + + assert_eq!(true, result.is_ok()); + } + + fn test_remove_completion_zsh() { + let _ = remove_completion_zsh(); + + let result = std::fs::read("test_files/test_zsh"); + assert_eq!(true, result.is_err()); + } +} diff --git a/src/bin/huak/commands/config/mod.rs b/src/bin/huak/commands/config/mod.rs index a0bb649b..c8548649 100644 --- a/src/bin/huak/commands/config/mod.rs +++ b/src/bin/huak/commands/config/mod.rs @@ -1,2 +1,63 @@ mod completion; -pub use completion::*; + +use crate::commands::Cli; +use crate::errors::CliResult; + +use clap::{Args, Command, CommandFactory, Subcommand}; +use clap_complete::{generate, Shell}; + +/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This +/// way if the user runs completion > completion.sh only the stdout will be redirected into +/// completion.sh. +pub fn run(config_command: Config) -> CliResult<()> { + match config_command.command { + ConfigCommand::Completion { shell } => { + generate_shell_completion_script(shell) + } + ConfigCommand::Install { shell } => { + let mut cmd: Command = Cli::command(); + let _result = match shell { + Shell::Bash => completion::add_completion_bash(), + Shell::Elvish => completion::add_completion_elvish(), + Shell::Fish => completion::add_completion_fish(&mut cmd), + Shell::PowerShell => completion::add_completion_powershell(), + Shell::Zsh => completion::add_completion_zsh(&mut cmd), + _ => Ok(()), + }; + } + ConfigCommand::Uninstall { shell } => { + let _result = match shell { + Shell::Bash => completion::remove_completion_bash(), + Shell::Elvish => completion::remove_completion_elvish(), + Shell::Fish => completion::remove_completion_fish(), + Shell::PowerShell => completion::remove_completion_powershell(), + Shell::Zsh => completion::remove_completion_zsh(), + _ => Ok(()), + }; + } + } + Ok(()) +} + +fn generate_shell_completion_script(shell: Shell) { + let mut cmd = Cli::command(); + + generate(shell, &mut cmd, "huak", &mut std::io::stdout()) +} + +#[derive(Args)] +pub struct Config { + #[command(subcommand)] + command: ConfigCommand, +} + +#[derive(Debug, Subcommand)] +pub enum ConfigCommand { + /// Generates a shell completion script for supported shells. + /// See the help menu for more information on supported shells. + Completion { shell: Shell }, + /// Installs the completion script in your shell init file. + Install { shell: Shell }, + /// Uninstalls the completion script from your shell init file. + Uninstall { shell: Shell }, +} From 31d045ccec181c7b6894d15975c793284296e4e0 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Sun, 30 Oct 2022 11:02:34 +0100 Subject: [PATCH 26/30] removed (un)install commands and added flags for them on completion instead --- src/bin/huak/commands/config/completion.rs | 15 +++-- src/bin/huak/commands/config/mod.rs | 71 +++++++++++++--------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index 33e45409..e763e90e 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -32,9 +32,11 @@ pub fn add_completion_bash() -> Result<(), Error> { // This needs to be a string since there will be a \n prepended if it is file.write_all( - format!(r##"{}eval "$(huak config completion bash)"{}"##, '\n', '\n') - .to_string() - .as_bytes(), + format!( + r##"{}eval "$(huak config completion -s bash)"{}"##, + '\n', '\n' + ) + .as_bytes(), )?; Ok(()) @@ -103,7 +105,10 @@ pub fn remove_completion_bash() -> Result<(), Error> { let file_content = std::fs::read_to_string(&_file_path)?; let new_content = file_content.replace( - &format!(r##"{}eval "$(huak config completion bash)"{}"##, '\n', '\n'), + &format!( + r##"{}eval "$(huak config completion -s bash)"{}"##, + '\n', '\n' + ), "", ); @@ -207,7 +212,7 @@ mod tests { # removing the bash completion script -eval "$(huak config completion bash)" +eval "$(huak config completion -s bash)" "## ), file_content diff --git a/src/bin/huak/commands/config/mod.rs b/src/bin/huak/commands/config/mod.rs index c8548649..6beddc83 100644 --- a/src/bin/huak/commands/config/mod.rs +++ b/src/bin/huak/commands/config/mod.rs @@ -11,29 +11,37 @@ use clap_complete::{generate, Shell}; /// completion.sh. pub fn run(config_command: Config) -> CliResult<()> { match config_command.command { - ConfigCommand::Completion { shell } => { - generate_shell_completion_script(shell) - } - ConfigCommand::Install { shell } => { - let mut cmd: Command = Cli::command(); - let _result = match shell { - Shell::Bash => completion::add_completion_bash(), - Shell::Elvish => completion::add_completion_elvish(), - Shell::Fish => completion::add_completion_fish(&mut cmd), - Shell::PowerShell => completion::add_completion_powershell(), - Shell::Zsh => completion::add_completion_zsh(&mut cmd), - _ => Ok(()), - }; - } - ConfigCommand::Uninstall { shell } => { - let _result = match shell { - Shell::Bash => completion::remove_completion_bash(), - Shell::Elvish => completion::remove_completion_elvish(), - Shell::Fish => completion::remove_completion_fish(), - Shell::PowerShell => completion::remove_completion_powershell(), - Shell::Zsh => completion::remove_completion_zsh(), - _ => Ok(()), - }; + ConfigCommand::Completion { + shell, + install, + uninstall, + } => { + if install { + let mut cmd: Command = Cli::command(); + let _result = match shell { + Shell::Bash => completion::add_completion_bash(), + Shell::Elvish => completion::add_completion_elvish(), + Shell::Fish => completion::add_completion_fish(&mut cmd), + Shell::PowerShell => { + completion::add_completion_powershell() + } + Shell::Zsh => completion::add_completion_zsh(&mut cmd), + _ => Ok(()), + }; + } else if uninstall { + let _result = match shell { + Shell::Bash => completion::remove_completion_bash(), + Shell::Elvish => completion::remove_completion_elvish(), + Shell::Fish => completion::remove_completion_fish(), + Shell::PowerShell => { + completion::remove_completion_powershell() + } + Shell::Zsh => completion::remove_completion_zsh(), + _ => Ok(()), + }; + } else { + generate_shell_completion_script(shell) + } } } Ok(()) @@ -55,9 +63,16 @@ pub struct Config { pub enum ConfigCommand { /// Generates a shell completion script for supported shells. /// See the help menu for more information on supported shells. - Completion { shell: Shell }, - /// Installs the completion script in your shell init file. - Install { shell: Shell }, - /// Uninstalls the completion script from your shell init file. - Uninstall { shell: Shell }, + Completion { + #[arg(short, long, value_name = "shell")] + shell: Shell, + + #[arg(short, long)] + /// Installs the completion script in your shell init file. + install: bool, + + #[arg(short, long)] + /// Uninstalls the completion script from your shell init file. + uninstall: bool, + }, } From 41191dc2127e6b9f1fd12314575f45a9b7b12dc2 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Mon, 31 Oct 2022 13:45:15 +0100 Subject: [PATCH 27/30] added a os dependency on tests --- src/bin/huak/commands/config/completion.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index e763e90e..46e32bb9 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -193,6 +193,7 @@ mod tests { #[derive(Parser)] struct Cli {} + #[cfg(not(target = "linux"))] #[test] /// This test ensures the order of operations is always correct fn test_bash_completion() { @@ -231,6 +232,7 @@ eval "$(huak config completion -s bash)" ", file_content) } + #[cfg(not(target = "linux"))] #[test] /// This test ensures the order of operations is always correct fn test_fish_completion() { @@ -255,6 +257,7 @@ eval "$(huak config completion -s bash)" assert_eq!(true, result.is_err()); } + #[cfg(not(target = "linux"))] #[test] /// This test ensures the order of operations is always correct fn test_zsh_completion() { From 995138f2036636805922b237e2b48dc5b6a27d98 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Mon, 31 Oct 2022 17:12:05 +0100 Subject: [PATCH 28/30] fixed target attribute for tests --- src/bin/huak/commands/config/completion.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index 46e32bb9..899e2bad 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -193,7 +193,7 @@ mod tests { #[derive(Parser)] struct Cli {} - #[cfg(not(target = "linux"))] + #[cfg(target = "linux")] #[test] /// This test ensures the order of operations is always correct fn test_bash_completion() { @@ -232,7 +232,7 @@ eval "$(huak config completion -s bash)" ", file_content) } - #[cfg(not(target = "linux"))] + #[cfg(target = "linux")] #[test] /// This test ensures the order of operations is always correct fn test_fish_completion() { @@ -257,7 +257,7 @@ eval "$(huak config completion -s bash)" assert_eq!(true, result.is_err()); } - #[cfg(not(target = "linux"))] + #[cfg(target = "linux")] #[test] /// This test ensures the order of operations is always correct fn test_zsh_completion() { From e70f6f371061885c1139bfcbdfdd326ad8a0841f Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Mon, 31 Oct 2022 17:31:09 +0100 Subject: [PATCH 29/30] made the shell flag only madatory when --install or --uninstall is passed, otherwise huak config completion just prints to stdout --- src/bin/huak/commands/config/completion.rs | 29 ++------- src/bin/huak/commands/config/mod.rs | 71 +++++++++++++++------- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index 899e2bad..082e3b01 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -2,7 +2,7 @@ use std::fs::File; use std::io::{Error, Write}; use std::path::Path; -use clap::{Command, Subcommand}; +use clap::Command; use clap_complete::{generate, Shell}; /// Bash has a couple of files that can contain the actual completion script. @@ -32,11 +32,8 @@ pub fn add_completion_bash() -> Result<(), Error> { // This needs to be a string since there will be a \n prepended if it is file.write_all( - format!( - r##"{}eval "$(huak config completion -s bash)"{}"##, - '\n', '\n' - ) - .as_bytes(), + format!(r##"{}eval "$(huak config completion)"{}"##, '\n', '\n') + .as_bytes(), )?; Ok(()) @@ -105,10 +102,7 @@ pub fn remove_completion_bash() -> Result<(), Error> { let file_content = std::fs::read_to_string(&_file_path)?; let new_content = file_content.replace( - &format!( - r##"{}eval "$(huak config completion -s bash)"{}"##, - '\n', '\n' - ), + &format!(r##"{}eval "$(huak config completion)"{}"##, '\n', '\n'), "", ); @@ -172,23 +166,12 @@ where Ok(()) } -#[derive(Debug, Subcommand)] -pub enum Config { - /// Generates a shell completion script for supported shells. - /// See the help menu for more information on supported shells. - Completion { shell: Shell }, - /// Installs the completion script in your shell init file. - Install { shell: Shell }, - /// Uninstalls the completion script from your shell init file. - Uninstall { shell: Shell }, -} - #[cfg(test)] mod tests { use super::*; use std::fs; - use clap::{Command, CommandFactory, Parser}; + use clap::{Command, Parser}; #[derive(Parser)] struct Cli {} @@ -213,7 +196,7 @@ mod tests { # removing the bash completion script -eval "$(huak config completion -s bash)" +eval "$(huak config completion)" "## ), file_content diff --git a/src/bin/huak/commands/config/mod.rs b/src/bin/huak/commands/config/mod.rs index 6beddc83..718e1000 100644 --- a/src/bin/huak/commands/config/mod.rs +++ b/src/bin/huak/commands/config/mod.rs @@ -18,39 +18,64 @@ pub fn run(config_command: Config) -> CliResult<()> { } => { if install { let mut cmd: Command = Cli::command(); - let _result = match shell { - Shell::Bash => completion::add_completion_bash(), - Shell::Elvish => completion::add_completion_elvish(), - Shell::Fish => completion::add_completion_fish(&mut cmd), - Shell::PowerShell => { - completion::add_completion_powershell() + match shell { + Some(shell) => { + let result = match shell { + Shell::Bash => completion::add_completion_bash(), + Shell::Elvish => { + completion::add_completion_elvish() + } + Shell::Fish => { + completion::add_completion_fish(&mut cmd) + } + Shell::PowerShell => { + completion::add_completion_powershell() + } + Shell::Zsh => { + completion::add_completion_zsh(&mut cmd) + } + _ => Ok(()), + }; + if let Err(e) = result { + eprintln!("{}", e); + } } - Shell::Zsh => completion::add_completion_zsh(&mut cmd), - _ => Ok(()), - }; + None => eprintln!("Please provide a shell"), + } } else if uninstall { - let _result = match shell { - Shell::Bash => completion::remove_completion_bash(), - Shell::Elvish => completion::remove_completion_elvish(), - Shell::Fish => completion::remove_completion_fish(), - Shell::PowerShell => { - completion::remove_completion_powershell() + match shell { + Some(shell) => { + let result = match shell { + Shell::Bash => completion::remove_completion_bash(), + Shell::Elvish => { + completion::remove_completion_elvish() + } + Shell::Fish => completion::remove_completion_fish(), + Shell::PowerShell => { + completion::remove_completion_powershell() + } + Shell::Zsh => completion::remove_completion_zsh(), + _ => Ok(()), + }; + + if let Err(e) = result { + eprintln!("{}", e); + } } - Shell::Zsh => completion::remove_completion_zsh(), - _ => Ok(()), - }; + None => eprintln!("Please provide a shell"), + } } else { - generate_shell_completion_script(shell) + generate_shell_completion_script() } } } Ok(()) } -fn generate_shell_completion_script(shell: Shell) { +fn generate_shell_completion_script() { let mut cmd = Cli::command(); - generate(shell, &mut cmd, "huak", &mut std::io::stdout()) + generate(Shell::Bash, &mut cmd, "huak", &mut std::io::stdout()) } #[derive(Args)] @@ -65,14 +90,16 @@ pub enum ConfigCommand { /// See the help menu for more information on supported shells. Completion { #[arg(short, long, value_name = "shell")] - shell: Shell, + shell: Option, #[arg(short, long)] /// Installs the completion script in your shell init file. + /// If this flag is passed the --shell is required install: bool, #[arg(short, long)] /// Uninstalls the completion script from your shell init file. + /// If this flag is passed the --shell is required uninstall: bool, }, } From c77fc9c404095d58f3e58f03d5b03e1d1c8a48ea Mon Sep 17 00:00:00 2001 From: Chris Pryer Date: Mon, 31 Oct 2022 18:10:48 -0400 Subject: [PATCH 30/30] Finalize completion command --- src/bin/huak/commands/config/completion.rs | 204 ++++++++++++++------- src/bin/huak/commands/config/mod.rs | 101 ++-------- src/bin/huak/commands/mod.rs | 7 +- src/bin/huak/errors.rs | 6 + 4 files changed, 164 insertions(+), 154 deletions(-) diff --git a/src/bin/huak/commands/config/completion.rs b/src/bin/huak/commands/config/completion.rs index 082e3b01..ef7b6e85 100644 --- a/src/bin/huak/commands/config/completion.rs +++ b/src/bin/huak/commands/config/completion.rs @@ -1,9 +1,99 @@ use std::fs::File; use std::io::{Error, Write}; use std::path::Path; +use std::process::ExitCode; -use clap::Command; +use clap::{Command, CommandFactory}; use clap_complete::{generate, Shell}; +use huak::errors::HuakError; + +use crate::commands::Cli; +use crate::errors::{CliError, CliResult}; + +/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This +/// way if the user runs completion > completion.sh only the stdout will be redirected into +/// completion.sh. +pub fn run( + shell: Option, + install: bool, + uninstall: bool, +) -> CliResult<()> { + if (install || uninstall) && shell.is_none() { + return Err(CliError::new( + HuakError::ConfigurationError("No shell provided".to_string()), + ExitCode::FAILURE, + )); + } + if install { + run_with_install(shell)?; + } else if uninstall { + run_with_uninstall(shell)?; + } else { + generate_shell_completion_script() + } + Ok(()) +} + +fn generate_shell_completion_script() { + let mut cmd = Cli::command(); + + generate(Shell::Bash, &mut cmd, "huak", &mut std::io::stdout()) +} + +fn run_with_install(shell: Option) -> CliResult<()> { + let sh = match shell { + Some(it) => it, + None => { + return Err(CliError::new( + HuakError::ConfigurationError("No shell provided".to_string()), + ExitCode::FAILURE, + )) + } + }; + let mut cmd: Command = Cli::command(); + match sh { + Shell::Bash => add_completion_bash(), + Shell::Elvish => add_completion_elvish(), + Shell::Fish => add_completion_fish(&mut cmd), + Shell::PowerShell => add_completion_powershell(), + Shell::Zsh => add_completion_zsh(&mut cmd), + _ => { + return Err(CliError::new( + HuakError::ConfigurationError("Invalid shell".to_string()), + ExitCode::FAILURE, + )); + } + }?; + + Ok(()) +} + +fn run_with_uninstall(shell: Option) -> CliResult<()> { + let sh = match shell { + Some(it) => it, + None => { + return Err(CliError::new( + HuakError::ConfigurationError("No shell provided".to_string()), + ExitCode::FAILURE, + )) + } + }; + match sh { + Shell::Bash => remove_completion_bash(), + Shell::Elvish => remove_completion_elvish(), + Shell::Fish => remove_completion_fish(), + Shell::PowerShell => remove_completion_powershell(), + Shell::Zsh => remove_completion_zsh(), + _ => { + return Err(CliError::new( + HuakError::ConfigurationError("Invalid shell".to_string()), + ExitCode::FAILURE, + )); + } + }?; + + Ok(()) +} /// Bash has a couple of files that can contain the actual completion script. /// Only the line `eval "$(huak config completion bash)"` needs to be added @@ -12,23 +102,16 @@ use clap_complete::{generate, Shell}; /// ~/.bash_login /// ~/.profile /// ~/.bashrc -pub fn add_completion_bash() -> Result<(), Error> { +pub fn add_completion_bash() -> CliResult<()> { let home = match std::env::var("HOME") { Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } + Err(e) => return Err(CliError::from(e)), }; - let _file_path = format!("{}/.bashrc", home); - - #[cfg(test)] - let _file_path = format!("test_files/test_bashrc"); + let file_path = format!("{}/.bashrc", home); // opening file in append mode - let mut file: File = File::options().append(true).open(_file_path)?; + let mut file = File::options().append(true).open(file_path)?; // This needs to be a string since there will be a \n prepended if it is file.write_all( @@ -40,114 +123,87 @@ pub fn add_completion_bash() -> Result<(), Error> { } // TODO -pub fn add_completion_elvish() -> Result<(), Error> { +pub fn add_completion_elvish() -> CliResult<()> { todo!() } /// huak config completion fish > ~/.config/fish/completions/huak.fish /// Fish has a completions directory in which all files are loaded on init. /// The naming convention is $HOME/.config/fish/completions/huak.fish -pub fn add_completion_fish(cli: &mut Command) -> Result<(), Error> { +pub fn add_completion_fish(cli: &mut Command) -> CliResult<()> { let home = match std::env::var("HOME") { Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } + Err(e) => return Err(CliError::from(e)), }; - let _target_file = format!("{}/.config/fish/completions/huak.fish", home); - - #[cfg(test)] - let _target_file = "test_files/test_fish".to_string(); + let target_file = format!("{}/.config/fish/completions/huak.fish", home); - generate_target_file(_target_file, cli)?; + generate_target_file(target_file, cli)?; Ok(()) } // TODO -pub fn add_completion_powershell() -> Result<(), Error> { +pub fn add_completion_powershell() -> CliResult<()> { todo!() } /// Zsh and fish are the same in the sense that the use an entire directory to collect shell init /// scripts. -pub fn add_completion_zsh(cli: &mut Command) -> Result<(), Error> { - let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); +pub fn add_completion_zsh(cli: &mut Command) -> CliResult<()> { + let target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); - #[cfg(test)] - let _target_file = "test_files/test_zsh".to_string(); - - generate_target_file(_target_file, cli)?; + generate_target_file(target_file, cli)?; Ok(()) } /// Reads the entire file and removes lines that match exactly with: /// \neval "$(huak config completion) -pub fn remove_completion_bash() -> Result<(), Error> { +pub fn remove_completion_bash() -> CliResult<()> { let home = match std::env::var("HOME") { Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } + Err(e) => return Err(CliError::from(e)), }; - let _file_path = format!("{}/.bashrc", home); + let file_path = format!("{}/.bashrc", home); - #[cfg(test)] - let _file_path = format!("test_files/test_bashrc"); - - let file_content = std::fs::read_to_string(&_file_path)?; + let file_content = std::fs::read_to_string(&file_path)?; let new_content = file_content.replace( &format!(r##"{}eval "$(huak config completion)"{}"##, '\n', '\n'), "", ); - std::fs::write(&_file_path, new_content)?; + std::fs::write(&file_path, new_content)?; Ok(()) } // TODO -pub fn remove_completion_elvish() -> Result<(), Error> { - todo!() +pub fn remove_completion_elvish() -> CliResult<()> { + unimplemented!() } -pub fn remove_completion_fish() -> Result<(), Error> { +pub fn remove_completion_fish() -> CliResult<()> { let home = match std::env::var("HOME") { Ok(dir) => dir, - Err(e) => { - // defaulting to root, this might not be the right call - eprintln!("{}", e); - String::from("root") - } + Err(e) => return Err(CliError::from(e)), }; - let _target_file = format!("{}/.config/fish/completions/huak.fish", home); - - #[cfg(test)] - let _target_file = "test_files/test_fish".to_string(); + let target_file = format!("{}/.config/fish/completions/huak.fish", home); - std::fs::remove_file(_target_file)?; + std::fs::remove_file(target_file)?; Ok(()) } // TODO -pub fn remove_completion_powershell() -> Result<(), Error> { - todo!() +pub fn remove_completion_powershell() -> CliResult<()> { + unimplemented!() } -pub fn remove_completion_zsh() -> Result<(), Error> { - let _target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); - - #[cfg(test)] - let _target_file = "test_files/test_zsh".to_string(); +pub fn remove_completion_zsh() -> CliResult<()> { + let target_file = "/usr/local/share/zsh/site-functions/_huak".to_string(); - std::fs::remove_file(_target_file)?; + std::fs::remove_file(target_file)?; Ok(()) } @@ -159,13 +215,16 @@ fn generate_target_file

( where P: AsRef, { - let mut file: File = File::create(&target_file)?; + let mut file = File::create(&target_file)?; generate(Shell::Fish, cmd, "huak", &mut file); Ok(()) } +// TODO: +// - Use tempdir and mocking for testing these features. +// - Requires refactors of functions and their signatures. #[cfg(test)] mod tests { use super::*; @@ -176,7 +235,8 @@ mod tests { #[derive(Parser)] struct Cli {} - #[cfg(target = "linux")] + #[cfg(target_family = "unix")] + #[ignore = "incomplete test"] // See TODO #[test] /// This test ensures the order of operations is always correct fn test_bash_completion() { @@ -184,6 +244,7 @@ mod tests { test_remove_completion_bash(); } + #[cfg(target_family = "unix")] fn test_adding_completion_bash() { let _ = add_completion_bash(); @@ -203,6 +264,7 @@ eval "$(huak config completion)" ) } + #[cfg(target_family = "unix")] fn test_remove_completion_bash() { let _ = remove_completion_bash(); @@ -215,7 +277,8 @@ eval "$(huak config completion)" ", file_content) } - #[cfg(target = "linux")] + #[cfg(target_family = "unix")] + #[ignore = "incomplete test"] // See TODO #[test] /// This test ensures the order of operations is always correct fn test_fish_completion() { @@ -225,6 +288,7 @@ eval "$(huak config completion)" test_remove_completion_fish(); } + #[cfg(target_family = "unix")] fn test_adding_completion_fish(cmd: &mut Command) { let _ = add_completion_fish(cmd); @@ -233,6 +297,7 @@ eval "$(huak config completion)" assert_eq!(true, result.is_ok()); } + #[cfg(target_family = "unix")] fn test_remove_completion_fish() { let _ = remove_completion_fish(); @@ -240,7 +305,8 @@ eval "$(huak config completion)" assert_eq!(true, result.is_err()); } - #[cfg(target = "linux")] + #[cfg(target_family = "unix")] + #[ignore = "incomplete test"] // See TODO #[test] /// This test ensures the order of operations is always correct fn test_zsh_completion() { @@ -250,6 +316,7 @@ eval "$(huak config completion)" test_remove_completion_zsh(); } + #[cfg(target_family = "unix")] fn test_adding_completion_zsh(cmd: &mut Command) { let _ = add_completion_zsh(cmd); @@ -258,6 +325,7 @@ eval "$(huak config completion)" assert_eq!(true, result.is_ok()); } + #[cfg(target_family = "unix")] fn test_remove_completion_zsh() { let _ = remove_completion_zsh(); diff --git a/src/bin/huak/commands/config/mod.rs b/src/bin/huak/commands/config/mod.rs index 718e1000..e6c797fa 100644 --- a/src/bin/huak/commands/config/mod.rs +++ b/src/bin/huak/commands/config/mod.rs @@ -1,91 +1,12 @@ mod completion; -use crate::commands::Cli; -use crate::errors::CliResult; - -use clap::{Args, Command, CommandFactory, Subcommand}; -use clap_complete::{generate, Shell}; - -/// Prints the script to stdout and a way to add the script to the shell init file to stderr. This -/// way if the user runs completion > completion.sh only the stdout will be redirected into -/// completion.sh. -pub fn run(config_command: Config) -> CliResult<()> { - match config_command.command { - ConfigCommand::Completion { - shell, - install, - uninstall, - } => { - if install { - let mut cmd: Command = Cli::command(); - match shell { - Some(shell) => { - let result = match shell { - Shell::Bash => completion::add_completion_bash(), - Shell::Elvish => { - completion::add_completion_elvish() - } - Shell::Fish => { - completion::add_completion_fish(&mut cmd) - } - Shell::PowerShell => { - completion::add_completion_powershell() - } - Shell::Zsh => { - completion::add_completion_zsh(&mut cmd) - } - _ => Ok(()), - }; - if let Err(e) = result { - eprintln!("{}", e); - } - } - None => eprintln!("Please provide a shell"), - } - } else if uninstall { - match shell { - Some(shell) => { - let result = match shell { - Shell::Bash => completion::remove_completion_bash(), - Shell::Elvish => { - completion::remove_completion_elvish() - } - Shell::Fish => completion::remove_completion_fish(), - Shell::PowerShell => { - completion::remove_completion_powershell() - } - Shell::Zsh => completion::remove_completion_zsh(), - _ => Ok(()), - }; +use clap::Subcommand; +use clap_complete::Shell; - if let Err(e) = result { - eprintln!("{}", e); - } - } - None => eprintln!("Please provide a shell"), - } - } else { - generate_shell_completion_script() - } - } - } - Ok(()) -} - -fn generate_shell_completion_script() { - let mut cmd = Cli::command(); - - generate(Shell::Bash, &mut cmd, "huak", &mut std::io::stdout()) -} - -#[derive(Args)] -pub struct Config { - #[command(subcommand)] - command: ConfigCommand, -} +use crate::errors::CliResult; -#[derive(Debug, Subcommand)] -pub enum ConfigCommand { +#[derive(Subcommand)] +pub enum Config { /// Generates a shell completion script for supported shells. /// See the help menu for more information on supported shells. Completion { @@ -103,3 +24,15 @@ pub enum ConfigCommand { uninstall: bool, }, } + +pub fn run(command: Config) -> CliResult<()> { + match command { + Config::Completion { + shell, + install, + uninstall, + } => completion::run(shell, install, uninstall), + }?; + + Ok(()) +} diff --git a/src/bin/huak/commands/mod.rs b/src/bin/huak/commands/mod.rs index fbef6065..14dcbfdd 100644 --- a/src/bin/huak/commands/mod.rs +++ b/src/bin/huak/commands/mod.rs @@ -49,7 +49,10 @@ pub enum Commands { /// Build tarball and wheel for the project. Build, /// Interact with the configuration of huak. - Config(config::Config), + Config { + #[command(subcommand)] + command: config::Config, + }, /// Remove tarball and wheel from the built project. Clean { #[arg(long, required = false)] @@ -123,7 +126,7 @@ pub enum Commands { impl Cli { pub fn run(self) -> CliResult<()> { match self.command { - Commands::Config(config_command) => config::run(config_command), + Commands::Config { command } => config::run(command), Commands::Activate => activate::run(), Commands::Add { dependency, dev } => add::run(dependency, dev), Commands::Audit => audit::run(), diff --git a/src/bin/huak/errors.rs b/src/bin/huak/errors.rs index 307ac080..95fb3aa6 100644 --- a/src/bin/huak/errors.rs +++ b/src/bin/huak/errors.rs @@ -57,3 +57,9 @@ impl From for CliError { CliError::new(HuakError::Utf8Error(err), BASIC_ERROR_CODE) } } + +impl From for CliError { + fn from(err: std::env::VarError) -> CliError { + CliError::new(HuakError::EnvVarError(err), BASIC_ERROR_CODE) + } +}