rust/hg-core/src/utils/files.rs
author Arseniy Alekseyev <aalekseyev@janestreet.com>
Fri, 12 Apr 2024 14:09:55 +0100
branchstable
changeset 51566 529a655874fb
parent 51120 532e74ad3ff6
permissions -rw-r--r--
matchers: fix the bug in rust PatternMatcher that made it cut off early This brings the rust output in line with the Python output.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42751
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
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    12
use crate::utils::{
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
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: 44267
diff changeset
    14
    path_auditor::PathAuditor,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    15
    replace_slice,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    16
};
44265
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
    17
use lazy_static::lazy_static;
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    18
use same_file::is_same_file;
45436
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
    19
use std::borrow::{Cow, ToOwned};
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    20
use std::ffi::{OsStr, OsString};
44267
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    21
use std::iter::FusedIterator;
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    22
use std::ops::Deref;
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
    23
use std::path::{Path, PathBuf};
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
46742
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    25
pub fn get_os_str_from_bytes(bytes: &[u8]) -> &OsStr {
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
    let os_str;
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
    #[cfg(unix)]
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
    {
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
        use std::os::unix::ffi::OsStrExt;
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
        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
    31
    }
43250
98d996a138de rust-cross-platform: remove `unimplemented!` to get compile-time errors
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    32
    // TODO Handle other platforms
98d996a138de rust-cross-platform: remove `unimplemented!` to get compile-time errors
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    33
    // 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: 42957
diff changeset
    34
    // Perhaps, the return type would have to be Result<PathBuf>.
46742
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    35
    os_str
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    36
}
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
46742
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    38
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: 46596
diff changeset
    39
    Path::new(get_os_str_from_bytes(bytes))
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
}
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    41
43868
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
    42
// 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
    43
// 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
    44
#[cfg(unix)]
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
    45
pub fn get_bytes_from_path(path: impl AsRef<Path>) -> Vec<u8> {
46596
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    46
    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: 46481
diff changeset
    47
}
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    48
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    49
#[cfg(unix)]
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    50
pub fn get_bytes_from_os_str(str: impl AsRef<OsStr>) -> Vec<u8> {
43868
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
    51
    use std::os::unix::ffi::OsStrExt;
46596
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    52
    str.as_ref().as_bytes().to_vec()
43868
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
    53
}
b06cf2809ec3 rust-cpython: do not convert warning pattern to utf-8 bytes
Yuya Nishihara <yuya@tcha.org>
parents: 43271
diff changeset
    54
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    55
#[cfg(unix)]
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    56
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: 46775
diff changeset
    57
    use std::os::unix::ffi::OsStringExt;
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    58
    str.into_vec()
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    59
}
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 46775
diff changeset
    60
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    61
/// 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: 42484
diff changeset
    62
#[derive(Copy, Clone, Debug)]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    63
pub struct Ancestors<'a> {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
    64
    next: Option<&'a HgPath>,
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    65
}
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    66
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    67
impl<'a> Iterator for Ancestors<'a> {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
    68
    type Item = &'a HgPath;
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    69
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    70
    fn next(&mut self) -> Option<Self::Item> {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    71
        let next = self.next;
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    72
        self.next = match self.next {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    73
            Some(s) if s.is_empty() => None,
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    74
            Some(s) => {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
    75
                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: 42840
diff changeset
    76
                Some(HgPath::new(&s.as_bytes()[..p]))
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    77
            }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    78
            None => None,
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    79
        };
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    80
        next
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    81
    }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    82
}
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    83
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    84
impl<'a> FusedIterator for Ancestors<'a> {}
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
    85
44267
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    86
/// An iterator over repository path yielding itself and its ancestors.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    87
#[derive(Copy, Clone, Debug)]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    88
pub(crate) struct AncestorsWithBase<'a> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    89
    next: Option<(&'a HgPath, &'a HgPath)>,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    90
}
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    91
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    92
impl<'a> Iterator for AncestorsWithBase<'a> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    93
    type Item = (&'a HgPath, &'a HgPath);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    94
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    95
    fn next(&mut self) -> Option<Self::Item> {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    96
        let next = self.next;
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    97
        self.next = match self.next {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    98
            Some((s, _)) if s.is_empty() => None,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
    99
            Some((s, _)) => Some(s.split_filename()),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   100
            None => None,
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   101
        };
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   102
        next
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   103
    }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   104
}
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   105
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   106
impl<'a> FusedIterator for AncestorsWithBase<'a> {}
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   107
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   108
/// 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: 42484
diff changeset
   109
/// path.
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   110
///
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   111
/// 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: 42484
diff changeset
   112
///
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   113
/// 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: 42484
diff changeset
   114
/// directory.)
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
   115
pub fn find_dirs(path: &HgPath) -> Ancestors {
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   116
    let mut dirs = Ancestors { next: Some(path) };
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   117
    if !path.is_empty() {
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   118
        dirs.next(); // skip itself
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   119
    }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   120
    dirs
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   121
}
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   122
51566
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51120
diff changeset
   123
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: 51120
diff changeset
   124
    Ancestors { next: Some(path) }
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51120
diff changeset
   125
}
529a655874fb matchers: fix the bug in rust PatternMatcher that made it cut off early
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51120
diff changeset
   126
44267
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   127
/// Returns an iterator yielding ancestor directories of the given repository
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   128
/// path.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   129
///
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   130
/// The path is separated by '/', and must not start with '/'.
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   131
///
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   132
/// 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: 44265
diff changeset
   133
/// directory.)
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
   134
pub(crate) fn find_dirs_with_base(path: &HgPath) -> AncestorsWithBase {
44267
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   135
    let mut dirs = AncestorsWithBase {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   136
        next: Some((path, HgPath::new(b""))),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   137
    };
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   138
    if !path.is_empty() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   139
        dirs.next(); // skip itself
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   140
    }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   141
    dirs
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   142
}
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   143
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   144
/// TODO more than ASCII?
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   145
pub fn normalize_case(path: &HgPath) -> HgPathBuf {
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42751
diff changeset
   146
    #[cfg(windows)] // NTFS compares via upper()
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   147
    return path.to_ascii_uppercase();
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42751
diff changeset
   148
    #[cfg(unix)]
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   149
    path.to_ascii_lowercase()
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42751
diff changeset
   150
}
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42751
diff changeset
   151
44265
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   152
lazy_static! {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   153
    static ref IGNORED_CHARS: Vec<Vec<u8>> = {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   154
        [
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   155
            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: 43869
diff changeset
   156
            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: 43869
diff changeset
   157
        ]
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   158
        .iter()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   159
        .map(|code| {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   160
            std::char::from_u32(*code)
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   161
                .unwrap()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   162
                .encode_utf8(&mut [0; 3])
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   163
                .bytes()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   164
                .collect()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   165
        })
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   166
        .collect()
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   167
    };
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   168
}
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   169
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   170
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: 43869
diff changeset
   171
    let mut buf = bytes.to_owned();
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   172
    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: 43869
diff changeset
   173
    if needs_escaping {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   174
        for forbidden in IGNORED_CHARS.iter() {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   175
            replace_slice(&mut buf, forbidden, &[])
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   176
        }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   177
        buf
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   178
    } else {
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   179
        buf
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   180
    }
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   181
}
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   182
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   183
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: 43869
diff changeset
   184
    hfs_ignore_clean(&bytes.to_ascii_lowercase())
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   185
}
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Raphaël Gomès <rgomes@octobus.net>
parents: 43869
diff changeset
   186
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   187
/// 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: 44267
diff changeset
   188
pub fn canonical_path(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   189
    root: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   190
    cwd: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   191
    name: impl AsRef<Path>,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   192
) -> Result<PathBuf, HgPathError> {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   193
    // TODO add missing normalization for other platforms
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   194
    let root = root.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   195
    let cwd = cwd.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   196
    let name = name.as_ref();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   197
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   198
    let name = if !name.is_absolute() {
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   199
        root.join(cwd).join(name)
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   200
    } else {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   201
        name.to_owned()
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   202
    };
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   203
    let auditor = PathAuditor::new(root);
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   204
    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: 49930
diff changeset
   205
        let name = name.strip_prefix(root).unwrap();
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   206
        auditor.audit_path(path_to_hg_path_buf(name)?)?;
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
   207
        Ok(name.to_owned())
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   208
    } else if name == root {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
   209
        Ok("".into())
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   210
    } else {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   211
        // 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: 44267
diff changeset
   212
        // 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: 44267
diff changeset
   213
        // 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: 44267
diff changeset
   214
        let mut name = name.deref();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   215
        let original_name = name.to_owned();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   216
        loop {
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   217
            let same = is_same_file(name, root).unwrap_or(false);
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   218
            if same {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   219
                if name == original_name {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   220
                    // `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: 44267
diff changeset
   221
                    return Ok("".into());
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   222
                }
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   223
                // `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: 44267
diff changeset
   224
                // root
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   225
                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: 49930
diff changeset
   226
                auditor.audit_path(path_to_hg_path_buf(rel_path)?)?;
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   227
                return Ok(rel_path.to_owned());
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   228
            }
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   229
            name = match name.parent() {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   230
                None => break,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   231
                Some(p) => p,
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   232
            };
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   233
        }
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   234
        // TODO hint to the user about using --cwd
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   235
        // Bubble up the responsibility to Python for now
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   236
        Err(HgPathError::NotUnderRoot {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 48082
diff changeset
   237
            path: original_name,
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   238
            root: root.to_owned(),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   239
        })
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   240
    }
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   241
}
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   242
45436
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   243
/// 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: 44973
diff changeset
   244
/// 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: 44973
diff changeset
   245
///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   246
/// `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: 44973
diff changeset
   247
/// 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: 44973
diff changeset
   248
///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   249
/// # Examples
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
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: 44973
diff changeset
   251
/// ```
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   252
/// 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: 44973
diff changeset
   253
/// 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: 44973
diff changeset
   254
/// 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: 44973
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: 44973
diff changeset
   256
/// 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: 44973
diff changeset
   257
/// 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: 44973
diff changeset
   258
/// 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: 44973
diff changeset
   259
///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   260
/// 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: 44973
diff changeset
   261
/// 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: 44973
diff changeset
   262
///
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   263
/// 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: 44973
diff changeset
   264
/// 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: 44973
diff changeset
   265
/// ```
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   266
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: 44973
diff changeset
   267
    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: 44973
diff changeset
   268
        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: 44973
diff changeset
   269
    } else {
46775
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46757
diff changeset
   270
        // 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: 46757
diff changeset
   271
        // 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: 46757
diff changeset
   272
        // 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: 46757
diff changeset
   273
        // repeatedly.
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46757
diff changeset
   274
        let guesstimate = path.as_bytes().len();
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46757
diff changeset
   275
c94fa884240b rust: Preallocate the returned `Vec` in `utils::files::relativize_path`
Simon Sapin <simon.sapin@octobus.net>
parents: 46757
diff changeset
   276
        let mut res: Vec<u8> = Vec::with_capacity(guesstimate);
45436
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   277
        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: 44973
diff changeset
   278
        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: 44973
diff changeset
   279
            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: 44973
diff changeset
   280
        loop {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   281
            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: 44973
diff changeset
   282
                (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: 44973
diff changeset
   283
                _ => break,
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   284
            }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   285
            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: 44973
diff changeset
   286
            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: 44973
diff changeset
   287
        }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   288
        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: 44973
diff changeset
   289
        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: 44973
diff changeset
   290
            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: 44973
diff changeset
   291
                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: 44973
diff changeset
   292
            } else {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   293
                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: 44973
diff changeset
   294
            };
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   295
            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: 44973
diff changeset
   296
        }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   297
        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: 44973
diff changeset
   298
            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: 44973
diff changeset
   299
                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: 44973
diff changeset
   300
            } else {
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   301
                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: 44973
diff changeset
   302
            };
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   303
            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: 44973
diff changeset
   304
        }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   305
        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: 44973
diff changeset
   306
    }
1b3197047f5c rhg: make output of `files` relative to the current directory and the root
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
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: 44973
diff changeset
   308
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   309
#[cfg(test)]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   310
mod tests {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   311
    use super::*;
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   312
    use pretty_assertions::assert_eq;
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   313
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   314
    #[test]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   315
    fn find_dirs_some() {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   316
        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: 42840
diff changeset
   317
        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: 42840
diff changeset
   318
        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: 42840
diff changeset
   319
        assert_eq!(dirs.next(), Some(HgPath::new(b"")));
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   320
        assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   321
        assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   322
    }
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   323
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   324
    #[test]
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   325
    fn find_dirs_empty() {
43633
0b7733719d21 utils: move finddirs() to pathutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43271
diff changeset
   326
        // looks weird, but mercurial.pathutil.finddirs(b"") yields b""
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   327
        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: 42840
diff changeset
   328
        assert_eq!(dirs.next(), Some(HgPath::new(b"")));
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   329
        assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   330
        assert_eq!(dirs.next(), None);
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   331
    }
44267
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   332
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   333
    #[test]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   334
    fn test_find_dirs_with_base_some() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   335
        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: 44265
diff changeset
   336
        assert_eq!(
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   337
            dirs.next(),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   338
            Some((HgPath::new(b"foo/bar"), HgPath::new(b"baz")))
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   339
        );
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   340
        assert_eq!(
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   341
            dirs.next(),
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   342
            Some((HgPath::new(b"foo"), HgPath::new(b"bar")))
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   343
        );
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   344
        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: 44265
diff changeset
   345
        assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   346
        assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   347
    }
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   348
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   349
    #[test]
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   350
    fn test_find_dirs_with_base_empty() {
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   351
        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: 44265
diff changeset
   352
        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: 44265
diff changeset
   353
        assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   354
        assert_eq!(dirs.next(), None);
0e9ac3968b56 rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents: 44265
diff changeset
   355
    }
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   356
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   357
    #[test]
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   358
    fn test_canonical_path() {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   359
        let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   360
        let cwd = Path::new("/dir");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   361
        let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   362
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   363
            canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   364
            Err(HgPathError::NotUnderRoot {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   365
                path: PathBuf::from("/dir/filename"),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   366
                root: root.to_path_buf()
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   367
            })
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   368
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   369
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   370
        let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   371
        let cwd = Path::new("/");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   372
        let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   373
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   374
            canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   375
            Err(HgPathError::NotUnderRoot {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   376
                path: PathBuf::from("/filename"),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   377
                root: root.to_path_buf()
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   378
            })
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   379
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   380
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   381
        let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   382
        let cwd = Path::new("/");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   383
        let name = Path::new("repo/filename");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   384
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   385
            canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   386
            Ok(PathBuf::from("filename"))
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   387
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   388
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   389
        let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   390
        let cwd = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   391
        let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   392
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   393
            canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   394
            Ok(PathBuf::from("filename"))
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   395
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   396
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   397
        let root = Path::new("/repo");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   398
        let cwd = Path::new("/repo/subdir");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   399
        let name = Path::new("filename");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   400
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   401
            canonical_path(root, cwd, name),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   402
            Ok(PathBuf::from("subdir/filename"))
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   403
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   404
    }
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   405
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   406
    #[test]
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   407
    fn test_canonical_path_not_rooted() {
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   408
        use std::fs::create_dir;
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   409
        use tempfile::tempdir;
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   410
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   411
        let base_dir = tempdir().unwrap();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   412
        let base_dir_path = base_dir.path();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   413
        let beneath_repo = base_dir_path.join("a");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   414
        let root = base_dir_path.join("a/b");
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   415
        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: 44267
diff changeset
   416
        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: 44267
diff changeset
   417
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   418
        create_dir(&beneath_repo).unwrap();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   419
        create_dir(&root).unwrap();
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   420
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   421
        // TODO make portable
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   422
        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: 44267
diff changeset
   423
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   424
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   425
            canonical_path(&root, Path::new(""), out_of_repo),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   426
            Ok(PathBuf::from(""))
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   427
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   428
        assert_eq!(
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   429
            canonical_path(&root, Path::new(""), &beneath_repo),
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   430
            Err(HgPathError::NotUnderRoot {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 48082
diff changeset
   431
                path: beneath_repo,
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   432
                root: root.to_owned()
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   433
            })
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   434
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   435
        assert_eq!(
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   436
            canonical_path(&root, Path::new(""), under_repo_symlink),
44301
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   437
            Ok(PathBuf::from("d"))
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   438
        );
4caac36c66bc rust-utils: add util for canonical path
Raphaël Gomès <rgomes@octobus.net>
parents: 44267
diff changeset
   439
    }
42586
cad3dde7a573 rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents: 42484
diff changeset
   440
}