@@ -16,8 +16,42 @@ pub enum Tool {
16
16
}
17
17
18
18
impl Tool {
19
+ pub fn proxy ( self ) -> Option < PathBuf > {
20
+ cargo_proxy ( self . name ( ) )
21
+ }
22
+
23
+ /// Return a `PathBuf` to use for the given executable.
24
+ ///
25
+ /// The current implementation checks three places for an executable to use:
26
+ /// 1) `$CARGO_HOME/bin/<executable_name>`
27
+ /// where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
28
+ /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
29
+ /// It seems that this is a reasonable place to try for cargo, rustc, and rustup
30
+ /// 2) Appropriate environment variable (erroring if this is set but not a usable executable)
31
+ /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
32
+ /// 3) $PATH/`<executable_name>`
33
+ /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the
34
+ /// first that exists
35
+ /// 4) If all else fails, we just try to use the executable name directly
36
+ pub fn prefer_proxy ( self ) -> PathBuf {
37
+ invoke ( & [ cargo_proxy, lookup_as_env_var, lookup_in_path] , self . name ( ) )
38
+ }
39
+
40
+ /// Return a `PathBuf` to use for the given executable.
41
+ ///
42
+ /// The current implementation checks three places for an executable to use:
43
+ /// 1) Appropriate environment variable (erroring if this is set but not a usable executable)
44
+ /// example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
45
+ /// 2) $PATH/`<executable_name>`
46
+ /// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the
47
+ /// first that exists
48
+ /// 3) `$CARGO_HOME/bin/<executable_name>`
49
+ /// where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
50
+ /// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
51
+ /// It seems that this is a reasonable place to try for cargo, rustc, and rustup
52
+ /// 4) If all else fails, we just try to use the executable name directly
19
53
pub fn path ( self ) -> PathBuf {
20
- get_path_for_executable ( self . name ( ) )
54
+ invoke ( & [ lookup_as_env_var , lookup_in_path , cargo_proxy ] , self . name ( ) )
21
55
}
22
56
23
57
pub fn path_in ( self , path : & Path ) -> Option < PathBuf > {
@@ -38,60 +72,21 @@ impl Tool {
38
72
}
39
73
}
40
74
41
- pub fn cargo ( ) -> PathBuf {
42
- get_path_for_executable ( "cargo" )
43
- }
44
-
45
- pub fn rustc ( ) -> PathBuf {
46
- get_path_for_executable ( "rustc" )
75
+ fn invoke ( list : & [ fn ( & str ) -> Option < PathBuf > ] , executable : & str ) -> PathBuf {
76
+ list. iter ( ) . find_map ( |it| it ( executable) ) . unwrap_or_else ( || executable. into ( ) )
47
77
}
48
78
49
- pub fn rustup ( ) -> PathBuf {
50
- get_path_for_executable ( "rustup" )
79
+ /// Looks up the binary as its SCREAMING upper case in the env variables.
80
+ fn lookup_as_env_var ( executable_name : & str ) -> Option < PathBuf > {
81
+ env:: var_os ( executable_name. to_ascii_uppercase ( ) ) . map ( Into :: into)
51
82
}
52
83
53
- pub fn rustfmt ( ) -> PathBuf {
54
- get_path_for_executable ( "rustfmt" )
55
- }
56
-
57
- /// Return a `PathBuf` to use for the given executable.
58
- ///
59
- /// E.g., `get_path_for_executable("cargo")` may return just `cargo` if that
60
- /// gives a valid Cargo executable; or it may return a full path to a valid
61
- /// Cargo.
62
- fn get_path_for_executable ( executable_name : & ' static str ) -> PathBuf {
63
- // The current implementation checks three places for an executable to use:
64
- // 1) Appropriate environment variable (erroring if this is set but not a usable executable)
65
- // example: for cargo, this checks $CARGO environment variable; for rustc, $RUSTC; etc
66
- // 2) `<executable_name>`
67
- // example: for cargo, this tries just `cargo`, which will succeed if `cargo` is on the $PATH
68
- // 3) `$CARGO_HOME/bin/<executable_name>`
69
- // where $CARGO_HOME defaults to ~/.cargo (see https://doc.rust-lang.org/cargo/guide/cargo-home.html)
70
- // example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
71
- // It seems that this is a reasonable place to try for cargo, rustc, and rustup
72
- let env_var = executable_name. to_ascii_uppercase ( ) ;
73
- if let Some ( path) = env:: var_os ( env_var) {
74
- return path. into ( ) ;
75
- }
76
-
77
- if lookup_in_path ( executable_name) {
78
- return executable_name. into ( ) ;
79
- }
80
-
81
- if let Some ( mut path) = get_cargo_home ( ) {
82
- path. push ( "bin" ) ;
83
- path. push ( executable_name) ;
84
- if let Some ( path) = probe_for_binary ( path) {
85
- return path;
86
- }
87
- }
88
-
89
- executable_name. into ( )
90
- }
91
-
92
- fn lookup_in_path ( exec : & str ) -> bool {
93
- let paths = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
94
- env:: split_paths ( & paths) . map ( |path| path. join ( exec) ) . find_map ( probe_for_binary) . is_some ( )
84
+ /// Looks up the binary in the cargo home directory if it exists.
85
+ fn cargo_proxy ( executable_name : & str ) -> Option < PathBuf > {
86
+ let mut path = get_cargo_home ( ) ?;
87
+ path. push ( "bin" ) ;
88
+ path. push ( executable_name) ;
89
+ probe_for_binary ( path)
95
90
}
96
91
97
92
fn get_cargo_home ( ) -> Option < PathBuf > {
@@ -107,6 +102,11 @@ fn get_cargo_home() -> Option<PathBuf> {
107
102
None
108
103
}
109
104
105
+ fn lookup_in_path ( exec : & str ) -> Option < PathBuf > {
106
+ let paths = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
107
+ env:: split_paths ( & paths) . map ( |path| path. join ( exec) ) . find_map ( probe_for_binary)
108
+ }
109
+
110
110
pub fn probe_for_binary ( path : PathBuf ) -> Option < PathBuf > {
111
111
let with_extension = match env:: consts:: EXE_EXTENSION {
112
112
"" => None ,
0 commit comments