annotate rust/hg-core/src/utils/files.rs @ 52781:6183949219b2

rhg: implement rhg annotate This initial implementation produces the same output as Python for all the files I've tried, and is usually 1.5-9x faster. The algorithm is mostly the same, but one key difference is that the Rust implementation only converts filelog revisions to changelog revisions if they will actually appear in the output. This does not support all the command line flags yet. In particular, --template, --include, --exclude, --skip, and whitespace-related flags will cause fallback to Python. Also, --rev 'wdir()' (often used by editor plugins) is not supported. There is also no pager.
author Mitchell Kember <mkember@janestreet.com>
date Fri, 24 Jan 2025 12:01:12 -0500
parents 94e2547e6f3d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42767
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
1 // files.rs
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
2 //
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
3 // Copyright 2019
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
4 // Raphaël Gomès <rgomes@octobus.net>,
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
5 // Yuya Nishihara <yuya@tcha.org>
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
6 //
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
7 // This software may be used and distributed according to the terms of the
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
8 // GNU General Public License version 2 or any later version.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
9
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
10 //! Functions for fiddling with files.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42586
diff changeset
11
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
12 use crate::utils::{
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
13 hg_path::{path_to_hg_path_buf, HgPath, HgPathBuf, HgPathError},
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
14 path_auditor::PathAuditor,
52774
94e2547e6f3d rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents: 52552
diff changeset
15 strings::replace_slice,
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
16 };
44312
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
17 use lazy_static::lazy_static;
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
18 use same_file::is_same_file;
47127
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
19 use std::ffi::{OsStr, OsString};
44314
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
20 use std::iter::FusedIterator;
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
21 use std::ops::Deref;
52552
66e34bc44280 rhg: set the expected temp file permissions (0o666 minus umask)
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52058
diff changeset
22 use std::os::unix::fs::PermissionsExt;
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
23 use std::path::{Path, PathBuf};
52058
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
24 use std::{
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
25 borrow::{Cow, ToOwned},
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
26 io,
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
27 time::SystemTime,
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
28 };
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
29
46755
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46635
diff changeset
30 pub fn get_os_str_from_bytes(bytes: &[u8]) -> &OsStr {
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
31 let os_str;
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
32 #[cfg(unix)]
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
33 {
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
34 use std::os::unix::ffi::OsStrExt;
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
35 os_str = std::ffi::OsStr::from_bytes(bytes);
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
36 }
43250
98d996a138de rust-cross-platform: remove `unimplemented!` to get compile-time errors
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42960
diff changeset
37 // TODO Handle other platforms
98d996a138de rust-cross-platform: remove `unimplemented!` to get compile-time errors
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42960
diff changeset
38 // TODO: convert from WTF8 to Windows MBCS (ANSI encoding).
98d996a138de rust-cross-platform: remove `unimplemented!` to get compile-time errors
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42960
diff changeset
39 // Perhaps, the return type would have to be Result<PathBuf>.
46755
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46635
diff changeset
40 os_str
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46635
diff changeset
41 }
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
42
46755
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46635
diff changeset
43 pub fn get_path_from_bytes(bytes: &[u8]) -> &Path {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46635
diff changeset
44 Path::new(get_os_str_from_bytes(bytes))
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
45 }
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
46
43467
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
47 // TODO: need to convert from WTF8 to MBCS bytes on Windows.
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
48 // that's why Vec<u8> is returned.
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
49 #[cfg(unix)]
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
50 pub fn get_bytes_from_path(path: impl AsRef<Path>) -> Vec<u8> {
46635
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
51 get_bytes_from_os_str(path.as_ref())
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
52 }
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
53
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
54 #[cfg(unix)]
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
55 pub fn get_bytes_from_os_str(str: impl AsRef<OsStr>) -> Vec<u8> {
43467
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
56 use std::os::unix::ffi::OsStrExt;
46635
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46540
diff changeset
57 str.as_ref().as_bytes().to_vec()
43467
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
58 }
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
59
47127
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
60 #[cfg(unix)]
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
61 pub fn get_bytes_from_os_string(str: OsString) -> Vec<u8> {
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
62 use std::os::unix::ffi::OsStringExt;
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
63 str.into_vec()
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
64 }
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46788
diff changeset
65
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
66 /// An iterator over repository path yielding itself and its ancestors.
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
67 #[derive(Copy, Clone, Debug)]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
68 pub struct Ancestors<'a> {
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
69 next: Option<&'a HgPath>,
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
70 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
71
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
72 impl<'a> Iterator for Ancestors<'a> {
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
73 type Item = &'a HgPath;
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
74
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
75 fn next(&mut self) -> Option<Self::Item> {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
76 let next = self.next;
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
77 self.next = match self.next {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
78 Some(s) if s.is_empty() => None,
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
79 Some(s) => {
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
80 let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0);
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
81 Some(HgPath::new(&s.as_bytes()[..p]))
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
82 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
83 None => None,
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
84 };
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
85 next
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
86 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
87 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
88
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
89 impl<'a> FusedIterator for Ancestors<'a> {}
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
90
44314
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
91 /// An iterator over repository path yielding itself and its ancestors.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
92 #[derive(Copy, Clone, Debug)]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
93 pub(crate) struct AncestorsWithBase<'a> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
94 next: Option<(&'a HgPath, &'a HgPath)>,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
95 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
96
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
97 impl<'a> Iterator for AncestorsWithBase<'a> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
98 type Item = (&'a HgPath, &'a HgPath);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
99
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
100 fn next(&mut self) -> Option<Self::Item> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
101 let next = self.next;
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
102 self.next = match self.next {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
103 Some((s, _)) if s.is_empty() => None,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
104 Some((s, _)) => Some(s.split_filename()),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
105 None => None,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
106 };
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
107 next
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
108 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
109 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
110
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
111 impl<'a> FusedIterator for AncestorsWithBase<'a> {}
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
112
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
113 /// Returns an iterator yielding ancestor directories of the given repository
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
114 /// path.
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
115 ///
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
116 /// The path is separated by '/', and must not start with '/'.
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
117 ///
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
118 /// The path itself isn't included unless it is b"" (meaning the root
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
119 /// directory.)
44998
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44545
diff changeset
120 pub fn find_dirs(path: &HgPath) -> Ancestors {
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
121 let mut dirs = Ancestors { next: Some(path) };
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
122 if !path.is_empty() {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
123 dirs.next(); // skip itself
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
124 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
125 dirs
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
126 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
127
51477
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51118
diff changeset
128 pub fn dir_ancestors(path: &HgPath) -> Ancestors {
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51118
diff changeset
129 Ancestors { next: Some(path) }
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51118
diff changeset
130 }
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51118
diff changeset
131
44314
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
132 /// Returns an iterator yielding ancestor directories of the given repository
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
133 /// path.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
134 ///
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
135 /// The path is separated by '/', and must not start with '/'.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
136 ///
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
137 /// The path itself isn't included unless it is b"" (meaning the root
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
138 /// directory.)
44998
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44545
diff changeset
139 pub(crate) fn find_dirs_with_base(path: &HgPath) -> AncestorsWithBase {
44314
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
140 let mut dirs = AncestorsWithBase {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
141 next: Some((path, HgPath::new(b""))),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
142 };
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
143 if !path.is_empty() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
144 dirs.next(); // skip itself
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
145 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
146 dirs
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
147 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
148
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
149 /// TODO more than ASCII?
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
150 pub fn normalize_case(path: &HgPath) -> HgPathBuf {
42850
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42767
diff changeset
151 #[cfg(windows)] // NTFS compares via upper()
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
152 return path.to_ascii_uppercase();
42850
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42767
diff changeset
153 #[cfg(unix)]
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
154 path.to_ascii_lowercase()
42850
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42767
diff changeset
155 }
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42767
diff changeset
156
44312
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
157 lazy_static! {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
158 static ref IGNORED_CHARS: Vec<Vec<u8>> = {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
159 [
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
160 0x200c, 0x200d, 0x200e, 0x200f, 0x202a, 0x202b, 0x202c, 0x202d,
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
161 0x202e, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0xfeff,
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
162 ]
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
163 .iter()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
164 .map(|code| {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
165 std::char::from_u32(*code)
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
166 .unwrap()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
167 .encode_utf8(&mut [0; 3])
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
168 .bytes()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
169 .collect()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
170 })
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
171 .collect()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
172 };
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
173 }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
174
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
175 fn hfs_ignore_clean(bytes: &[u8]) -> Vec<u8> {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
176 let mut buf = bytes.to_owned();
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
177 let needs_escaping = bytes.iter().any(|b| *b == b'\xe2' || *b == b'\xef');
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
178 if needs_escaping {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
179 for forbidden in IGNORED_CHARS.iter() {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
180 replace_slice(&mut buf, forbidden, &[])
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
181 }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
182 buf
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
183 } else {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
184 buf
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
185 }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
186 }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
187
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
188 pub fn lower_clean(bytes: &[u8]) -> Vec<u8> {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
189 hfs_ignore_clean(&bytes.to_ascii_lowercase())
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
190 }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43875
diff changeset
191
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
192 /// Returns the canonical path of `name`, given `cwd` and `root`
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
193 pub fn canonical_path(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
194 root: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
195 cwd: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
196 name: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
197 ) -> Result<PathBuf, HgPathError> {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
198 // TODO add missing normalization for other platforms
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
199 let root = root.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
200 let cwd = cwd.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
201 let name = name.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
202
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
203 let name = if !name.is_absolute() {
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
204 root.join(cwd).join(name)
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
205 } else {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
206 name.to_owned()
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
207 };
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
208 let auditor = PathAuditor::new(root);
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
209 if name != root && name.starts_with(root) {
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
210 let name = name.strip_prefix(root).unwrap();
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
211 auditor.audit_path(path_to_hg_path_buf(name)?)?;
44998
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44545
diff changeset
212 Ok(name.to_owned())
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
213 } else if name == root {
44998
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44545
diff changeset
214 Ok("".into())
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
215 } else {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
216 // Determine whether `name' is in the hierarchy at or beneath `root',
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
217 // by iterating name=name.parent() until it returns `None` (can't
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
218 // check name == '/', because that doesn't work on windows).
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
219 let mut name = name.deref();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
220 let original_name = name.to_owned();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
221 loop {
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
222 let same = is_same_file(name, root).unwrap_or(false);
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
223 if same {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
224 if name == original_name {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
225 // `name` was actually the same as root (maybe a symlink)
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
226 return Ok("".into());
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
227 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
228 // `name` is a symlink to root, so `original_name` is under
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
229 // root
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
230 let rel_path = original_name.strip_prefix(name).unwrap();
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
231 auditor.audit_path(path_to_hg_path_buf(rel_path)?)?;
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
232 return Ok(rel_path.to_owned());
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
233 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
234 name = match name.parent() {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
235 None => break,
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
236 Some(p) => p,
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
237 };
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
238 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
239 // TODO hint to the user about using --cwd
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
240 // Bubble up the responsibility to Python for now
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
241 Err(HgPathError::NotUnderRoot {
50003
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48094
diff changeset
242 path: original_name,
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
243 root: root.to_owned(),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
244 })
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
245 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
246 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
247
45447
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
248 /// Returns the representation of the path relative to the current working
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
249 /// directory for display purposes.
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
250 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
251 /// `cwd` is a `HgPath`, so it is considered relative to the root directory
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
252 /// of the repository.
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
253 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
254 /// # Examples
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
255 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
256 /// ```
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
257 /// use hg::utils::hg_path::HgPath;
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
258 /// use hg::utils::files::relativize_path;
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
259 /// use std::borrow::Cow;
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
260 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
261 /// let file = HgPath::new(b"nested/file");
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
262 /// let cwd = HgPath::new(b"");
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
263 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"nested/file"));
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
264 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
265 /// let cwd = HgPath::new(b"nested");
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
266 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"file"));
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
267 ///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
268 /// let cwd = HgPath::new(b"other");
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
269 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"../nested/file"));
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
270 /// ```
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
271 pub fn relativize_path(path: &HgPath, cwd: impl AsRef<HgPath>) -> Cow<[u8]> {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
272 if cwd.as_ref().is_empty() {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
273 Cow::Borrowed(path.as_bytes())
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
274 } else {
46788
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
275 // This is not all accurate as to how large `res` will actually be, but
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
276 // profiling `rhg files` on a large-ish repo shows it’s better than
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
277 // starting from a zero-capacity `Vec` and letting `extend` reallocate
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
278 // repeatedly.
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
279 let guesstimate = path.as_bytes().len();
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
280
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46770
diff changeset
281 let mut res: Vec<u8> = Vec::with_capacity(guesstimate);
45447
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
282 let mut path_iter = path.as_bytes().split(|b| *b == b'/').peekable();
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
283 let mut cwd_iter =
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
284 cwd.as_ref().as_bytes().split(|b| *b == b'/').peekable();
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
285 loop {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
286 match (path_iter.peek(), cwd_iter.peek()) {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
287 (Some(a), Some(b)) if a == b => (),
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
288 _ => break,
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
289 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
290 path_iter.next();
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
291 cwd_iter.next();
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
292 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
293 let mut need_sep = false;
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
294 for _ in cwd_iter {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
295 if need_sep {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
296 res.extend(b"/")
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
297 } else {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
298 need_sep = true
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
299 };
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
300 res.extend(b"..");
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
301 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
302 for c in path_iter {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
303 if need_sep {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
304 res.extend(b"/")
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
305 } else {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
306 need_sep = true
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
307 };
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
308 res.extend(c);
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
309 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
310 Cow::Owned(res)
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
311 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
312 }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44998
diff changeset
313
52058
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
314 /// Return the `mtime` of a temporary file newly-created in the `.hg` directory
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
315 /// of the give repository.
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
316 ///
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
317 /// This is similar to `SystemTime::now()`, with the result truncated to the
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
318 /// same time resolution as other files’ modification times. Using `.hg`
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
319 /// instead of the system’s default temporary directory (such as `/tmp`) makes
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
320 /// it more likely the temporary file is in the same disk partition as contents
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
321 /// of the working directory, which can matter since different filesystems may
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
322 /// store timestamps with different resolutions.
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
323 ///
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
324 /// This may fail, typically if we lack write permissions. In that case we
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
325 /// should continue the `status()` algoritm anyway and consider the current
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
326 /// date/time to be unknown.
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
327 pub fn filesystem_now(repo_root: &Path) -> Result<SystemTime, io::Error> {
52552
66e34bc44280 rhg: set the expected temp file permissions (0o666 minus umask)
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52058
diff changeset
328 tempfile::Builder::new()
66e34bc44280 rhg: set the expected temp file permissions (0o666 minus umask)
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52058
diff changeset
329 .permissions(std::fs::Permissions::from_mode(0o666))
66e34bc44280 rhg: set the expected temp file permissions (0o666 minus umask)
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52058
diff changeset
330 .tempfile_in(repo_root.join(".hg"))?
66e34bc44280 rhg: set the expected temp file permissions (0o666 minus umask)
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52058
diff changeset
331 .into_file()
52058
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
332 .metadata()?
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
333 .modified()
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
334 }
b55f653a0b34 rust-utils: move the `filesystem_now` function to a util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51477
diff changeset
335
52781
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
336 /// Returns true if file content is considered to be binary (not text).
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
337 pub fn is_binary(content: &[u8]) -> bool {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
338 // Matches binary() in utils/stringutil.py.
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
339 !content.is_empty() && memchr::memchr(b'\0', content).is_some()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
340 }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents: 52774
diff changeset
341
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
342 #[cfg(test)]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
343 mod tests {
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
344 use super::*;
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
345 use pretty_assertions::assert_eq;
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
346
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
347 #[test]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
348 fn find_dirs_some() {
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
349 let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz"));
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
350 assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar")));
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
351 assert_eq!(dirs.next(), Some(HgPath::new(b"foo")));
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
352 assert_eq!(dirs.next(), Some(HgPath::new(b"")));
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
353 assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
354 assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
355 }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
356
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
357 #[test]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
358 fn find_dirs_empty() {
43677
0b7733719d21 utils: move finddirs() to pathutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43271
diff changeset
359 // looks weird, but mercurial.pathutil.finddirs(b"") yields b""
42960
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
360 let mut dirs = super::find_dirs(HgPath::new(b""));
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42850
diff changeset
361 assert_eq!(dirs.next(), Some(HgPath::new(b"")));
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
362 assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
363 assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
364 }
44314
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
365
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
366 #[test]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
367 fn test_find_dirs_with_base_some() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
368 let mut dirs = super::find_dirs_with_base(HgPath::new(b"foo/bar/baz"));
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
369 assert_eq!(
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
370 dirs.next(),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
371 Some((HgPath::new(b"foo/bar"), HgPath::new(b"baz")))
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
372 );
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
373 assert_eq!(
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
374 dirs.next(),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
375 Some((HgPath::new(b"foo"), HgPath::new(b"bar")))
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
376 );
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
377 assert_eq!(dirs.next(), Some((HgPath::new(b""), HgPath::new(b"foo"))));
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
378 assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
379 assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
380 }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
381
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
382 #[test]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
383 fn test_find_dirs_with_base_empty() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
384 let mut dirs = super::find_dirs_with_base(HgPath::new(b""));
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
385 assert_eq!(dirs.next(), Some((HgPath::new(b""), HgPath::new(b""))));
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
386 assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
387 assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
388 }
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
389
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
390 #[test]
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
391 fn test_canonical_path() {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
392 let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
393 let cwd = Path::new("/dir");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
394 let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
395 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
396 canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
397 Err(HgPathError::NotUnderRoot {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
398 path: PathBuf::from("/dir/filename"),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
399 root: root.to_path_buf()
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
400 })
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
401 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
402
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
403 let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
404 let cwd = Path::new("/");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
405 let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
406 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
407 canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
408 Err(HgPathError::NotUnderRoot {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
409 path: PathBuf::from("/filename"),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
410 root: root.to_path_buf()
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
411 })
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
412 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
413
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
414 let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
415 let cwd = Path::new("/");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
416 let name = Path::new("repo/filename");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
417 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
418 canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
419 Ok(PathBuf::from("filename"))
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
420 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
421
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
422 let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
423 let cwd = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
424 let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
425 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
426 canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
427 Ok(PathBuf::from("filename"))
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
428 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
429
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
430 let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
431 let cwd = Path::new("/repo/subdir");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
432 let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
433 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
434 canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
435 Ok(PathBuf::from("subdir/filename"))
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
436 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
437 }
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
438
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
439 #[test]
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
440 fn test_canonical_path_not_rooted() {
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
441 use std::fs::create_dir;
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
442 use tempfile::tempdir;
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
443
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
444 let base_dir = tempdir().unwrap();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
445 let base_dir_path = base_dir.path();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
446 let beneath_repo = base_dir_path.join("a");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
447 let root = base_dir_path.join("a/b");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
448 let out_of_repo = base_dir_path.join("c");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
449 let under_repo_symlink = out_of_repo.join("d");
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
450
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
451 create_dir(&beneath_repo).unwrap();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
452 create_dir(&root).unwrap();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
453
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
454 // TODO make portable
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
455 std::os::unix::fs::symlink(&root, &out_of_repo).unwrap();
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
456
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
457 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
458 canonical_path(&root, Path::new(""), out_of_repo),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
459 Ok(PathBuf::from(""))
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
460 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
461 assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
462 canonical_path(&root, Path::new(""), &beneath_repo),
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
463 Err(HgPathError::NotUnderRoot {
50003
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48094
diff changeset
464 path: beneath_repo,
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
465 root: root.to_owned()
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
466 })
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
467 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
468 assert_eq!(
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
469 canonical_path(&root, Path::new(""), under_repo_symlink),
44345
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
470 Ok(PathBuf::from("d"))
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
471 );
4caac36c66bc rust-utils: add util for canonical path
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44314
diff changeset
472 }
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42499
diff changeset
473 }