@@ -24,9 +24,9 @@ use once_cell::sync::Lazy;
24
24
/// more prefixes or matching a broad pattern of platform-like strings might be too broad. So only
25
25
/// prefixes that have been used in MSYS2 are considered.
26
26
///
27
- /// Second, we don't recognize `usr` itself here, even though is a plausible prefix. In MSYS2, it
28
- /// is the prefix for MSYS2 non-native programs, i.e. those that use `msys-2.0.dll`. But unlike the
29
- /// `<platform>` names we recognize, `usr` also has an effectively unbounded range of plausible
27
+ /// Second, we don't recognize `usr` itself here, even though it is a plausible prefix. In MSYS2,
28
+ /// it is the prefix for MSYS2 non-native programs, i.e. those that use `msys-2.0.dll`. But unlike
29
+ /// the `<platform>` names we recognize, `usr` also has an effectively unbounded range of plausible
30
30
/// meanings on non-Unix systems (for example, what should we take `Z:\usr` to mean?), which might
31
31
/// occasionally relate to subdirectories with contents controlled by different *user accounts*.
32
32
///
@@ -60,30 +60,44 @@ fn git_for_windows_root() -> Option<&'static Path> {
60
60
GIT_ROOT . as_deref ( )
61
61
}
62
62
63
- /// Shell path fragments to concatenate to the root of a Git for Windows or MSYS2 installation.
64
- ///
65
- /// When appended to the root of a Git for Windows installation, these are locations where `sh.exe`
66
- /// can usually be found. The leading `/` allow these to be used (only) with `raw_join()`.
63
+ /// `bin` directory paths to try relative to the root of a Git for Windows or MSYS2 installation.
67
64
///
68
65
/// These are ordered so that a shim is preferred over a non-shim when they are tried in order.
69
- const RAW_SH_EXE_PATH_SUFFIXES : & [ & str ] = & [ "/bin/sh.exe" , "/usr/bin/sh.exe" ] ;
70
-
71
- /// Concatenate a path by appending a raw suffix, which must contain its own leading separator.
72
- fn raw_join ( path : & Path , raw_suffix : & str ) -> OsString {
73
- let mut raw_path = OsString :: from ( path) ;
74
- raw_path. push ( raw_suffix) ;
75
- raw_path
76
- }
66
+ const BIN_DIR_FRAGMENTS : & [ & str ] = & [ "bin" , "usr/bin" ] ;
77
67
78
- /// Obtain a path to a `sh.exe` on Windows associated with Git, if one can be found.
68
+ /// Obtain a path to an executable command on Windows associated with Git, if one can be found.
79
69
///
80
70
/// The resulting path uses only `/` separators so long as the path obtained from `git --exec-path`
81
71
/// does, which is the case unless it is overridden by setting `GIT_EXEC_PATH` to an unusual value.
82
- pub ( super ) fn find_sh_on_windows ( ) -> Option < OsString > {
72
+ ///
73
+ /// This is currently only used (and only exercised in tests) for finding `sh.exe`. It may be used
74
+ /// to find other executables in the future, but may require adjustment. (In particular, depending
75
+ /// on the desired semantics, it should possibly also check inside a `cmd` directory, possibly also
76
+ /// check inside `super::core_dir()` itself, and could safely check the latter location even if its
77
+ /// value is not suitable to use in inferring any other paths.)
78
+ fn find_git_associated_windows_executable ( stem : & str ) -> Option < OsString > {
83
79
let git_root = git_for_windows_root ( ) ?;
84
80
85
- RAW_SH_EXE_PATH_SUFFIXES
81
+ BIN_DIR_FRAGMENTS
86
82
. iter ( )
87
- . map ( |raw_suffix| raw_join ( git_root, raw_suffix) )
83
+ . map ( |bin_dir_fragment| {
84
+ // Perform explicit raw concatenation with `/` to avoid introducing any `\` separators.
85
+ let mut raw_path = OsString :: from ( git_root) ;
86
+ raw_path. push ( "/" ) ;
87
+ raw_path. push ( bin_dir_fragment) ;
88
+ raw_path. push ( "/" ) ;
89
+ raw_path. push ( stem) ;
90
+ raw_path. push ( ".exe" ) ;
91
+ raw_path
92
+ } )
88
93
. find ( |raw_path| Path :: new ( raw_path) . is_file ( ) )
89
94
}
95
+
96
+ /// Like `find_associated_windows_executable`, but if not found, fall back to a simple filename.
97
+ pub ( super ) fn find_git_associated_windows_executable_with_fallback ( stem : & str ) -> OsString {
98
+ find_git_associated_windows_executable ( stem) . unwrap_or_else ( || {
99
+ let mut raw_path = OsString :: from ( stem) ;
100
+ raw_path. push ( ".exe" ) ;
101
+ raw_path
102
+ } )
103
+ }
0 commit comments