Show More
@@ -47,8 +47,8 b' pub fn normalize_for_display_bytes(path:' | |||
|
47 | 47 | /// For example: |
|
48 | 48 | /// |
|
49 | 49 | /// - On some systems with symlink support, `foo/bar/..` and `foo` can be |
|
50 | /// different as seen by the kernel, if `foo/bar` is a symlink. This | |
|
51 |
/// |
|
|
50 | /// different as seen by the kernel, if `foo/bar` is a symlink. This function | |
|
51 | /// always returns `foo` in this case. | |
|
52 | 52 | /// - On Windows, the official normalization rules are much more complicated. |
|
53 | 53 | /// See https://github.com/rust-lang/rust/pull/47363#issuecomment-357069527. |
|
54 | 54 | /// For example, this function cannot translate "drive relative" path like |
@@ -74,7 +74,9 b' pub fn absolute(path: impl AsRef<Path>) ' | |||
|
74 | 74 | let mut result = PathBuf::new(); |
|
75 | 75 | for component in path.components() { |
|
76 | 76 | match component { |
|
77 | Component::Normal(_) | Component::RootDir | Component::Prefix(_) => { | |
|
77 | Component::Normal(_) | |
|
78 | | Component::RootDir | |
|
79 | | Component::Prefix(_) => { | |
|
78 | 80 | result.push(component); |
|
79 | 81 | } |
|
80 | 82 | Component::ParentDir => { |
@@ -95,9 +97,10 b' pub fn remove_file<P: AsRef<Path>>(path:' | |||
|
95 | 97 | |
|
96 | 98 | /// Remove the file pointed by `path`. |
|
97 | 99 | /// |
|
98 |
/// On Windows, removing a file can fail for various reasons, including if the |
|
|
99 |
/// mapped. This can happen when the repository is accessed |
|
|
100 | /// trying to remove a packfile. To solve this, we can rename the file before trying to remove it. | |
|
100 | /// On Windows, removing a file can fail for various reasons, including if the | |
|
101 | /// file is memory mapped. This can happen when the repository is accessed | |
|
102 | /// concurrently while a background task is trying to remove a packfile. To | |
|
103 | /// solve this, we can rename the file before trying to remove it. | |
|
101 | 104 | /// If the remove operation fails, a future repack will clean it up. |
|
102 | 105 | #[cfg(not(unix))] |
|
103 | 106 | pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<()> { |
@@ -116,12 +119,14 b' pub fn remove_file<P: AsRef<Path>>(path:' | |||
|
116 | 119 | |
|
117 | 120 | rename(path, &dest_path)?; |
|
118 | 121 | |
|
119 |
// Ignore errors when removing the file, it will be cleaned up at a later |
|
|
122 | // Ignore errors when removing the file, it will be cleaned up at a later | |
|
123 | // time. | |
|
120 | 124 | let _ = fs_remove_file(dest_path); |
|
121 | 125 | Ok(()) |
|
122 | 126 | } |
|
123 | 127 | |
|
124 |
/// Create the directory and ignore failures when a directory of the same name |
|
|
128 | /// Create the directory and ignore failures when a directory of the same name | |
|
129 | /// already exists. | |
|
125 | 130 | pub fn create_dir(path: impl AsRef<Path>) -> io::Result<()> { |
|
126 | 131 | match fs::create_dir(path.as_ref()) { |
|
127 | 132 | Ok(()) => Ok(()), |
@@ -135,28 +140,29 b' pub fn create_dir(path: impl AsRef<Path>' | |||
|
135 | 140 | } |
|
136 | 141 | } |
|
137 | 142 | |
|
138 |
/// Expand the user's home directory and any environment variables references |
|
|
139 | /// the given path. | |
|
143 | /// Expand the user's home directory and any environment variables references | |
|
144 | /// in the given path. | |
|
140 | 145 | /// |
|
141 |
/// This function is designed to emulate the behavior of Mercurial's |
|
|
142 | /// function, which in turn uses Python's `os.path.expand{user,vars}` functions. This | |
|
143 | /// results in behavior that is notably different from the default expansion behavior | |
|
144 | /// of the `shellexpand` crate. In particular: | |
|
146 | /// This function is designed to emulate the behavior of Mercurial's | |
|
147 | /// `util.expandpath` function, which in turn uses Python's | |
|
148 | /// `os.path.expand{user,vars}` functions. This results in behavior that is | |
|
149 | /// notably different from the default expansion behavior of the `shellexpand` | |
|
150 | /// crate. In particular: | |
|
145 | 151 | /// |
|
146 |
/// - If a reference to an environment variable is missing or invalid, the |
|
|
147 |
/// is left unchanged in the resulting path rather than emitting an |
|
|
152 | /// - If a reference to an environment variable is missing or invalid, the | |
|
153 | /// reference is left unchanged in the resulting path rather than emitting an | |
|
154 | /// error. | |
|
148 | 155 | /// |
|
149 | 156 | /// - Home directory expansion explicitly happens after environment variable |
|
150 | 157 | /// expansion, meaning that if an environment variable is expanded into a |
|
151 | 158 | /// string starting with a tilde (`~`), the tilde will be expanded into the |
|
152 | 159 | /// user's home directory. |
|
153 | /// | |
|
154 | 160 | pub fn expand_path(path: impl AsRef<str>) -> PathBuf { |
|
155 | 161 | expand_path_impl(path.as_ref(), |k| env::var(k).ok(), dirs::home_dir) |
|
156 | 162 | } |
|
157 | 163 | |
|
158 |
/// Same as `expand_path` but explicitly takes closures for environment |
|
|
159 | /// and home directory lookup for the sake of testability. | |
|
164 | /// Same as `expand_path` but explicitly takes closures for environment | |
|
165 | /// variable and home directory lookup for the sake of testability. | |
|
160 | 166 | fn expand_path_impl<E, H>(path: &str, getenv: E, homedir: H) -> PathBuf |
|
161 | 167 | where |
|
162 | 168 | E: FnMut(&str) -> Option<String>, |
@@ -238,7 +244,10 b' mod tests {' | |||
|
238 | 244 | |
|
239 | 245 | #[test] |
|
240 | 246 | fn test_absolute_fullpath() { |
|
241 | assert_eq!(absolute("/a/./b\\c/../d/.").unwrap(), Path::new("/a/d")); | |
|
247 | assert_eq!( | |
|
248 | absolute("/a/./b\\c/../d/.").unwrap(), | |
|
249 | Path::new("/a/d") | |
|
250 | ); | |
|
242 | 251 | assert_eq!(absolute("/a/../../../../b").unwrap(), Path::new("/b")); |
|
243 | 252 | assert_eq!(absolute("/../../..").unwrap(), Path::new("/")); |
|
244 | 253 | assert_eq!(absolute("/../../../").unwrap(), Path::new("/")); |
General Comments 0
You need to be logged in to leave comments.
Login now