From 982ac52c694f35115eb27ced3d4671ce738c8a19 Mon Sep 17 00:00:00 2001 From: Azalea Gui <22280294+hykilpikonna@users.noreply.github.com> Date: Sun, 22 Dec 2024 08:14:24 -0500 Subject: [PATCH] [O] Better pathfinding --- Cargo.lock | 25 +++++++++ Cargo.toml | 1 + crates/hyfetch/Cargo.toml | 1 + crates/hyfetch/src/bin/hyfetch.rs | 26 +++------ crates/hyfetch/src/neofetch_util.rs | 83 +++++++++++++---------------- 5 files changed, 72 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c814f8f..b7719d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -186,6 +186,12 @@ dependencies = [ "topology-traits", ] +[[package]] +name = "env_home" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" + [[package]] name = "equivalent" version = "1.0.1" @@ -274,6 +280,7 @@ dependencies = [ "tracing-subscriber", "unicode-normalization", "unicode-segmentation", + "which", ] [[package]] @@ -947,6 +954,18 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "which" +version = "7.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a9e33648339dc1642b0e36e21b3385e6148e289226f657c809dee59df5028" +dependencies = [ + "either", + "env_home", + "rustix", + "winsafe", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1182,3 +1201,9 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" diff --git a/Cargo.toml b/Cargo.toml index a733ba34..67bbbef0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ tracing = { version = "0.1.40", default-features = false } tracing-subscriber = { version = "0.3.18", default-features = false } unicode-normalization = { version = "0.1.23", default-features = false } unicode-segmentation = { version = "1.11.0", default-features = false } +which = { version = "7.0.1", default-features = false } [workspace.lints.clippy] arithmetic_side_effects = "warn" diff --git a/crates/hyfetch/Cargo.toml b/crates/hyfetch/Cargo.toml index 63a4fbef..a1cbc3b9 100644 --- a/crates/hyfetch/Cargo.toml +++ b/crates/hyfetch/Cargo.toml @@ -38,6 +38,7 @@ toml_edit = { workspace = true, features = [], optional = true } tracing = { workspace = true, features = ["attributes", "std"] } tracing-subscriber = { workspace = true, features = ["ansi", "fmt", "smallvec", "std", "tracing-log"] } unicode-segmentation = { workspace = true, features = [] } +which = { workspace = true, features = [] } [build-dependencies] indexmap = { workspace = true, features = ["std"] } diff --git a/crates/hyfetch/src/bin/hyfetch.rs b/crates/hyfetch/src/bin/hyfetch.rs index 005482eb..8daa1b26 100644 --- a/crates/hyfetch/src/bin/hyfetch.rs +++ b/crates/hyfetch/src/bin/hyfetch.rs @@ -21,10 +21,7 @@ use hyfetch::color_util::{ use hyfetch::models::Config; #[cfg(feature = "macchina")] use hyfetch::neofetch_util::macchina_path; -use hyfetch::neofetch_util::{ - self, fastfetch_path, get_distro_ascii, literal_input, ColorAlignment, NEOFETCH_COLORS_AC, - NEOFETCH_COLOR_PATTERNS, TEST_ASCII, -}; +use hyfetch::neofetch_util::{self, add_pkg_path, fastfetch_path, get_distro_ascii, literal_input, ColorAlignment, NEOFETCH_COLORS_AC, NEOFETCH_COLOR_PATTERNS, TEST_ASCII}; use hyfetch::presets::{AssignLightness, Preset}; use hyfetch::pride_month; use hyfetch::types::{AnsiMode, Backend, TerminalTheme}; @@ -42,6 +39,8 @@ use time::{Month, OffsetDateTime}; use tracing::debug; fn main() -> Result<()> { + add_pkg_path().expect("failed to add pkg path"); + #[cfg(windows)] if let Err(err) = enable_ansi_support::enable_ansi_support() { debug!(%err, "could not enable ANSI escape code support"); @@ -58,20 +57,9 @@ fn main() -> Result<()> { // Use a custom distro let distro = options.distro.as_ref(); - let backend = options.backend.map_or_else( - || { - fastfetch_path() - .context("failed to get fastfetch path") - .map(|fastfetch_path| { - if fastfetch_path.is_some() { - Backend::Fastfetch - } else { - Backend::Neofetch - } - }) - }, - Ok, - )?; + let backend = options.backend.unwrap_or_else(|| { + if fastfetch_path().is_ok() { Backend::Fastfetch } else { Backend::Neofetch } + }); if options.test_print { let asc = get_distro_ascii(distro, backend).context("failed to get distro ascii")?; @@ -956,7 +944,7 @@ fn create_config( .context("failed to print title prompt")?; // Check if fastfetch is installed - let fastfetch_path = fastfetch_path().context("failed to get fastfetch path")?; + let fastfetch_path = fastfetch_path().ok(); // Check if macchina is installed #[cfg(feature = "macchina")] diff --git a/crates/hyfetch/src/neofetch_util.rs b/crates/hyfetch/src/neofetch_util.rs index eb4c0397..32ebc797 100644 --- a/crates/hyfetch/src/neofetch_util.rs +++ b/crates/hyfetch/src/neofetch_util.rs @@ -6,7 +6,7 @@ use std::io::{self, Write as _}; use std::path::{PathBuf}; use std::process::Command; use std::sync::OnceLock; -use std::{fmt}; +use std::{env, fmt}; use aho_corasick::AhoCorasick; use anyhow::{Context as _, Result}; @@ -22,7 +22,7 @@ use strum::AsRefStr; use toml_edit::{value, DocumentMut, Item, Table}; use tracing::debug; use unicode_segmentation::UnicodeSegmentation as _; - +use which::which; use crate::ascii::{RawAsciiArt, RecoloredAsciiArt}; use crate::color_util::{printc, NeofetchAsciiIndexedColor, PresetIndexedColor}; use crate::distros::Distro; @@ -145,10 +145,39 @@ where } } +/// Add the PyPI pacakge path to the PATH environment variable (for this local process only). +/// This is done so that `which` can find the commands inside the PyPI package. +pub fn add_pkg_path() -> Result<()> { + // Get PATH + let pv = &env::var_os("PATH").context("`PATH` env var is not set or invalid")?; + let mut path = env::split_paths(pv).collect::>(); + let exe = env::current_exe().context("failed to get path of current running executable")?; + let base = exe.parent().unwrap(); + + // Add from bin: ../git, ../fastfetch, ../scripts + let to_add = ["git", "fastfetch", "scripts", "fastfetch/usr/bin"]; + if let Some(parent) = base.parent() { + path.extend(to_add.iter().map(|d| parent.join(d))); + } + + // Add from cwd: ./hyfetch/git, ./hyfetch/fastfetch, ./hyfetch/scripts + path.extend(to_add.iter().map(|d| PathBuf::from("hyfetch").join(d))); + + // Set PATH + env::set_var("PATH", env::join_paths(path).context("failed to join paths")?); + debug!("Added PyPI package path to PATH, PATH={}", env::var("PATH")?); + + Ok(()) +} + /// Gets the absolute path of the [neofetch] command. /// /// [neofetch]: https://github.com/hykilpikonna/hyfetch#running-updated-original-neofetch pub fn neofetch_path() -> Result { + if let Ok(p) = which("neowofetch") { + return Ok(p); + } + // Instead of doing that, let's write the neofetch script to a temp file let f: PathBuf = get_cache_path().context("Failed to get cache path")?.join("nf_script.sh"); let mut file = fs::File::create(&f).context("Failed to create neofetch script file")?; @@ -158,43 +187,6 @@ pub fn neofetch_path() -> Result { Ok(f) } -/// Gets the absolute path of the [fastfetch] command. -/// -/// [fastfetch]: https://github.com/fastfetch-cli/fastfetch -pub fn fastfetch_path() -> Result> { - let fastfetch_path = { - #[cfg(not(windows))] - { - find_in_path("fastfetch") - .context("failed to check existence of `fastfetch` in `PATH`")? - } - #[cfg(windows)] - { - find_in_path("fastfetch.exe") - .context("failed to check existence of `fastfetch.exe` in `PATH`")? - } - }; - - // Fall back to `fastfetch\fastfetch.exe` in directory of current executable - #[cfg(windows)] - let fastfetch_path = fastfetch_path.map_or_else( - || { - let current_exe_path: PathBuf = env::current_exe() - .and_then(|p| p.normalize().map(|p| p.into())) - .context("failed to get path of current running executable")?; - let current_exe_dir_path = current_exe_path - .parent() - .expect("parent should not be `None`"); - let fastfetch_path = current_exe_dir_path.join(r"fastfetch\fastfetch.exe"); - find_file(&fastfetch_path) - .with_context(|| format!("failed to check existence of file {fastfetch_path:?}")) - }, - |path| Ok(Some(path)), - )?; - - Ok(fastfetch_path) -} - /// Gets the absolute path of the [macchina] command. /// /// [macchina]: https://github.com/Macchina-CLI/macchina @@ -427,18 +419,19 @@ where Ok(out) } +pub fn fastfetch_path() -> Result { + which("fastfetch").context("fastfetch command not found") +} + fn make_fastfetch_command(args: &[S]) -> Result where S: AsRef, { // Find fastfetch executable - let fastfetch_path = fastfetch_path() - .context("failed to get fastfetch path")? - .context("fastfetch command not found")?; - - debug!(?fastfetch_path, "fastfetch path"); + let ff_path = fastfetch_path()?; + debug!(?ff_path, "fastfetch path"); - let mut command = Command::new(fastfetch_path); + let mut command = Command::new(ff_path); command.args(args); Ok(command) }