From a065455574fc17a5ddd2149526dcaf8a13556a07 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Fri, 17 Feb 2023 09:52:07 +0100 Subject: Upgrade which to 4.4.0 This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update rust/crates/which For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md Test: TreeHugger Change-Id: I9ff5e0aaffe13044c1ecff0f5785e1c24e4449b4 --- .cargo_vcs_info.json | 2 +- Android.bp | 3 +- Cargo.toml | 2 +- Cargo.toml.orig | 2 +- METADATA | 10 +-- src/lib.rs | 225 ++++++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 225 insertions(+), 19 deletions(-) diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index d0e4fff..0dcc2ff 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "492df704947be42c30f3bc7947e75244f26a0a45" + "sha1": "13722854453a50002d72faa1d0960f70b68ceea4" }, "path_in_vcs": "" } \ No newline at end of file diff --git a/Android.bp b/Android.bp index bc8bec7..e4167ea 100644 --- a/Android.bp +++ b/Android.bp @@ -20,10 +20,11 @@ license { rust_library { name: "libwhich", + // has rustc warnings host_supported: true, crate_name: "which", cargo_env_compat: true, - cargo_pkg_version: "4.3.0", + cargo_pkg_version: "4.4.0", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ diff --git a/Cargo.toml b/Cargo.toml index 84d671a..ff6894a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2018" name = "which" -version = "4.3.0" +version = "4.4.0" authors = ["Harry Fei "] description = "A Rust equivalent of Unix command \"which\". Locate installed executable in cross platforms." documentation = "https://docs.rs/which/" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index d8251f8..e05adb3 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "which" -version = "4.3.0" +version = "4.4.0" edition = "2018" authors = ["Harry Fei "] repository = "https://github.com/harryfei/which-rs.git" diff --git a/METADATA b/METADATA index 36e9b3e..d2123d9 100644 --- a/METADATA +++ b/METADATA @@ -11,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/which/which-4.3.0.crate" + value: "https://static.crates.io/crates/which/which-4.4.0.crate" } - version: "4.3.0" + version: "4.4.0" license_type: NOTICE last_upgrade_date { - year: 2022 - month: 12 - day: 19 + year: 2023 + month: 2 + day: 17 } } diff --git a/src/lib.rs b/src/lib.rs index b9026ff..3e556eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,15 +20,13 @@ mod finder; #[cfg(windows)] mod helper; -#[cfg(feature = "regex")] -use regex::Regex; #[cfg(feature = "regex")] use std::borrow::Borrow; use std::env; use std::fmt; use std::path; -use std::ffi::OsStr; +use std::ffi::{OsStr, OsString}; use crate::checker::{CompositeChecker, ExecutableChecker, ExistedChecker}; pub use crate::error::*; @@ -59,7 +57,31 @@ pub fn which>(binary_name: T) -> Result { which_all(binary_name).and_then(|mut i| i.next().ok_or(Error::CannotFindBinaryPath)) } -/// Find all binaries with `binary_name` in the path list `paths`, using `cwd` to resolve relative paths. +/// Find an executable binary's path by name, ignoring `cwd`. +/// +/// If given an absolute path, returns it if the file exists and is executable. +/// +/// Does not resolve relative paths. +/// +/// If given a string without path separators, looks for a file named +/// `binary_name` at each directory in `$PATH` and if it finds an executable +/// file there, returns it. +/// +/// # Example +/// +/// ```no_run +/// use which::which; +/// use std::path::PathBuf; +/// +/// let result = which::which_global("rustc").unwrap(); +/// assert_eq!(result, PathBuf::from("/usr/bin/rustc")); +/// +/// ``` +pub fn which_global>(binary_name: T) -> Result { + which_all_global(binary_name).and_then(|mut i| i.next().ok_or(Error::CannotFindBinaryPath)) +} + +/// Find all binaries with `binary_name` using `cwd` to resolve relative paths. pub fn which_all>(binary_name: T) -> Result> { let cwd = env::current_dir().ok(); @@ -70,6 +92,22 @@ pub fn which_all>(binary_name: T) -> Result>( + binary_name: T, +) -> Result> { + let binary_checker = build_binary_checker(); + + let finder = Finder::new(); + + finder.find( + binary_name, + env::var_os("PATH"), + Option::<&Path>::None, + binary_checker, + ) +} + /// Find all binaries matching a regular expression in a the system PATH. /// /// Only available when feature `regex` is enabled. @@ -174,12 +212,183 @@ where finder.find(binary_name, paths, Some(cwd), binary_checker) } +/// Find all binaries with `binary_name` in the path list `paths`, ignoring `cwd`. +pub fn which_in_global( + binary_name: T, + paths: Option, +) -> Result> +where + T: AsRef, + U: AsRef, +{ + let binary_checker = build_binary_checker(); + + let finder = Finder::new(); + + finder.find(binary_name, paths, Option::<&Path>::None, binary_checker) +} + fn build_binary_checker() -> CompositeChecker { CompositeChecker::new() .add_checker(Box::new(ExistedChecker::new())) .add_checker(Box::new(ExecutableChecker::new())) } +/// A wrapper containing all functionality in this crate. +pub struct WhichConfig { + cwd: Option>, + custom_path_list: Option, + binary_name: Option, + #[cfg(feature = "regex")] + regex: Option, +} + +impl Default for WhichConfig { + fn default() -> Self { + Self { + cwd: Some(either::Either::Left(true)), + custom_path_list: None, + binary_name: None, + #[cfg(feature = "regex")] + regex: None, + } + } +} + +#[cfg(feature = "regex")] +type Regex = regex::Regex; + +#[cfg(not(feature = "regex"))] +type Regex = (); + +impl WhichConfig { + pub fn new() -> Self { + Self::default() + } + + /// Whether or not to use the current working directory. `true` by default. + /// + /// # Panics + /// + /// If regex was set previously, and you've just passed in `use_cwd: true`, this will panic. + pub fn system_cwd(mut self, use_cwd: bool) -> Self { + #[cfg(feature = "regex")] + if self.regex.is_some() && use_cwd { + panic!("which can't use regex and cwd at the same time!") + } + self.cwd = Some(either::Either::Left(use_cwd)); + self + } + + /// Sets a custom path for resolving relative paths. + /// + /// # Panics + /// + /// If regex was set previously, this will panic. + pub fn custom_cwd(mut self, cwd: path::PathBuf) -> Self { + #[cfg(feature = "regex")] + if self.regex.is_some() { + panic!("which can't use regex and cwd at the same time!") + } + self.cwd = Some(either::Either::Right(cwd)); + self + } + + /// Sets the path name regex to search for. You ***MUST*** call this, or [`Self::binary_name`] prior to searching. + /// + /// When `Regex` is disabled this function takes the unit type as a stand in. The parameter will change when + /// `Regex` is enabled. + /// + /// # Panics + /// + /// If the `regex` feature wasn't turned on for this crate this will always panic. Additionally if a + /// `cwd` (aka current working directory) or `binary_name` was set previously, this will panic, as those options + /// are incompatible with `regex`. + #[allow(unused_variables)] + pub fn regex(mut self, regex: Regex) -> Self { + #[cfg(not(feature = "regex"))] + { + panic!("which's regex feature was not enabled in your Cargo.toml!") + } + #[cfg(feature = "regex")] + { + if self.cwd != Some(either::Either::Left(false)) && self.cwd.is_some() { + panic!("which can't use regex and cwd at the same time!") + } + if self.binary_name.is_some() { + panic!("which can't use `binary_name` and `regex` at the same time!"); + } + self.regex = Some(regex); + self + } + } + + /// Sets the path name to search for. You ***MUST*** call this, or [`Self::regex`] prior to searching. + /// + /// # Panics + /// + /// If a `regex` was set previously this will panic as this is not compatible with `regex`. + pub fn binary_name(mut self, name: OsString) -> Self { + #[cfg(feature = "regex")] + if self.regex.is_some() { + panic!("which can't use `binary_name` and `regex` at the same time!"); + } + self.binary_name = Some(name); + self + } + + /// Uses the given string instead of the `PATH` env variable. + pub fn custom_path_list(mut self, custom_path_list: OsString) -> Self { + self.custom_path_list = Some(custom_path_list); + self + } + + /// Uses the `PATH` env variable. Enabled by default. + pub fn system_path_list(mut self) -> Self { + self.custom_path_list = None; + self + } + + /// Finishes configuring, runs the query and returns the first result. + pub fn first_result(self) -> Result { + self.all_results() + .and_then(|mut i| i.next().ok_or(Error::CannotFindBinaryPath)) + } + + /// Finishes configuring, runs the query and returns all results. + pub fn all_results(self) -> Result> { + let binary_checker = build_binary_checker(); + + let finder = Finder::new(); + + let paths = self.custom_path_list.or_else(|| env::var_os("PATH")); + + #[cfg(feature = "regex")] + if let Some(regex) = self.regex { + return finder + .find_re(regex, paths, binary_checker) + .map(|i| Box::new(i) as Box>); + } + + let cwd = match self.cwd { + Some(either::Either::Left(false)) => None, + Some(either::Either::Right(custom)) => Some(custom), + None | Some(either::Either::Left(true)) => env::current_dir().ok(), + }; + + finder + .find( + self.binary_name.expect( + "binary_name not set! You must set binary_name or regex before searching!", + ), + paths, + cwd, + binary_checker, + ) + .map(|i| Box::new(i) as Box>) + } +} + /// An owned, immutable wrapper around a `PathBuf` containing the path of an executable. /// /// The constructed `PathBuf` is the output of `which` or `which_in`, but `which::Path` has the @@ -190,7 +399,7 @@ fn build_binary_checker() -> CompositeChecker { /// /// Since `which::Path` implements `Deref` for `std::path::Path`, all methods on `&std::path::Path` /// are also available to `&which::Path` values. -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Eq)] pub struct Path { inner: path::PathBuf, } @@ -277,8 +486,6 @@ impl AsRef for Path { } } -impl Eq for Path {} - impl PartialEq for Path { fn eq(&self, other: &path::PathBuf) -> bool { self.inner == *other @@ -304,7 +511,7 @@ impl PartialEq for path::PathBuf { /// /// Since `CanonicalPath` implements `Deref` for `std::path::Path`, all methods on /// `&std::path::Path` are also available to `&CanonicalPath` values. -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Eq)] pub struct CanonicalPath { inner: path::PathBuf, } @@ -411,8 +618,6 @@ impl AsRef for CanonicalPath { } } -impl Eq for CanonicalPath {} - impl PartialEq for CanonicalPath { fn eq(&self, other: &path::PathBuf) -> bool { self.inner == *other -- cgit v1.2.3