rust/hg-core/src/filepatterns.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 11 Mar 2025 02:29:42 +0100
branchstable
changeset 53042 cdd7bf612c7b
parent 52760 94e2547e6f3d
permissions -rw-r--r--
bundle-spec: properly format boolean parameter (issue6960) This was breaking automatic clone bundle generation. This changeset fixes it and add a test to catch it in the future.
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: 42636
diff changeset
     1
// filepatterns.rs
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     2
//
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     4
//
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     5
// 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: 42636
diff changeset
     6
// 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: 42636
diff changeset
     7
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     8
//! Handling of Mercurial-specific patterns.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42636
diff changeset
     9
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    10
use crate::{
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
    11
    pre_regex::PreRegex,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    12
    utils::{
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    13
        files::{canonical_path, get_bytes_from_path, get_path_from_bytes},
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    14
        hg_path::{path_to_hg_path_buf, HgPathBuf, HgPathError},
52760
94e2547e6f3d rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents: 52556
diff changeset
    15
        strings::SliceExt,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    16
    },
52302
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    17
    FastHashMap,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    18
};
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42483
diff changeset
    19
use lazy_static::lazy_static;
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
    20
use regex::bytes::{NoExpand, Regex};
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
    21
use std::mem;
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42865
diff changeset
    22
use std::path::{Path, PathBuf};
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    23
use std::vec::Vec;
52302
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    24
use std::{fmt, ops::Deref};
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    25
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    26
#[derive(Debug, derive_more::From)]
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    27
pub enum PatternError {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    28
    #[from]
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    29
    Path(HgPathError),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    30
    UnsupportedSyntax(String),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    31
    UnsupportedSyntaxInFile(String, String, usize),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    32
    TooLong(usize),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    33
    #[from]
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    34
    IO(std::io::Error),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    35
    /// Needed a pattern that can be turned into a regex but got one that
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    36
    /// can't. This should only happen through programmer error.
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    37
    NonRegexPattern(IgnorePattern),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    38
}
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    39
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    40
impl fmt::Display for PatternError {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    41
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    42
        match self {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    43
            PatternError::UnsupportedSyntax(syntax) => {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    44
                write!(f, "Unsupported syntax {}", syntax)
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    45
            }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    46
            PatternError::UnsupportedSyntaxInFile(syntax, file_path, line) => {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    47
                write!(
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    48
                    f,
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    49
                    "{}:{}: unsupported syntax {}",
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    50
                    file_path, line, syntax
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    51
                )
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    52
            }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    53
            PatternError::TooLong(size) => {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    54
                write!(f, "matcher pattern is too long ({} bytes)", size)
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    55
            }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    56
            PatternError::IO(error) => error.fmt(f),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    57
            PatternError::Path(error) => error.fmt(f),
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    58
            PatternError::NonRegexPattern(pattern) => {
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    59
                write!(f, "'{:?}' cannot be turned into a regex", pattern)
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    60
            }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    61
        }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    62
    }
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51602
diff changeset
    63
}
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    64
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    65
lazy_static! {
42483
a4a468b00d44 rust-filepatterns: silence warning of non_upper_case_globals
Yuya Nishihara <yuya@tcha.org>
parents: 42438
diff changeset
    66
    static ref RE_ESCAPE: Vec<Vec<u8>> = {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    67
        let mut v: Vec<Vec<u8>> = (0..=255).map(|byte| vec![byte]).collect();
50856
2b4bcdc948e7 rust: don't escape spaces in regex
Spencer Baugh <sbaugh@janestreet.com>
parents: 50855
diff changeset
    68
        let to_escape = b"()[]{}?*+-|^$\\.&~#\t\n\r\x0b\x0c";
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    69
        for byte in to_escape {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    70
            v[*byte as usize].insert(0, b'\\');
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    71
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    72
        v
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    73
    };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    74
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    75
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
    76
#[derive(Debug, Clone, PartialEq, Eq)]
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    77
pub enum PatternSyntax {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    78
    /// A regular expression
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    79
    Regexp,
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    80
    /// Glob that matches at the front of the path
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    81
    RootGlob,
42841
ce6797ef6eab rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents: 42751
diff changeset
    82
    /// Glob that matches at any suffix of the path (still anchored at
ce6797ef6eab rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents: 42751
diff changeset
    83
    /// slashes)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    84
    Glob,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    85
    /// a path relative to repository root, which is matched recursively
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    86
    Path,
50692
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    87
    /// a single exact path relative to repository root
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    88
    FilePath,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    89
    /// A path relative to cwd
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    90
    RelPath,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    91
    /// an unrooted glob (*.rs matches Rust files in all dirs)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    92
    RelGlob,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    93
    /// A regexp that needn't match the start of a name
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    94
    RelRegexp,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    95
    /// A path relative to repository root, which is matched non-recursively
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
    96
    /// (will not match subdirectories)
51565
2a89d2f6336f match: rename RootFiles to RootFilesIn for more consistency
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51467
diff changeset
    97
    RootFilesIn,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    98
    /// A file of patterns to read and include
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
    99
    Include,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   100
    /// A file of patterns to match against files under the same directory
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   101
    SubInclude,
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   102
    /// SubInclude with the result of parsing the included file
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   103
    ///
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   104
    /// Note: there is no ExpandedInclude because that expansion can be done
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   105
    /// in place by replacing the Include pattern by the included patterns.
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   106
    /// SubInclude requires more handling.
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   107
    ///
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   108
    /// Note: `Box` is used to minimize size impact on other enum variants
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   109
    ExpandedSubInclude(Box<SubInclude>),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   110
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   111
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   112
/// A wildcard parsed from a glob
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   113
#[derive(Debug, Clone, Copy)]
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   114
enum GlobWildcard {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   115
    /// `**/` matches any sequence of characters ending at a path
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   116
    /// component boundary
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   117
    AnyComponents,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   118
    /// `*`: matches any sequence of characters within one path component
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   119
    AnyNonSlash,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   120
    /// `**`: matches any sequence of characters including slashes
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   121
    Anything,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   122
}
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   123
impl GlobWildcard {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   124
    /// Optimization to simplify the regex prefixes for unrooted globs.
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   125
    /// It's unclear if this is worth it for performance, but it also has
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   126
    /// some cosmetic effect by making these regexes easier to understand.
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   127
    fn make_unrooted(wildcard: Option<GlobWildcard>) -> GlobWildcard {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   128
        match wildcard {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   129
            None => Self::AnyComponents,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   130
            Some(Self::AnyComponents) => Self::AnyComponents,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   131
            Some(Self::AnyNonSlash) => Self::Anything,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   132
            Some(Self::Anything) => Self::Anything,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   133
        }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   134
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   135
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   136
    fn to_re(self) -> PreRegex {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   137
        match self {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   138
            Self::AnyComponents => PreRegex::preceding_dir_components(),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   139
            Self::AnyNonSlash => PreRegex::NonslashStar,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   140
            Self::Anything => PreRegex::DotStar,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   141
        }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   142
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   143
}
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   144
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   145
fn glob_parse_after_star(input: &mut &[u8]) -> GlobWildcard {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   146
    if let Some((b'*', rest)) = input.split_first() {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   147
        if let Some((b'/', rest)) = rest.split_first() {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   148
            *input = rest;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   149
            GlobWildcard::AnyComponents
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   150
        } else {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   151
            *input = rest;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   152
            GlobWildcard::Anything
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   153
        }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   154
    } else {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   155
        GlobWildcard::AnyNonSlash
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   156
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   157
}
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   158
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   159
/// The result of glob to re conversion.
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   160
/// The start of the regular expression `start` is tracked
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   161
/// separately for a pattern simplification opportunity
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   162
/// (see `GlobWildcard::make_unrooted`)
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   163
pub struct GlobToRe {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   164
    start: Option<GlobWildcard>,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   165
    rest: Vec<PreRegex>,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   166
}
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   167
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   168
impl GlobToRe {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   169
    /// Convert to a regex. `rooted` specifies if the glob should match
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   170
    /// at the root of the repo (true), or anywhere in the repo (false)
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   171
    fn into_re(self, rooted: bool) -> PreRegex {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   172
        let wildcard = if !rooted {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   173
            Some(GlobWildcard::make_unrooted(self.start))
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   174
        } else {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   175
            self.start
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   176
        };
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   177
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   178
        let mut res: Vec<_> =
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   179
            wildcard.into_iter().map(|x| x.to_re()).collect();
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   180
        res.extend(self.rest);
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   181
        PreRegex::Sequence(res)
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   182
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   183
}
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   184
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   185
/// Transforms a glob pattern into a regex.
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   186
pub fn glob_to_re(pat: &[u8]) -> PatternResult<GlobToRe> {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   187
    let mut start = None;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   188
    let mut res: Vec<PreRegex> = vec![];
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   189
    let mut input = pat;
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   190
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   191
    let mut group_stack = vec![];
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   192
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   193
    let add_byte = |out: &mut Vec<PreRegex>, b: u8| match out.last_mut() {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   194
        Some(PreRegex::Bytes(v)) => {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   195
            v.push(b);
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   196
        }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   197
        _ => out.push(PreRegex::Bytes(vec![b])),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   198
    };
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   199
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   200
    while let Some((c, rest)) = input.split_first() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   201
        input = rest;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   202
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   203
        match c {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   204
            b'*' => {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   205
                let wildcard = glob_parse_after_star(&mut input);
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   206
                if res.is_empty() && start.is_none() {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   207
                    start = Some(wildcard)
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   208
                } else {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   209
                    res.push(wildcard.to_re())
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   210
                }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   211
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   212
            b'?' => res.push(PreRegex::Dot),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   213
            b'[' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   214
                match input.iter().skip(1).position(|b| *b == b']') {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   215
                    None => res.push(PreRegex::Byte(b'[')),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   216
                    Some(end) => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   217
                        // Account for the one we skipped
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   218
                        let end = end + 1;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   219
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   220
                        // TODO: parse charsets ourselves?
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   221
                        let mut class = vec![];
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   222
                        class.extend(b"[");
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   223
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   224
                        for (i, b) in input[..end].iter().enumerate() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   225
                            if *b == b'!' && i == 0 {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   226
                                class.extend(b"^")
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   227
                            } else if *b == b'^' && i == 0 {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   228
                                class.extend(b"\\^")
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   229
                            } else if *b == b'\\' {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   230
                                class.extend(b"\\\\")
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   231
                            } else {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   232
                                class.push(*b)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   233
                            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   234
                        }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   235
                        class.extend(b"]");
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   236
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   237
                        res.push(PreRegex::parse(&class)?);
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   238
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   239
                        input = &input[end + 1..];
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   240
                    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   241
                }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   242
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   243
            b'{' => {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   244
                group_stack.push((mem::take(&mut res), vec![]));
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   245
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   246
            b'}' if !group_stack.is_empty() => {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   247
                let hir = PreRegex::Sequence(mem::take(&mut res));
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   248
                let (old_res, mut alt) = group_stack.pop().unwrap();
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   249
                alt.push(hir);
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   250
                res = old_res;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   251
                res.push(PreRegex::Alternation(alt));
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   252
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   253
            b',' if !group_stack.is_empty() => {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   254
                let frame = group_stack.last_mut().unwrap();
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   255
                frame.1.push(PreRegex::Sequence(mem::take(&mut res)));
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   256
            }
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   257
            b'\\' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   258
                let c = {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   259
                    if let Some((c, rest)) = input.split_first() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   260
                        input = rest;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   261
                        c
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   262
                    } else {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   263
                        c
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   264
                    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   265
                };
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   266
                add_byte(&mut res, *c)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   267
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   268
            _ => add_byte(&mut res, *c),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   269
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   270
    }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   271
    if !group_stack.is_empty() {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   272
        return Err(PatternError::UnsupportedSyntax(
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   273
            "error: invalid glob, has unclosed alternation ('{')".to_string(),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   274
        ));
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   275
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   276
    Ok(GlobToRe { start, rest: res })
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   277
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   278
51602
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   279
pub fn parse_pattern_syntax_kind(
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   280
    kind: &[u8],
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   281
) -> Result<PatternSyntax, PatternError> {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   282
    match kind {
51602
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   283
        b"re" => Ok(PatternSyntax::Regexp),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   284
        b"path" => Ok(PatternSyntax::Path),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   285
        b"filepath" => Ok(PatternSyntax::FilePath),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   286
        b"relpath" => Ok(PatternSyntax::RelPath),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   287
        b"rootfilesin" => Ok(PatternSyntax::RootFilesIn),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   288
        b"relglob" => Ok(PatternSyntax::RelGlob),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   289
        b"relre" => Ok(PatternSyntax::RelRegexp),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   290
        b"glob" => Ok(PatternSyntax::Glob),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   291
        b"rootglob" => Ok(PatternSyntax::RootGlob),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   292
        b"include" => Ok(PatternSyntax::Include),
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51565
diff changeset
   293
        b"subinclude" => Ok(PatternSyntax::SubInclude),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   294
        _ => Err(PatternError::UnsupportedSyntax(
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   295
            String::from_utf8_lossy(kind).to_string(),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   296
        )),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   297
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   298
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   299
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   300
lazy_static! {
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   301
    static ref FLAG_RE: Regex = Regex::new(r"^\(\?[aiLmsux]+\)").unwrap();
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   302
}
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   303
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   304
/// Extra path components to match at the end of the pattern
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   305
#[derive(Clone, Copy)]
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   306
pub enum GlobSuffix {
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   307
    /// `Empty` means the pattern only matches files, not directories,
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   308
    /// so the path needs to match exactly.
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   309
    Empty,
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   310
    /// `MoreComponents` means the pattern matches directories as well,
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   311
    /// so any path that has the pattern as a prefix, should match.
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   312
    MoreComponents,
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   313
}
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   314
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   315
impl GlobSuffix {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   316
    pub fn to_re(self) -> PreRegex {
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   317
        match self {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   318
            Self::Empty => PreRegex::Eof,
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   319
            Self::MoreComponents => PreRegex::SlashOrEof,
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   320
        }
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   321
    }
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   322
}
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   323
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   324
/// Builds the regex that corresponds to the given pattern.
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   325
/// If within a `syntax: regexp` context, returns the pattern,
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   326
/// otherwise, returns the corresponding regex.
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   327
fn _build_single_regex(
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   328
    entry: &IgnorePattern,
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   329
    glob_suffix: GlobSuffix,
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   330
) -> PatternResult<PreRegex> {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   331
    let IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   332
        syntax, pattern, ..
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   333
    } = entry;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   334
    if pattern.is_empty() {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   335
        return Ok(PreRegex::Empty);
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   336
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   337
    match syntax {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   338
        PatternSyntax::Regexp => PreRegex::parse(pattern),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   339
        PatternSyntax::RelRegexp => {
44593
496868f1030c rust-matchers: use the `regex` crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44304
diff changeset
   340
            // The `regex` crate accepts `**` while `re2` and Python's `re`
496868f1030c rust-matchers: use the `regex` crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44304
diff changeset
   341
            // do not. Checking for `*` correctly triggers the same error all
496868f1030c rust-matchers: use the `regex` crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44304
diff changeset
   342
            // engines.
44833
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44832
diff changeset
   343
            if pattern[0] == b'^'
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44832
diff changeset
   344
                || pattern[0] == b'*'
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44832
diff changeset
   345
                || pattern.starts_with(b".*")
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44832
diff changeset
   346
            {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   347
                return PreRegex::parse(pattern);
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   348
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   349
            let re = match FLAG_RE.find(pattern) {
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   350
                Some(mat) => {
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   351
                    let s = mat.start();
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   352
                    let e = mat.end();
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   353
                    [
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   354
                        &b"(?"[..],
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   355
                        &pattern[s + 2..e - 1],
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   356
                        &b":"[..],
49605
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   357
                        if pattern[e] == b'^'
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   358
                            || pattern[e] == b'*'
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   359
                            || pattern[e..].starts_with(b".*")
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   360
                        {
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   361
                            &b""[..]
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   362
                        } else {
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   363
                            &b".*"[..]
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
   364
                        },
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   365
                        &pattern[e..],
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   366
                        &b")"[..],
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   367
                    ]
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   368
                    .concat()
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   369
                }
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
   370
                None => [&b".*"[..], pattern].concat(),
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   371
            };
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   372
            PreRegex::parse(&re)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   373
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   374
        PatternSyntax::Path | PatternSyntax::RelPath => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   375
            if pattern == b"." {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   376
                return Ok(PreRegex::Empty);
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   377
            }
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   378
            Ok(PreRegex::Sequence(vec![
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   379
                PreRegex::literal(pattern),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   380
                GlobSuffix::MoreComponents.to_re(),
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   381
            ]))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   382
        }
51565
2a89d2f6336f match: rename RootFiles to RootFilesIn for more consistency
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51467
diff changeset
   383
        PatternSyntax::RootFilesIn => {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   384
            let re = if pattern == b"." {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   385
                PreRegex::Empty
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   386
            } else {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   387
                // Pattern is a directory name.
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   388
                let mut pattern = pattern.clone();
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   389
                pattern.push(b'/');
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   390
                PreRegex::Bytes(pattern)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   391
            };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   392
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   393
            // Anything after the pattern must be a non-directory.
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   394
            Ok(PreRegex::Sequence(vec![re, PreRegex::parse(b"[^/]+$")?]))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   395
        }
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   396
        PatternSyntax::RelGlob => {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   397
            let glob_re = glob_to_re(pattern)?;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   398
            Ok(PreRegex::Sequence(vec![
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   399
                glob_re.into_re(false),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   400
                glob_suffix.to_re(),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   401
            ]))
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   402
        }
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   403
        PatternSyntax::Glob | PatternSyntax::RootGlob => {
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   404
            let glob_re = glob_to_re(pattern)?;
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   405
            Ok(PreRegex::Sequence(vec![
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   406
                glob_re.into_re(true),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   407
                glob_suffix.to_re(),
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   408
            ]))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   409
        }
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   410
        PatternSyntax::Include
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   411
        | PatternSyntax::SubInclude
50692
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   412
        | PatternSyntax::ExpandedSubInclude(_)
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   413
        | PatternSyntax::FilePath => unreachable!(),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   414
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   415
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   416
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   417
const GLOB_SPECIAL_CHARACTERS: [u8; 7] =
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   418
    [b'*', b'?', b'[', b']', b'{', b'}', b'\\'];
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   419
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   420
/// TODO support other platforms
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   421
#[cfg(unix)]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   422
pub fn normalize_path_bytes(bytes: &[u8]) -> Vec<u8> {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   423
    if bytes.is_empty() {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   424
        return b".".to_vec();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   425
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   426
    let sep = b'/';
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   427
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   428
    let mut initial_slashes = bytes.iter().take_while(|b| **b == sep).count();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   429
    if initial_slashes > 2 {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   430
        // POSIX allows one or two initial slashes, but treats three or more
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   431
        // as single slash.
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   432
        initial_slashes = 1;
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   433
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   434
    let components = bytes
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   435
        .split(|b| *b == sep)
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   436
        .filter(|c| !(c.is_empty() || c == b"."))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   437
        .fold(vec![], |mut acc, component| {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   438
            if component != b".."
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   439
                || (initial_slashes == 0 && acc.is_empty())
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   440
                || (!acc.is_empty() && acc[acc.len() - 1] == b"..")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   441
            {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   442
                acc.push(component)
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   443
            } else if !acc.is_empty() {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   444
                acc.pop();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   445
            }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   446
            acc
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   447
        });
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   448
    let mut new_bytes = components.join(&sep);
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   449
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   450
    if initial_slashes > 0 {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   451
        let mut buf: Vec<_> = (0..initial_slashes).map(|_| sep).collect();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   452
        buf.extend(new_bytes);
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   453
        new_bytes = buf;
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   454
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   455
    if new_bytes.is_empty() {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   456
        b".".to_vec()
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   457
    } else {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   458
        new_bytes
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   459
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   460
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   461
52353
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   462
/// Controls whether we want the emitted regex to cover all cases
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   463
/// or just the cases that are not covered by optimized code paths.
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   464
#[derive(Debug, Clone, Copy)]
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   465
pub enum RegexCompleteness {
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   466
    /// `Complete` emits a regex that handles all files, including the ones
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   467
    /// that are typically handled by a different code path.
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   468
    /// This is used in `hg debugignorerhg -a` to avoid missing some rules.
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   469
    Complete,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   470
    /// `ExcludeExactFiles` excludes the patterns that correspond to exact
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   471
    /// file matches. This is the normal behavior, and gives a potentially
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   472
    /// much smaller regex.
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   473
    ExcludeExactFiles,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   474
}
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   475
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   476
impl RegexCompleteness {
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   477
    fn may_exclude_exact_files(self) -> bool {
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   478
        match self {
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   479
            Self::Complete => false,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   480
            Self::ExcludeExactFiles => true,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   481
        }
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   482
    }
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   483
}
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   484
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   485
/// Wrapper function to `_build_single_regex` that short-circuits 'exact' globs
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   486
/// that don't need to be transformed into a regex.
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   487
pub fn build_single_regex(
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   488
    entry: &IgnorePattern,
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   489
    glob_suffix: GlobSuffix,
52353
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   490
    regex_config: RegexCompleteness,
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   491
) -> Result<Option<PreRegex>, PatternError> {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   492
    let IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   493
        pattern, syntax, ..
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   494
    } = entry;
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   495
    let pattern = match syntax {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   496
        PatternSyntax::RootGlob
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   497
        | PatternSyntax::Path
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   498
        | PatternSyntax::RelGlob
50855
df6dfad5009a rust-filepatterns: also normalize RelPath
Spencer Baugh <sbaugh@janestreet.com>
parents: 50854
diff changeset
   499
        | PatternSyntax::RelPath
51565
2a89d2f6336f match: rename RootFiles to RootFilesIn for more consistency
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51467
diff changeset
   500
        | PatternSyntax::RootFilesIn => normalize_path_bytes(pattern),
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   501
        PatternSyntax::Include | PatternSyntax::SubInclude => {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   502
            return Err(PatternError::NonRegexPattern(entry.clone()))
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   503
        }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   504
        _ => pattern.to_owned(),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   505
    };
50692
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   506
    let is_simple_rootglob = *syntax == PatternSyntax::RootGlob
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   507
        && !pattern.iter().any(|b| GLOB_SPECIAL_CHARACTERS.contains(b));
52353
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   508
    if regex_config.may_exclude_exact_files()
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   509
        && (is_simple_rootglob || syntax == &PatternSyntax::FilePath)
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   510
    {
44802
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44593
diff changeset
   511
        Ok(None)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   512
    } else {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   513
        let mut entry = entry.clone();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   514
        entry.pattern = pattern;
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   515
        Ok(Some(_build_single_regex(&entry, glob_suffix)?))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   516
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   517
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   518
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   519
lazy_static! {
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   520
    static ref SYNTAXES: FastHashMap<&'static [u8], PatternSyntax> = {
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42957
diff changeset
   521
        let mut m = FastHashMap::default();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   522
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   523
        m.insert(b"re:".as_ref(), PatternSyntax::Regexp);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   524
        m.insert(b"regexp:".as_ref(), PatternSyntax::Regexp);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   525
        m.insert(b"path:".as_ref(), PatternSyntax::Path);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   526
        m.insert(b"filepath:".as_ref(), PatternSyntax::FilePath);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   527
        m.insert(b"relpath:".as_ref(), PatternSyntax::RelPath);
51565
2a89d2f6336f match: rename RootFiles to RootFilesIn for more consistency
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51467
diff changeset
   528
        m.insert(b"rootfilesin:".as_ref(), PatternSyntax::RootFilesIn);
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   529
        m.insert(b"relglob:".as_ref(), PatternSyntax::RelGlob);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   530
        m.insert(b"relre:".as_ref(), PatternSyntax::RelRegexp);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   531
        m.insert(b"glob:".as_ref(), PatternSyntax::Glob);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   532
        m.insert(b"rootglob:".as_ref(), PatternSyntax::RootGlob);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   533
        m.insert(b"include:".as_ref(), PatternSyntax::Include);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   534
        m.insert(b"subinclude:".as_ref(), PatternSyntax::SubInclude);
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   535
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   536
        m
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   537
    };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   538
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   539
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   540
#[derive(Debug)]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   541
pub enum PatternFileWarning {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   542
    /// (file path, syntax bytes)
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   543
    InvalidSyntax(PathBuf, Vec<u8>),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   544
    /// File path
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   545
    NoSuchFile(PathBuf),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   546
}
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   547
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   548
pub fn parse_one_pattern(
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   549
    pattern: &[u8],
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   550
    source: &Path,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   551
    default: PatternSyntax,
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   552
    normalize: bool,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   553
) -> IgnorePattern {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   554
    let mut pattern_bytes: &[u8] = pattern;
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   555
    let mut syntax = default;
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   556
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   557
    for (s, val) in SYNTAXES.iter() {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   558
        if let Some(rest) = pattern_bytes.drop_prefix(s) {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   559
            syntax = val.clone();
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   560
            pattern_bytes = rest;
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   561
            break;
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   562
        }
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   563
    }
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   564
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   565
    let pattern = match syntax {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   566
        PatternSyntax::RootGlob
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   567
        | PatternSyntax::Path
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   568
        | PatternSyntax::Glob
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   569
        | PatternSyntax::RelGlob
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   570
        | PatternSyntax::RelPath
51565
2a89d2f6336f match: rename RootFiles to RootFilesIn for more consistency
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51467
diff changeset
   571
        | PatternSyntax::RootFilesIn
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   572
            if normalize =>
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   573
        {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   574
            normalize_path_bytes(pattern_bytes)
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   575
        }
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   576
        _ => pattern_bytes.to_vec(),
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   577
    };
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   578
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   579
    IgnorePattern {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   580
        syntax,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   581
        pattern,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   582
        source: source.to_owned(),
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   583
    }
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   584
}
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   585
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   586
pub fn parse_pattern_file_contents(
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   587
    lines: &[u8],
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   588
    file_path: &Path,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   589
    default_syntax_override: Option<PatternSyntax>,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   590
    warn: bool,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   591
    relativize: bool,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   592
) -> Result<(Vec<IgnorePattern>, Vec<PatternFileWarning>), PatternError> {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   593
    let comment_regex = Regex::new(r"((?:^|[^\\])(?:\\\\)*)#.*").unwrap();
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44834
diff changeset
   594
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44834
diff changeset
   595
    #[allow(clippy::trivial_regex)]
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   596
    let comment_escape_regex = Regex::new(r"\\#").unwrap();
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   597
    let mut inputs: Vec<IgnorePattern> = vec![];
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   598
    let mut warnings: Vec<PatternFileWarning> = vec![];
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   599
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   600
    let mut current_syntax =
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   601
        default_syntax_override.unwrap_or(PatternSyntax::RelRegexp);
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   602
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   603
    for mut line in lines.split(|c| *c == b'\n') {
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   604
        let line_buf;
42635
30f8e786868c rust-filepatterns: use literal b'#' instead of cast
Yuya Nishihara <yuya@tcha.org>
parents: 42634
diff changeset
   605
        if line.contains(&b'#') {
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   606
            if let Some(cap) = comment_regex.captures(line) {
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   607
                line = &line[..cap.get(1).unwrap().end()]
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   608
            }
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   609
            line_buf = comment_escape_regex.replace_all(line, NoExpand(b"#"));
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   610
            line = &line_buf;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   611
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   612
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   613
        let line = line.trim_end();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   614
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   615
        if line.is_empty() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   616
            continue;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   617
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   618
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   619
        if let Some(syntax) = line.drop_prefix(b"syntax:") {
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   620
            let syntax = syntax.trim();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   621
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   622
            if let Some(parsed) =
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   623
                SYNTAXES.get([syntax, &b":"[..]].concat().as_slice())
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   624
            {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   625
                current_syntax = parsed.clone();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   626
            } else if warn {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   627
                warnings.push(PatternFileWarning::InvalidSyntax(
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   628
                    file_path.to_owned(),
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   629
                    syntax.to_owned(),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   630
                ));
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   631
            }
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   632
        } else {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   633
            let pattern = parse_one_pattern(
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   634
                line,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   635
                file_path,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   636
                current_syntax.clone(),
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   637
                false,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   638
            );
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   639
            inputs.push(if relativize {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   640
                pattern.to_relative()
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   641
            } else {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   642
                pattern
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   643
            })
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   644
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   645
    }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   646
    Ok((inputs, warnings))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   647
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   648
50863
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   649
pub fn parse_pattern_args(
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   650
    patterns: Vec<Vec<u8>>,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   651
    cwd: &Path,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   652
    root: &Path,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   653
) -> Result<Vec<IgnorePattern>, HgPathError> {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   654
    let mut ignore_patterns: Vec<IgnorePattern> = Vec::new();
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   655
    for pattern in patterns {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   656
        let pattern = parse_one_pattern(
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   657
            &pattern,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   658
            Path::new("<args>"),
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   659
            PatternSyntax::RelPath,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   660
            true,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   661
        );
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   662
        match pattern.syntax {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   663
            PatternSyntax::RelGlob | PatternSyntax::RelPath => {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   664
                let name = get_path_from_bytes(&pattern.pattern);
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   665
                let canon = canonical_path(root, cwd, name)?;
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   666
                ignore_patterns.push(IgnorePattern {
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   667
                    syntax: pattern.syntax,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   668
                    pattern: get_bytes_from_path(canon),
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   669
                    source: pattern.source,
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   670
                })
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   671
            }
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   672
            _ => ignore_patterns.push(pattern.to_owned()),
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   673
        };
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   674
    }
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   675
    Ok(ignore_patterns)
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   676
}
c112cc9effdc rhg: support "status FILE"
Spencer Baugh <sbaugh@janestreet.com>
parents: 50858
diff changeset
   677
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   678
pub fn read_pattern_file(
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   679
    file_path: &Path,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   680
    warn: bool,
49558
363923bd51cd dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49489
diff changeset
   681
    inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   682
) -> Result<(Vec<IgnorePattern>, Vec<PatternFileWarning>), PatternError> {
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   683
    match std::fs::read(file_path) {
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   684
        Ok(contents) => {
49558
363923bd51cd dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49489
diff changeset
   685
            inspect_pattern_bytes(file_path, &contents);
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   686
            parse_pattern_file_contents(&contents, file_path, None, warn, true)
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   687
        }
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   688
        Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok((
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   689
            vec![],
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   690
            vec![PatternFileWarning::NoSuchFile(file_path.to_owned())],
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   691
        )),
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   692
        Err(e) => Err(e.into()),
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   693
    }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   694
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   695
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   696
/// Represents an entry in an "ignore" file.
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   697
#[derive(Debug, Eq, PartialEq, Clone)]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   698
pub struct IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   699
    pub syntax: PatternSyntax,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   700
    pub pattern: Vec<u8>,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   701
    pub source: PathBuf,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   702
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   703
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   704
impl IgnorePattern {
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   705
    pub fn new(syntax: PatternSyntax, pattern: &[u8], source: &Path) -> Self {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   706
        Self {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   707
            syntax,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   708
            pattern: pattern.to_owned(),
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   709
            source: source.to_owned(),
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   710
        }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   711
    }
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   712
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   713
    pub fn to_relative(self) -> Self {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   714
        let Self {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   715
            syntax,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   716
            pattern,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   717
            source,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   718
        } = self;
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   719
        Self {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   720
            syntax: match syntax {
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   721
                PatternSyntax::Regexp => PatternSyntax::RelRegexp,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   722
                PatternSyntax::Glob => PatternSyntax::RelGlob,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   723
                x => x,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   724
            },
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   725
            pattern,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   726
            source,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   727
        }
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   728
    }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   729
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   730
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   731
pub type PatternResult<T> = Result<T, PatternError>;
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   732
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   733
/// Wrapper for `read_pattern_file` that also recursively expands `include:`
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   734
/// and `subinclude:` patterns.
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   735
///
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   736
/// The former are expanded in place, while `PatternSyntax::ExpandedSubInclude`
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   737
/// is used for the latter to form a tree of patterns.
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   738
pub fn get_patterns_from_file(
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   739
    pattern_file: &Path,
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   740
    root_dir: &Path,
49558
363923bd51cd dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49489
diff changeset
   741
    inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   742
) -> PatternResult<(Vec<IgnorePattern>, Vec<PatternFileWarning>)> {
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   743
    let (patterns, mut warnings) =
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   744
        read_pattern_file(pattern_file, true, inspect_pattern_bytes)?;
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   745
    let patterns = patterns
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   746
        .into_iter()
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   747
        .flat_map(|entry| -> PatternResult<_> {
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   748
            Ok(match &entry.syntax {
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   749
                PatternSyntax::Include => {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   750
                    let inner_include =
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   751
                        root_dir.join(get_path_from_bytes(&entry.pattern));
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   752
                    let (inner_pats, inner_warnings) = get_patterns_from_file(
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   753
                        &inner_include,
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   754
                        root_dir,
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   755
                        inspect_pattern_bytes,
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   756
                    )?;
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   757
                    warnings.extend(inner_warnings);
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   758
                    inner_pats
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   759
                }
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   760
                PatternSyntax::SubInclude => {
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   761
                    let mut sub_include = SubInclude::new(
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49928
diff changeset
   762
                        root_dir,
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   763
                        &entry.pattern,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   764
                        &entry.source,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   765
                    )?;
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   766
                    let (inner_patterns, inner_warnings) =
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   767
                        get_patterns_from_file(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   768
                            &sub_include.path,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   769
                            &sub_include.root,
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47379
diff changeset
   770
                            inspect_pattern_bytes,
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   771
                        )?;
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   772
                    sub_include.included_patterns = inner_patterns;
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   773
                    warnings.extend(inner_warnings);
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   774
                    vec![IgnorePattern {
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   775
                        syntax: PatternSyntax::ExpandedSubInclude(Box::new(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   776
                            sub_include,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   777
                        )),
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   778
                        ..entry
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   779
                    }]
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   780
                }
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   781
                _ => vec![entry],
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   782
            })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   783
        })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   784
        .flatten()
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   785
        .collect();
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   786
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   787
    Ok((patterns, warnings))
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   788
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   789
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   790
/// Holds all the information needed to handle a `subinclude:` pattern.
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   791
#[derive(Debug, PartialEq, Eq, Clone)]
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   792
pub struct SubInclude {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   793
    /// Will be used for repository (hg) paths that start with this prefix.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   794
    /// It is relative to the current working directory, so comparing against
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   795
    /// repository paths is painless.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   796
    pub prefix: HgPathBuf,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   797
    /// The file itself, containing the patterns
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   798
    pub path: PathBuf,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   799
    /// Folder in the filesystem where this it applies
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   800
    pub root: PathBuf,
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   801
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   802
    pub included_patterns: Vec<IgnorePattern>,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   803
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   804
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   805
impl SubInclude {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   806
    pub fn new(
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   807
        root_dir: &Path,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   808
        pattern: &[u8],
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   809
        source: &Path,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   810
    ) -> Result<SubInclude, HgPathError> {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   811
        let normalized_source =
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   812
            normalize_path_bytes(&get_bytes_from_path(source));
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   813
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   814
        let source_root = get_path_from_bytes(&normalized_source);
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   815
        let source_root = source_root.parent().unwrap_or(source_root);
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   816
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   817
        let path = source_root.join(get_path_from_bytes(pattern));
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44834
diff changeset
   818
        let new_root = path.parent().unwrap_or_else(|| path.deref());
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   819
47378
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
   820
        let prefix = canonical_path(root_dir, root_dir, new_root)?;
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   821
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   822
        Ok(Self {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49928
diff changeset
   823
            prefix: path_to_hg_path_buf(prefix).map(|mut p| {
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   824
                if !p.is_empty() {
48311
6d69e83e6b6e rhg: more efficient `HgPath::join`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47409
diff changeset
   825
                    p.push_byte(b'/');
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   826
                }
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49928
diff changeset
   827
                p
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   828
            })?,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   829
            path: path.to_owned(),
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   830
            root: new_root.to_owned(),
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   831
            included_patterns: Vec::new(),
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   832
        })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   833
    }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   834
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   835
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   836
/// Separate and pre-process subincludes from other patterns for the "ignore"
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   837
/// phase.
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   838
pub fn filter_subincludes(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   839
    ignore_patterns: Vec<IgnorePattern>,
49928
ccb6cfb0f2c0 rust-filepatterns: don't `Box` subincludes unnecessarily
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49605
diff changeset
   840
) -> Result<(Vec<SubInclude>, Vec<IgnorePattern>), HgPathError> {
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   841
    let mut subincludes = vec![];
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   842
    let mut others = vec![];
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   843
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   844
    for pattern in ignore_patterns {
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   845
        if let PatternSyntax::ExpandedSubInclude(sub_include) = pattern.syntax
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   846
        {
49928
ccb6cfb0f2c0 rust-filepatterns: don't `Box` subincludes unnecessarily
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49605
diff changeset
   847
            subincludes.push(*sub_include);
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   848
        } else {
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47378
diff changeset
   849
            others.push(pattern)
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   850
        }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   851
    }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   852
    Ok((subincludes, others))
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   853
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44303
diff changeset
   854
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   855
#[cfg(test)]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   856
mod tests {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   857
    use super::*;
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   858
    use pretty_assertions::assert_eq;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   859
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   860
    fn escape_pattern(pattern: &[u8]) -> Vec<u8> {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   861
        pattern
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   862
            .iter()
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   863
            .flat_map(|c| RE_ESCAPE[*c as usize].clone())
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   864
            .collect()
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   865
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   866
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   867
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   868
    fn escape_pattern_test() {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   869
        let untouched =
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   870
            br#"!"%',/0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz"#;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   871
        assert_eq!(escape_pattern(untouched), untouched.to_vec());
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   872
        // All escape codes
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   873
        assert_eq!(
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   874
            escape_pattern(br"()[]{}?*+-|^$\\.&~#\t\n\r\v\f"),
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   875
            br"\(\)\[\]\{\}\?\*\+\-\|\^\$\\\\\.\&\~\#\\t\\n\\r\\v\\f".to_vec()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   876
        );
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   877
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   878
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   879
    fn glob_to_re(pat: &[u8]) -> Vec<u8> {
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   880
        super::glob_to_re(pat).unwrap().into_re(true).to_bytes()
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   881
    }
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   882
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   883
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   884
    fn glob_test() {
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   885
        assert_eq!(glob_to_re(br"?"), br".");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   886
        assert_eq!(glob_to_re(br"*"), br"[^/]*");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   887
        assert_eq!(glob_to_re(br"**"), br".*");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   888
        assert_eq!(glob_to_re(br"**/a"), br"(?:.*/)?a");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   889
        assert_eq!(glob_to_re(br"a/**/b"), br"a/(?:.*/)?b");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   890
        assert_eq!(glob_to_re(br"[a*?!^][^b][!c]"), br"[a*?!^][\^b][^c]");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   891
        assert_eq!(glob_to_re(br"{a,b}"), br"(?:a|b)");
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50863
diff changeset
   892
        assert_eq!(glob_to_re(br".\*\?"), br"\.\*\?");
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   893
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   894
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   895
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   896
    fn test_parse_pattern_file_contents() {
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   897
        let lines = b"syntax: glob\n*.elc";
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   898
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   899
        assert_eq!(
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   900
            parse_pattern_file_contents(
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   901
                lines,
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   902
                Path::new("file_path"),
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   903
                None,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   904
                false,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   905
                true,
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   906
            )
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   907
            .unwrap()
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   908
            .0,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   909
            vec![IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   910
                PatternSyntax::RelGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   911
                b"*.elc",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   912
                Path::new("file_path")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   913
            )],
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   914
        );
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   915
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   916
        let lines = b"syntax: include\nsyntax: glob";
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   917
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   918
        assert_eq!(
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   919
            parse_pattern_file_contents(
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   920
                lines,
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   921
                Path::new("file_path"),
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   922
                None,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   923
                false,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   924
                true,
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   925
            )
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   926
            .unwrap()
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   927
            .0,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   928
            vec![]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   929
        );
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   930
        let lines = b"glob:**.o";
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   931
        assert_eq!(
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   932
            parse_pattern_file_contents(
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   933
                lines,
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   934
                Path::new("file_path"),
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   935
                None,
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   936
                false,
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50692
diff changeset
   937
                true,
49482
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   938
            )
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   939
            .unwrap()
5fbdd88824dc rust-filepatterns: allow overriding default syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48311
diff changeset
   940
            .0,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   941
            vec![IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   942
                PatternSyntax::RelGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   943
                b"**.o",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   944
                Path::new("file_path")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   945
            )]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   946
        );
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   947
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   948
52353
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   949
    pub fn build_single_regex(
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   950
        entry: &IgnorePattern,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   951
        glob_suffix: GlobSuffix,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   952
    ) -> Result<Option<Vec<u8>>, PatternError> {
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   953
        super::build_single_regex(
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   954
            entry,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   955
            glob_suffix,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   956
            RegexCompleteness::ExcludeExactFiles,
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   957
        )
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
   958
        .map(|re_opt| re_opt.map(|re| re.to_bytes()))
52353
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   959
    }
e2e49069eeb6 rust-ignore: make `debugignorerhg` command show a full regex, with exact files
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52352
diff changeset
   960
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   961
    #[test]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   962
    fn test_build_single_regex() {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   963
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   964
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   965
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   966
                    PatternSyntax::RelGlob,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   967
                    b"rust/target/",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   968
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   969
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   970
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   971
            )
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
   972
            .unwrap(),
44802
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44593
diff changeset
   973
            Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()),
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42327
diff changeset
   974
        );
44834
be6401a25726 rust-regex: add test for verbatim regex syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44833
diff changeset
   975
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   976
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   977
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   978
                    PatternSyntax::Regexp,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   979
                    br"rust/target/\d+",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   980
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   981
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   982
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   983
            )
44834
be6401a25726 rust-regex: add test for verbatim regex syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44833
diff changeset
   984
            .unwrap(),
be6401a25726 rust-regex: add test for verbatim regex syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44833
diff changeset
   985
            Some(br"rust/target/\d+".to_vec()),
be6401a25726 rust-regex: add test for verbatim regex syntax
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44833
diff changeset
   986
        );
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   987
    }
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
   988
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
   989
    #[test]
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
   990
    fn test_build_single_regex_shortcut() {
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
   991
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   992
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   993
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   994
                    PatternSyntax::RootGlob,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   995
                    b"",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   996
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   997
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
   998
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
   999
            )
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
  1000
            .unwrap(),
44802
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44593
diff changeset
  1001
            None,
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1002
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1003
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1004
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1005
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1006
                    PatternSyntax::RootGlob,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1007
                    b"whatever",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1008
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1009
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1010
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1011
            )
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
  1012
            .unwrap(),
44802
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44593
diff changeset
  1013
            None,
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1014
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1015
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1016
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1017
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1018
                    PatternSyntax::RootGlob,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1019
                    b"*.o",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1020
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1021
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1022
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1023
            )
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43826
diff changeset
  1024
            .unwrap(),
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44802
diff changeset
  1025
            Some(br"[^/]*\.o(?:/|$)".to_vec()),
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1026
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42437
diff changeset
  1027
    }
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1028
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1029
    #[test]
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1030
    fn test_build_single_relregex() {
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1031
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1032
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1033
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1034
                    PatternSyntax::RelRegexp,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1035
                    b"^ba{2}r",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1036
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1037
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1038
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1039
            )
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1040
            .unwrap(),
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1041
            Some(b"^ba{2}r".to_vec()),
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1042
        );
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1043
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1044
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1045
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1046
                    PatternSyntax::RelRegexp,
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1047
                    b"ba{2}r",
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1048
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1049
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1050
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1051
            )
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1052
            .unwrap(),
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1053
            Some(b".*ba{2}r".to_vec()),
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1054
        );
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1055
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1056
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1057
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1058
                    PatternSyntax::RelRegexp,
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
  1059
                    b"(?i)ba{2}r",
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1060
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1061
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1062
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1063
            )
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1064
            .unwrap(),
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
  1065
            Some(b"(?i:.*ba{2}r)".to_vec()),
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1066
        );
49605
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
  1067
        assert_eq!(
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1068
            build_single_regex(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1069
                &IgnorePattern::new(
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1070
                    PatternSyntax::RelRegexp,
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
  1071
                    b"(?i)^ba{2}r",
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1072
                    Path::new("")
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1073
                ),
52352
2ff004fb491c hgignore: add a GlobSuffix type, instead of passing byte arrays
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52302
diff changeset
  1074
                GlobSuffix::MoreComponents
50858
090658724abf rust: de-hardcode glob_suffix
Spencer Baugh <sbaugh@janestreet.com>
parents: 50856
diff changeset
  1075
            )
49605
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
  1076
            .unwrap(),
52556
1866119cbad7 rust-ignore: construct regex Hir object directly, avoiding large regex string
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 52353
diff changeset
  1077
            Some(b"(?i:^ba{2}r)".to_vec()),
49605
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49604
diff changeset
  1078
        );
49604
086b0c4f8663 matcher: fix the issue with regex inline-flag in rust oo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49558
diff changeset
  1079
    }
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
  1080
}