From 6d724a8f331f4b2a8f1a001e990cf6129dc50b00 Mon Sep 17 00:00:00 2001
From: Michael Davis <mcarsondavis@gmail.com>
Date: Tue, 23 Jan 2024 09:29:07 -0500
Subject: [PATCH] Re-export `which` from `helix-stdx::env`

We use `which::which` in many crates, so `which` was a separate
dependency across all of them. We can centralize `which` into the
stdx crate so it's easy for all crates to depend on it.

I also moved the rest of `helix-view/src/env.rs` into helix-stdx's
`env` module since it only contained a thin wrapper around `which`
and `std::env`.
---
 Cargo.lock                  | 23 ++++++++++-------------
 helix-dap/Cargo.toml        |  2 +-
 helix-dap/src/client.rs     |  2 +-
 helix-loader/Cargo.toml     |  1 -
 helix-loader/src/grammar.rs |  2 +-
 helix-lsp/Cargo.toml        |  1 -
 helix-lsp/src/client.rs     |  2 +-
 helix-stdx/Cargo.toml       |  1 +
 helix-stdx/src/env.rs       | 10 ++++++++++
 helix-term/Cargo.toml       |  2 --
 helix-term/src/health.rs    |  6 +++---
 helix-view/Cargo.toml       |  1 -
 helix-view/src/clipboard.rs |  4 ++--
 helix-view/src/document.rs  |  7 ++++++-
 helix-view/src/editor.rs    |  4 ++--
 helix-view/src/env.rs       |  8 --------
 helix-view/src/lib.rs       |  1 -
 17 files changed, 38 insertions(+), 39 deletions(-)
 delete mode 100644 helix-view/src/env.rs

diff --git a/Cargo.lock b/Cargo.lock
index 9f62947f..d4ac12e4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -358,9 +358,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
 
 [[package]]
 name = "either"
-version = "1.8.1"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 
 [[package]]
 name = "encoding_rs"
@@ -1095,12 +1095,12 @@ dependencies = [
  "anyhow",
  "fern",
  "helix-core",
+ "helix-stdx",
  "log",
  "serde",
  "serde_json",
  "thiserror",
  "tokio",
- "which",
 ]
 
 [[package]]
@@ -1134,7 +1134,6 @@ dependencies = [
  "threadpool",
  "toml",
  "tree-sitter",
- "which",
 ]
 
 [[package]]
@@ -1157,7 +1156,6 @@ dependencies = [
  "thiserror",
  "tokio",
  "tokio-stream",
- "which",
 ]
 
 [[package]]
@@ -1172,6 +1170,7 @@ dependencies = [
  "etcetera",
  "ropey",
  "tempfile",
+ "which",
 ]
 
 [[package]]
@@ -1214,7 +1213,6 @@ dependencies = [
  "tokio-stream",
  "toml",
  "url",
- "which",
 ]
 
 [[package]]
@@ -1280,7 +1278,6 @@ dependencies = [
  "tokio-stream",
  "toml",
  "url",
- "which",
 ]
 
 [[package]]
@@ -1294,11 +1291,11 @@ dependencies = [
 
 [[package]]
 name = "home"
-version = "0.5.5"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
+checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
 dependencies = [
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -2359,15 +2356,15 @@ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
 
 [[package]]
 name = "which"
-version = "5.0.0"
+version = "6.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14"
+checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
 dependencies = [
  "either",
  "home",
  "once_cell",
  "rustix",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
diff --git a/helix-dap/Cargo.toml b/helix-dap/Cargo.toml
index f7acb003..3521f589 100644
--- a/helix-dap/Cargo.toml
+++ b/helix-dap/Cargo.toml
@@ -13,6 +13,7 @@ homepage.workspace = true
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+helix-stdx = { path = "../helix-stdx" }
 helix-core = { path = "../helix-core" }
 
 anyhow = "1.0"
@@ -21,7 +22,6 @@ serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 thiserror = "1.0"
 tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "net", "sync"] }
-which = "5.0.0"
 
 [dev-dependencies]
 fern = "0.6"
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 55ebab57..579811df 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -113,7 +113,7 @@ impl Client {
         id: usize,
     ) -> Result<(Self, UnboundedReceiver<Payload>)> {
         // Resolve path to the binary
-        let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
+        let cmd = helix_stdx::env::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
 
         let process = Command::new(cmd)
             .args(args)
diff --git a/helix-loader/Cargo.toml b/helix-loader/Cargo.toml
index 08da7f29..469bedc1 100644
--- a/helix-loader/Cargo.toml
+++ b/helix-loader/Cargo.toml
@@ -24,7 +24,6 @@ etcetera = "0.8"
 tree-sitter.workspace = true
 once_cell = "1.19"
 log = "0.4"
-which = "5.0.0"
 
 # TODO: these two should be on !wasm32 only
 
diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs
index 66111aeb..537e1282 100644
--- a/helix-loader/src/grammar.rs
+++ b/helix-loader/src/grammar.rs
@@ -86,7 +86,7 @@ pub fn get_language(name: &str) -> Result<Language> {
 }
 
 fn ensure_git_is_available() -> Result<()> {
-    match which::which("git") {
+    match helix_stdx::env::which("git") {
         Ok(_cmd) => Ok(()),
         Err(err) => Err(anyhow::anyhow!("'git' could not be found ({err})")),
     }
diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml
index 510be6ee..8e9e3407 100644
--- a/helix-lsp/Cargo.toml
+++ b/helix-lsp/Cargo.toml
@@ -29,5 +29,4 @@ serde_json = "1.0"
 thiserror = "1.0"
 tokio = { version = "1.35", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] }
 tokio-stream = "0.1.14"
-which = "5.0.0"
 parking_lot = "0.12.1"
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs
index 7eef2bf7..f8c2912e 100644
--- a/helix-lsp/src/client.rs
+++ b/helix-lsp/src/client.rs
@@ -183,7 +183,7 @@ impl Client {
         doc_path: Option<&std::path::PathBuf>,
     ) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc<Notify>)> {
         // Resolve path to the binary
-        let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
+        let cmd = helix_stdx::env::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
 
         let process = Command::new(cmd)
             .envs(server_environment)
diff --git a/helix-stdx/Cargo.toml b/helix-stdx/Cargo.toml
index 9b4de9fe..e77f8b91 100644
--- a/helix-stdx/Cargo.toml
+++ b/helix-stdx/Cargo.toml
@@ -15,6 +15,7 @@ homepage.workspace = true
 dunce = "1.0"
 etcetera = "0.8"
 ropey = { version = "1.6.1", default-features = false }
+which = "6.0"
 
 [dev-dependencies]
 tempfile = "3.9"
diff --git a/helix-stdx/src/env.rs b/helix-stdx/src/env.rs
index 864ba828..3676727f 100644
--- a/helix-stdx/src/env.rs
+++ b/helix-stdx/src/env.rs
@@ -1,3 +1,5 @@
+pub use which::which;
+
 use std::{
     path::{Path, PathBuf},
     sync::RwLock,
@@ -30,6 +32,14 @@ pub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<()> {
     Ok(())
 }
 
+pub fn env_var_is_set(env_var_name: &str) -> bool {
+    std::env::var_os(env_var_name).is_some()
+}
+
+pub fn binary_exists(binary_name: &str) -> bool {
+    which::which(binary_name).is_ok()
+}
+
 #[cfg(test)]
 mod tests {
     use super::{current_working_dir, set_current_working_dir};
diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml
index 683d6dc5..9a7162ac 100644
--- a/helix-term/Cargo.toml
+++ b/helix-term/Cargo.toml
@@ -35,8 +35,6 @@ helix-loader = { path = "../helix-loader" }
 anyhow = "1"
 once_cell = "1.19"
 
-which = "5.0.0"
-
 tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] }
 tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"] }
 crossterm = { version = "0.27", features = ["event-stream"] }
diff --git a/helix-term/src/health.rs b/helix-term/src/health.rs
index 44ae2a2f..5f201926 100644
--- a/helix-term/src/health.rs
+++ b/helix-term/src/health.rs
@@ -182,7 +182,7 @@ pub fn languages_all() -> std::io::Result<()> {
         .sort_unstable_by_key(|l| l.language_id.clone());
 
     let check_binary = |cmd: Option<&str>| match cmd {
-        Some(cmd) => match which::which(cmd) {
+        Some(cmd) => match helix_stdx::env::which(cmd) {
             Ok(_) => column(&format!("✓ {}", cmd), Color::Green),
             Err(_) => column(&format!("✘ {}", cmd), Color::Red),
         },
@@ -322,7 +322,7 @@ fn probe_protocols<'a, I: Iterator<Item = &'a str> + 'a>(
     writeln!(stdout)?;
 
     for cmd in server_cmds {
-        let (path, icon) = match which::which(cmd) {
+        let (path, icon) = match helix_stdx::env::which(cmd) {
             Ok(path) => (path.display().to_string().green(), "✓".green()),
             Err(_) => (format!("'{}' not found in $PATH", cmd).red(), "✘".red()),
         };
@@ -344,7 +344,7 @@ fn probe_protocol(protocol_name: &str, server_cmd: Option<String>) -> std::io::R
     writeln!(stdout, "Configured {}: {}", protocol_name, cmd_name)?;
 
     if let Some(cmd) = server_cmd {
-        let path = match which::which(&cmd) {
+        let path = match helix_stdx::env::which(&cmd) {
             Ok(path) => path.display().to_string().green(),
             Err(_) => format!("'{}' not found in $PATH", cmd).red(),
         };
diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml
index 0dc18b37..2e689341 100644
--- a/helix-view/Cargo.toml
+++ b/helix-view/Cargo.toml
@@ -46,7 +46,6 @@ serde_json = "1.0"
 toml = "0.7"
 log = "~0.4"
 
-which = "5.0.0"
 parking_lot = "0.12.1"
 
 
diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs
index 812c803e..9ff2fd78 100644
--- a/helix-view/src/clipboard.rs
+++ b/helix-view/src/clipboard.rs
@@ -73,7 +73,7 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
 
 #[cfg(target_os = "macos")]
 pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
-    use crate::env::{binary_exists, env_var_is_set};
+    use helix_stdx::env::{binary_exists, env_var_is_set};
 
     if env_var_is_set("TMUX") && binary_exists("tmux") {
         command_provider! {
@@ -98,7 +98,7 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
 
 #[cfg(not(any(windows, target_os = "wasm32", target_os = "macos")))]
 pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
-    use crate::env::{binary_exists, env_var_is_set};
+    use helix_stdx::env::{binary_exists, env_var_is_set};
     use provider::command::is_exit_success;
     // TODO: support for user-defined provider, probably when we have plugin support by setting a
     // variable?
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 388810b1..88653948 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -726,7 +726,12 @@ impl Document {
         if let Some((fmt_cmd, fmt_args)) = self
             .language_config()
             .and_then(|c| c.formatter.as_ref())
-            .and_then(|formatter| Some((which::which(&formatter.command).ok()?, &formatter.args)))
+            .and_then(|formatter| {
+                Some((
+                    helix_stdx::env::which(&formatter.command).ok()?,
+                    &formatter.args,
+                ))
+            })
         {
             use std::process::Stdio;
             let text = self.text().clone();
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index fbfcb356..f605cbb5 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -329,7 +329,7 @@ pub struct TerminalConfig {
 
 #[cfg(windows)]
 pub fn get_terminal_provider() -> Option<TerminalConfig> {
-    use crate::env::binary_exists;
+    use helix_stdx::env::binary_exists;
 
     if binary_exists("wt") {
         return Some(TerminalConfig {
@@ -352,7 +352,7 @@ pub fn get_terminal_provider() -> Option<TerminalConfig> {
 
 #[cfg(not(any(windows, target_os = "wasm32")))]
 pub fn get_terminal_provider() -> Option<TerminalConfig> {
-    use crate::env::{binary_exists, env_var_is_set};
+    use helix_stdx::env::{binary_exists, env_var_is_set};
 
     if env_var_is_set("TMUX") && binary_exists("tmux") {
         return Some(TerminalConfig {
diff --git a/helix-view/src/env.rs b/helix-view/src/env.rs
deleted file mode 100644
index c68cc609..00000000
--- a/helix-view/src/env.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub fn binary_exists(binary_name: &str) -> bool {
-    which::which(binary_name).is_ok()
-}
-
-#[cfg(not(windows))]
-pub fn env_var_is_set(env_var_name: &str) -> bool {
-    std::env::var_os(env_var_name).is_some()
-}
diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs
index 82827b5d..14b6e1ce 100644
--- a/helix-view/src/lib.rs
+++ b/helix-view/src/lib.rs
@@ -5,7 +5,6 @@ pub mod base64;
 pub mod clipboard;
 pub mod document;
 pub mod editor;
-pub mod env;
 pub mod events;
 pub mod graphics;
 pub mod gutter;