aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2023-02-17 21:09:04 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-02-17 21:09:04 +0000
commit67111d64ebf07d5769ac580b6695b21cbb757c3b (patch)
tree8d776c48ca763a8a92725842792c44c68bd6d5b0
parentf2ea97bd814cc806114adf5c96250a4076346fe9 (diff)
parent26caf7138b86de0a9aa5fbb388eb1971bed964fb (diff)
downloadwhich-67111d64ebf07d5769ac580b6695b21cbb757c3b.tar.gz
Upgrade which to 4.4.0 am: a065455574 am: 26caf7138b
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/which/+/2441940 Change-Id: Id2691086307858ea6299725333a559b602a793e8 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp3
-rw-r--r--Cargo.toml2
-rw-r--r--Cargo.toml.orig2
-rw-r--r--METADATA10
-rw-r--r--src/lib.rs225
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 <tiziyuanfang@gmail.com>"]
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 <tiziyuanfang@gmail.com>"]
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
@@ -21,14 +21,12 @@ mod finder;
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<T: AsRef<OsStr>>(binary_name: T) -> Result<path::PathBuf> {
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<T: AsRef<OsStr>>(binary_name: T) -> Result<path::PathBuf> {
+ 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<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item = path::PathBuf>> {
let cwd = env::current_dir().ok();
@@ -70,6 +92,22 @@ pub fn which_all<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item =
finder.find(binary_name, env::var_os("PATH"), cwd, binary_checker)
}
+/// Find all binaries with `binary_name` ignoring `cwd`.
+pub fn which_all_global<T: AsRef<OsStr>>(
+ binary_name: T,
+) -> Result<impl Iterator<Item = path::PathBuf>> {
+ 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<T, U>(
+ binary_name: T,
+ paths: Option<U>,
+) -> Result<impl Iterator<Item = path::PathBuf>>
+where
+ T: AsRef<OsStr>,
+ U: AsRef<OsStr>,
+{
+ 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<either::Either<bool, path::PathBuf>>,
+ custom_path_list: Option<OsString>,
+ binary_name: Option<OsString>,
+ #[cfg(feature = "regex")]
+ regex: Option<Regex>,
+}
+
+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<path::PathBuf> {
+ 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<impl Iterator<Item = path::PathBuf>> {
+ 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<dyn Iterator<Item = path::PathBuf>>);
+ }
+
+ 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<dyn Iterator<Item = path::PathBuf>>)
+ }
+}
+
/// 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<OsStr> for Path {
}
}
-impl Eq for Path {}
-
impl PartialEq<path::PathBuf> for Path {
fn eq(&self, other: &path::PathBuf) -> bool {
self.inner == *other
@@ -304,7 +511,7 @@ impl PartialEq<Path> 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<OsStr> for CanonicalPath {
}
}
-impl Eq for CanonicalPath {}
-
impl PartialEq<path::PathBuf> for CanonicalPath {
fn eq(&self, other: &path::PathBuf) -> bool {
self.inner == *other