Mercurial > public > mercurial-scm > hg
comparison rust/hg-core/src/utils.rs @ 46742:91ab5190a3de
rhg: Add support for environment variables in config include paths
Some tests rely on this.
Differential Revision: https://phab.mercurial-scm.org/D10140
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 08 Mar 2021 15:35:32 +0100 |
parents | e8cd519a0a34 |
children | 696abab107b4 |
comparison
equal
deleted
inserted
replaced
46741:25e3dac511f0 | 46742:91ab5190a3de |
---|---|
237 pub fn current_exe() -> Result<std::path::PathBuf, HgError> { | 237 pub fn current_exe() -> Result<std::path::PathBuf, HgError> { |
238 std::env::current_exe().map_err(|error| HgError::IoError { | 238 std::env::current_exe().map_err(|error| HgError::IoError { |
239 error, | 239 error, |
240 context: IoErrorContext::CurrentExe, | 240 context: IoErrorContext::CurrentExe, |
241 }) | 241 }) |
242 } | |
243 | |
244 /// Expand `$FOO` and `${FOO}` environment variables in the given byte string | |
245 pub fn expand_vars(s: &[u8]) -> std::borrow::Cow<[u8]> { | |
246 lazy_static::lazy_static! { | |
247 /// https://github.com/python/cpython/blob/3.9/Lib/posixpath.py#L301 | |
248 /// The `x` makes whitespace ignored. | |
249 /// `-u` disables the Unicode flag, which makes `\w` like Python with the ASCII flag. | |
250 static ref VAR_RE: regex::bytes::Regex = | |
251 regex::bytes::Regex::new(r"(?x-u) | |
252 \$ | |
253 (?: | |
254 (\w+) | |
255 | | |
256 \{ | |
257 ([^}]*) | |
258 \} | |
259 ) | |
260 ").unwrap(); | |
261 } | |
262 VAR_RE.replace_all(s, |captures: ®ex::bytes::Captures| { | |
263 let var_name = files::get_os_str_from_bytes( | |
264 captures | |
265 .get(1) | |
266 .or_else(|| captures.get(2)) | |
267 .expect("either side of `|` must participate in match") | |
268 .as_bytes(), | |
269 ); | |
270 std::env::var_os(var_name) | |
271 .map(files::get_bytes_from_os_str) | |
272 .unwrap_or_else(|| { | |
273 // Referencing an environment variable that does not exist. | |
274 // Leave the $FOO reference as-is. | |
275 captures[0].to_owned() | |
276 }) | |
277 }) | |
278 } | |
279 | |
280 #[test] | |
281 fn test_expand_vars() { | |
282 // Modifying process-global state in a test isn’t great, | |
283 // but hopefully this won’t collide with anything. | |
284 std::env::set_var("TEST_EXPAND_VAR", "1"); | |
285 assert_eq!( | |
286 expand_vars(b"before/$TEST_EXPAND_VAR/after"), | |
287 &b"before/1/after"[..] | |
288 ); | |
289 assert_eq!( | |
290 expand_vars(b"before${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}after"), | |
291 &b"before111after"[..] | |
292 ); | |
293 let s = b"before $SOME_LONG_NAME_THAT_WE_ASSUME_IS_NOT_AN_ACTUAL_ENV_VAR after"; | |
294 assert_eq!(expand_vars(s), &s[..]); | |
242 } | 295 } |
243 | 296 |
244 pub(crate) enum MergeResult<V> { | 297 pub(crate) enum MergeResult<V> { |
245 UseLeftValue, | 298 UseLeftValue, |
246 UseRightValue, | 299 UseRightValue, |