1
- use std:: { borrow:: Cow , env, path:: PathBuf } ;
2
-
3
- use bstr:: { ByteSlice , ByteVec } ;
1
+ use std:: ffi:: OsStr ;
2
+ use std:: { env, path:: PathBuf } ;
4
3
5
4
/// The error returned by [git_discover::upwards()][crate::upwards()].
6
5
#[ derive( Debug , thiserror:: Error ) ]
@@ -81,44 +80,40 @@ impl Options<'_> {
81
80
// TODO: test
82
81
pub fn apply_environment ( mut self ) -> Self {
83
82
let name = "GIT_CEILING_DIRECTORIES" ;
84
- if let Some ( ceiling_dirs) = env:: var_os ( name) . and_then ( |c| Vec :: from_os_string ( c ) . ok ( ) ) {
83
+ if let Some ( ceiling_dirs) = env:: var_os ( name) {
85
84
self . ceiling_dirs = parse_ceiling_dirs ( & ceiling_dirs) ;
86
85
}
87
86
self
88
87
}
89
88
}
90
89
91
90
/// Parse a byte-string of `:`-separated paths into `Vec<PathBuf>`.
91
+ /// On Windows, paths are separated by `;`.
92
92
/// Non-absolute paths are discarded.
93
93
/// To match git, all paths are normalized, until an empty path is encountered.
94
- pub ( crate ) fn parse_ceiling_dirs ( ceiling_dirs : & [ u8 ] ) -> Vec < PathBuf > {
94
+ pub ( crate ) fn parse_ceiling_dirs ( ceiling_dirs : & OsStr ) -> Vec < PathBuf > {
95
95
let mut should_normalize = true ;
96
- let mut result = Vec :: new ( ) ;
97
- for ceiling_dir in ceiling_dirs . split_str ( ":" ) {
98
- if ceiling_dir. is_empty ( ) {
96
+ let mut out = Vec :: new ( ) ;
97
+ for ceiling_dir in std :: env :: split_paths ( ceiling_dirs ) {
98
+ if ceiling_dir. as_os_str ( ) . is_empty ( ) {
99
99
should_normalize = false ;
100
100
continue ;
101
101
}
102
102
103
- // Paths that are invalid unicode can't be handled
104
- let mut dir = match ceiling_dir. to_path ( ) {
105
- Ok ( dir) => Cow :: Borrowed ( dir) ,
106
- Err ( _) => continue ,
107
- } ;
108
-
109
103
// Only absolute paths are allowed
110
- if dir . is_relative ( ) {
104
+ if ceiling_dir . is_relative ( ) {
111
105
continue ;
112
106
}
113
107
108
+ let mut dir = ceiling_dir;
114
109
if should_normalize {
115
110
if let Ok ( normalized) = git_path:: realpath ( & dir) {
116
- dir = Cow :: Owned ( normalized) ;
111
+ dir = normalized;
117
112
}
118
113
}
119
- result . push ( dir. into_owned ( ) ) ;
114
+ out . push ( dir) ;
120
115
}
121
- result
116
+ out
122
117
}
123
118
124
119
#[ cfg( test) ]
@@ -141,7 +136,7 @@ mod tests {
141
136
// Parse & build ceiling dirs string
142
137
let symlink_str = symlink_path. to_str ( ) . expect ( "symlink path is valid utf8" ) ;
143
138
let ceiling_dir_string = format ! ( "{}:relative::{}" , symlink_str, symlink_str) ;
144
- let ceiling_dirs = parse_ceiling_dirs ( ceiling_dir_string. as_bytes ( ) ) ;
139
+ let ceiling_dirs = parse_ceiling_dirs ( OsStr :: new ( ceiling_dir_string. as_str ( ) ) ) ;
145
140
146
141
assert_eq ! ( ceiling_dirs. len( ) , 2 , "Relative path is discarded" ) ;
147
142
assert_eq ! (
@@ -156,4 +151,33 @@ mod tests {
156
151
157
152
dir. close ( )
158
153
}
154
+
155
+ #[ test]
156
+ #[ cfg( windows) ]
157
+ fn parse_ceiling_dirs_from_environment_format ( ) -> std:: io:: Result < ( ) > {
158
+ use std:: { fs, os:: windows:: fs:: symlink_dir} ;
159
+
160
+ use super :: * ;
161
+
162
+ // Setup filesystem
163
+ let dir = tempfile:: tempdir ( ) . expect ( "success creating temp dir" ) ;
164
+ let direct_path = dir. path ( ) . join ( "direct" ) ;
165
+ let symlink_path = dir. path ( ) . join ( "symlink" ) ;
166
+ fs:: create_dir ( & direct_path) ?;
167
+ symlink_dir ( & direct_path, & symlink_path) ?;
168
+
169
+ // Parse & build ceiling dirs string
170
+ let symlink_str = symlink_path. to_str ( ) . expect ( "symlink path is valid utf8" ) ;
171
+ let ceiling_dir_string = format ! ( "{};relative;;{}" , symlink_str, symlink_str) ;
172
+ let ceiling_dirs = parse_ceiling_dirs ( OsStr :: new ( ceiling_dir_string. as_str ( ) ) ) ;
173
+
174
+ assert_eq ! ( ceiling_dirs. len( ) , 2 , "Relative path is discarded" ) ;
175
+ assert_eq ! ( ceiling_dirs[ 0 ] , direct_path, "Symlinks are resolved" ) ;
176
+ assert_eq ! (
177
+ ceiling_dirs[ 1 ] , symlink_path,
178
+ "Symlink are not resolved after empty item"
179
+ ) ;
180
+
181
+ dir. close ( )
182
+ }
159
183
}
0 commit comments