diff options
author | Elliott Hughes <enh@google.com> | 2021-04-12 21:24:21 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-04-12 21:24:21 +0000 |
commit | b904996c6a5b5df1ef990d50331ede25f91b196f (patch) | |
tree | cc218f809b980499efdc11c0902cd6c3b2637ab4 /src | |
parent | eaca4d18d27d7fa54182f1cd91849bddca42db92 (diff) | |
parent | d7bcf437866b7142b68207bb7ac480dfe63ab990 (diff) | |
download | which-b904996c6a5b5df1ef990d50331ede25f91b196f.tar.gz |
Upgrade rust/crates/which to 4.1.0 am: d7bcf43786
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/which/+/1662641
Change-Id: Iad5f634cfd3d5450a173c99c25649ce6d2695f19
Diffstat (limited to 'src')
-rw-r--r-- | src/checker.rs | 2 | ||||
-rw-r--r-- | src/error.rs | 23 | ||||
-rw-r--r-- | src/finder.rs | 29 | ||||
-rw-r--r-- | src/lib.rs | 106 |
4 files changed, 120 insertions, 40 deletions
diff --git a/src/checker.rs b/src/checker.rs index 94ef31a..62b78a2 100644 --- a/src/checker.rs +++ b/src/checker.rs @@ -1,4 +1,4 @@ -use finder::Checker; +use crate::finder::Checker; #[cfg(unix)] use libc; #[cfg(unix)] diff --git a/src/error.rs b/src/error.rs index 708c884..6d800a6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,17 +1,26 @@ -use thiserror; +use std::fmt; pub type Result<T> = std::result::Result<T, Error>; -#[derive(thiserror::Error, Copy, Clone, Eq, PartialEq, Debug)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum Error { - #[error("bad absolute path")] BadAbsolutePath, - #[error("bad relative path")] BadRelativePath, - #[error("cannot find binary path")] CannotFindBinaryPath, - #[error("cannot get current directory")] CannotGetCurrentDir, - #[error("cannot canonicalize path")] CannotCanonicalize, } + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::BadAbsolutePath => write!(f, "bad absolute path"), + Error::BadRelativePath => write!(f, "bad relative path"), + Error::CannotFindBinaryPath => write!(f, "cannot find binary path"), + Error::CannotGetCurrentDir => write!(f, "cannot get current directory"), + Error::CannotCanonicalize => write!(f, "cannot canonicalize path"), + } + } +} diff --git a/src/finder.rs b/src/finder.rs index d23cbaa..91c6cab 100644 --- a/src/finder.rs +++ b/src/finder.rs @@ -1,6 +1,8 @@ -use error::*; +use crate::checker::CompositeChecker; +use crate::error::*; +use either::Either; #[cfg(windows)] -use helper::has_executable_extension; +use crate::helper::has_executable_extension; use std::env; use std::ffi::OsStr; #[cfg(windows)] @@ -51,8 +53,8 @@ impl Finder { binary_name: T, paths: Option<U>, cwd: V, - binary_checker: &dyn Checker, - ) -> Result<PathBuf> + binary_checker: CompositeChecker, + ) -> Result<impl Iterator<Item = PathBuf>> where T: AsRef<OsStr>, U: AsRef<OsStr>, @@ -60,29 +62,18 @@ impl Finder { { let path = PathBuf::from(&binary_name); - let binary_path_candidates: Box<dyn Iterator<Item = _>> = if path.has_separator() { + let binary_path_candidates = if path.has_separator() { // Search binary in cwd if the path have a path separator. - let candidates = Self::cwd_search_candidates(path, cwd).into_iter(); - Box::new(candidates) + Either::Left(Self::cwd_search_candidates(path, cwd).into_iter()) } else { // Search binary in PATHs(defined in environment variable). let p = paths.ok_or(Error::CannotFindBinaryPath)?; let paths: Vec<_> = env::split_paths(&p).collect(); - let candidates = Self::path_search_candidates(path, paths).into_iter(); - - Box::new(candidates) + Either::Right(Self::path_search_candidates(path, paths).into_iter()) }; - for p in binary_path_candidates { - // find a valid binary - if binary_checker.is_valid(&p) { - return Ok(p); - } - } - - // can't find any binary - Err(Error::CannotFindBinaryPath) + Ok(binary_path_candidates.filter(move |p| binary_checker.is_valid(p))) } fn cwd_search_candidates<C>(binary_name: PathBuf, cwd: C) -> impl IntoIterator<Item = PathBuf> @@ -5,17 +5,15 @@ //! //! To find which rustc executable binary is using: //! -//! ``` norun +//! ```no_run //! use which::which; +//! use std::path::PathBuf; //! //! let result = which::which("rustc").unwrap(); //! assert_eq!(result, PathBuf::from("/usr/bin/rustc")); //! //! ``` -extern crate libc; -extern crate thiserror; - mod checker; mod error; mod finder; @@ -28,11 +26,9 @@ use std::path; use std::ffi::OsStr; -use checker::CompositeChecker; -use checker::ExecutableChecker; -use checker::ExistedChecker; -pub use error::*; -use finder::Finder; +use crate::checker::{CompositeChecker, ExecutableChecker, ExistedChecker}; +pub use crate::error::*; +use crate::finder::Finder; /// Find a exectable binary's path by name. /// @@ -47,7 +43,7 @@ use finder::Finder; /// /// # Example /// -/// ``` norun +/// ```no_run /// use which::which; /// use std::path::PathBuf; /// @@ -56,9 +52,14 @@ use finder::Finder; /// /// ``` 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. +pub fn which_all<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item = path::PathBuf>> { let cwd = env::current_dir().map_err(|_| Error::CannotGetCurrentDir)?; - which_in(binary_name, env::var_os("PATH"), &cwd) + which_in_all(binary_name, env::var_os("PATH"), cwd) } /// Find `binary_name` in the path list `paths`, using `cwd` to resolve relative paths. @@ -68,13 +69,28 @@ where U: AsRef<OsStr>, V: AsRef<path::Path>, { + which_in_all(binary_name, paths, cwd) + .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. +pub fn which_in_all<T, U, V>( + binary_name: T, + paths: Option<U>, + cwd: V, +) -> Result<impl Iterator<Item = path::PathBuf>> +where + T: AsRef<OsStr>, + U: AsRef<OsStr>, + V: AsRef<path::Path>, +{ let binary_checker = CompositeChecker::new() .add_checker(Box::new(ExistedChecker::new())) .add_checker(Box::new(ExecutableChecker::new())); let finder = Finder::new(); - finder.find(binary_name, paths, cwd, &binary_checker) + finder.find(binary_name, paths, cwd, binary_checker) } /// An owned, immutable wrapper around a `PathBuf` containing the path of an executable. @@ -100,6 +116,13 @@ impl Path { which(binary_name).map(|inner| Path { inner }) } + /// Returns the paths of all executable binaries by a name. + /// + /// this calls `which_all` and maps the results into `Path`s. + pub fn all<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item = Path>> { + which_all(binary_name).map(|inner| inner.map(|inner| Path { inner })) + } + /// Returns the path of an executable binary by name in the path list `paths` and using the /// current working directory `cwd` to resolve relative paths. /// @@ -113,6 +136,23 @@ impl Path { which_in(binary_name, paths, cwd).map(|inner| Path { inner }) } + /// Returns all paths of an executable binary by name in the path list `paths` and using the + /// current working directory `cwd` to resolve relative paths. + /// + /// This calls `which_in_all` and maps the results into a `Path`. + pub fn all_in<T, U, V>( + binary_name: T, + paths: Option<U>, + cwd: V, + ) -> Result<impl Iterator<Item = Path>> + where + T: AsRef<OsStr>, + U: AsRef<OsStr>, + V: AsRef<path::Path>, + { + which_in_all(binary_name, paths, cwd).map(|inner| inner.map(|inner| Path { inner })) + } + /// Returns a reference to a `std::path::Path`. pub fn as_path(&self) -> &path::Path { self.inner.as_path() @@ -192,10 +232,26 @@ impl CanonicalPath { .map(|inner| CanonicalPath { inner }) } + /// Returns the canonical paths of an executable binary by name. + /// + /// This calls `which_all` and `Path::canonicalize` and maps the results into `CanonicalPath`s. + pub fn all<T: AsRef<OsStr>>( + binary_name: T, + ) -> Result<impl Iterator<Item = Result<CanonicalPath>>> { + which_all(binary_name).map(|inner| { + inner.map(|inner| { + inner + .canonicalize() + .map_err(|_| Error::CannotCanonicalize) + .map(|inner| CanonicalPath { inner }) + }) + }) + } + /// Returns the canonical path of an executable binary by name in the path list `paths` and /// using the current working directory `cwd` to resolve relative paths. /// - /// This calls `which` and `Path::canonicalize` and maps the result into a `CanonicalPath`. + /// This calls `which_in` and `Path::canonicalize` and maps the result into a `CanonicalPath`. pub fn new_in<T, U, V>(binary_name: T, paths: Option<U>, cwd: V) -> Result<CanonicalPath> where T: AsRef<OsStr>, @@ -207,6 +263,30 @@ impl CanonicalPath { .map(|inner| CanonicalPath { inner }) } + /// Returns all of the canonical paths of an executable binary by name in the path list `paths` and + /// using the current working directory `cwd` to resolve relative paths. + /// + /// This calls `which_in_all` and `Path::canonicalize` and maps the result into a `CanonicalPath`. + pub fn all_in<T, U, V>( + binary_name: T, + paths: Option<U>, + cwd: V, + ) -> Result<impl Iterator<Item = Result<CanonicalPath>>> + where + T: AsRef<OsStr>, + U: AsRef<OsStr>, + V: AsRef<path::Path>, + { + which_in_all(binary_name, paths, cwd).map(|inner| { + inner.map(|inner| { + inner + .canonicalize() + .map_err(|_| Error::CannotCanonicalize) + .map(|inner| CanonicalPath { inner }) + }) + }) + } + /// Returns a reference to a `std::path::Path`. pub fn as_path(&self) -> &path::Path { self.inner.as_path() |