rust/hg-core/src/filepatterns.rs
author Raphaël Gomès <rgomes@octobus.net>
Thu, 07 May 2020 23:54:37 +0200
changeset 44834 be6401a25726
parent 44833 1e9bfeaec9ba
child 44973 26114bd6ec60
permissions -rw-r--r--
rust-regex: add test for verbatim regex syntax This makes sure it's not modified. Differential Revision: https://phab.mercurial-scm.org/D8508
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::{
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    11
    utils::{
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    12
        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
    13
        hg_path::{path_to_hg_path_buf, HgPathBuf, HgPathError},
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    14
        SliceExt,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    15
    },
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    16
    FastHashMap, PatternError,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    17
};
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42483
diff changeset
    18
use lazy_static::lazy_static;
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
    19
use regex::bytes::{NoExpand, Regex};
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
use std::fs::File;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
use std::io::Read;
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    22
use std::ops::Deref;
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
    23
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
    24
use std::vec::Vec;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
lazy_static! {
42483
a4a468b00d44 rust-filepatterns: silence warning of non_upper_case_globals
Yuya Nishihara <yuya@tcha.org>
parents: 42438
diff changeset
    27
    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
    28
        let mut v: Vec<Vec<u8>> = (0..=255).map(|byte| vec![byte]).collect();
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
        let to_escape = b"()[]{}?*+-|^$\\.&~# \t\n\r\x0b\x0c";
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
        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
    31
            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
    32
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
        v
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
    };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
/// These are matched in order
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
const GLOB_REPLACEMENTS: &[(&[u8], &[u8])] =
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
    &[(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
    40
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    41
/// Appended to the regexp of globs
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    42
const GLOB_SUFFIX: &[u8; 7] = b"(?:/|$)";
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    43
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
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
    46
    /// 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
    47
    Regexp,
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
    /// 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
    49
    RootGlob,
42841
ce6797ef6eab rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents: 42751
diff changeset
    50
    /// 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
    51
    /// slashes)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
    Glob,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    53
    /// 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
    54
    Path,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    55
    /// 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
    56
    RelPath,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    57
    /// 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
    58
    RelGlob,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    59
    /// 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
    60
    RelRegexp,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
    61
    /// 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
    62
    /// (will not match subdirectories)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
    RootFiles,
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    64
    /// 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
    65
    Include,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
    66
    /// 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
    67
    SubInclude,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    68
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    70
/// Transforms a glob pattern into a regex
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
fn glob_to_re(pat: &[u8]) -> Vec<u8> {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
    let mut input = pat;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    73
    let mut res: Vec<u8> = vec![];
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    74
    let mut group_depth = 0;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    75
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    76
    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
    77
        input = rest;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    78
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
        match c {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
            b'*' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
                for (source, repl) in GLOB_REPLACEMENTS {
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
    82
                    if let Some(rest) = input.drop_prefix(source) {
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
    83
                        input = rest;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    84
                        res.extend(*repl);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
                        break;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
                    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    87
                }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    88
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    89
            b'?' => res.extend(b"."),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
            b'[' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    91
                match input.iter().skip(1).position(|b| *b == b']') {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    92
                    None => res.extend(b"\\["),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
                    Some(end) => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
                        // 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
    95
                        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
    96
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
                        res.extend(b"[");
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    98
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
                        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
   100
                            if *b == b'!' && i == 0 {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
                                res.extend(b"^")
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   102
                            } else if *b == b'^' && i == 0 {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   103
                                res.extend(b"\\^")
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   104
                            } else if *b == b'\\' {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   105
                                res.extend(b"\\\\")
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   106
                            } else {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   107
                                res.push(*b)
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   108
                            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   109
                        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   110
                        res.extend(b"]");
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   111
                        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
   112
                    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
                }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
            b'{' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   116
                group_depth += 1;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   117
                res.extend(b"(?:")
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   119
            b'}' if group_depth > 0 => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   120
                group_depth -= 1;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   121
                res.extend(b")");
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   122
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   123
            b',' if group_depth > 0 => res.extend(b"|"),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   124
            b'\\' => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   125
                let c = {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   126
                    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
   127
                        input = rest;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   128
                        c
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   129
                    } else {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   130
                        c
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   131
                    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   132
                };
42483
a4a468b00d44 rust-filepatterns: silence warning of non_upper_case_globals
Yuya Nishihara <yuya@tcha.org>
parents: 42438
diff changeset
   133
                res.extend(&RE_ESCAPE[*c as usize])
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   134
            }
42483
a4a468b00d44 rust-filepatterns: silence warning of non_upper_case_globals
Yuya Nishihara <yuya@tcha.org>
parents: 42438
diff changeset
   135
            _ => res.extend(&RE_ESCAPE[*c as usize]),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   136
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   137
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   138
    res
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   139
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   140
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   141
fn escape_pattern(pattern: &[u8]) -> Vec<u8> {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   142
    pattern
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   143
        .iter()
42483
a4a468b00d44 rust-filepatterns: silence warning of non_upper_case_globals
Yuya Nishihara <yuya@tcha.org>
parents: 42438
diff changeset
   144
        .flat_map(|c| RE_ESCAPE[*c as usize].clone())
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   145
        .collect()
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   146
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   147
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   148
pub fn parse_pattern_syntax(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   149
    kind: &[u8],
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   150
) -> 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
   151
    match kind {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   152
        b"re:" => Ok(PatternSyntax::Regexp),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   153
        b"path:" => Ok(PatternSyntax::Path),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   154
        b"relpath:" => Ok(PatternSyntax::RelPath),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   155
        b"rootfilesin:" => Ok(PatternSyntax::RootFiles),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   156
        b"relglob:" => Ok(PatternSyntax::RelGlob),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   157
        b"relre:" => Ok(PatternSyntax::RelRegexp),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   158
        b"glob:" => Ok(PatternSyntax::Glob),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   159
        b"rootglob:" => Ok(PatternSyntax::RootGlob),
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   160
        b"include:" => Ok(PatternSyntax::Include),
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   161
        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
   162
        _ => Err(PatternError::UnsupportedSyntax(
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   163
            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
   164
        )),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   165
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   166
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   167
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   168
/// 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
   169
/// 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
   170
/// otherwise, returns the corresponding regex.
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   171
fn _build_single_regex(entry: &IgnorePattern) -> Vec<u8> {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   172
    let IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   173
        syntax, pattern, ..
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   174
    } = entry;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   175
    if pattern.is_empty() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   176
        return vec![];
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   177
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   178
    match syntax {
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44802
diff changeset
   179
        PatternSyntax::Regexp => pattern.to_owned(),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   180
        PatternSyntax::RelRegexp => {
44593
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44304
diff changeset
   181
            // 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
   182
            // 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
   183
            // engines.
44833
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Raphaël Gomès <rgomes@octobus.net>
parents: 44832
diff changeset
   184
            if pattern[0] == b'^'
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Raphaël Gomès <rgomes@octobus.net>
parents: 44832
diff changeset
   185
                || pattern[0] == b'*'
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Raphaël Gomès <rgomes@octobus.net>
parents: 44832
diff changeset
   186
                || pattern.starts_with(b".*")
1e9bfeaec9ba rust-regex: prevent nonsensical `.*.*` pattern from happening
Raphaël Gomès <rgomes@octobus.net>
parents: 44832
diff changeset
   187
            {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   188
                return pattern.to_owned();
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   189
            }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   190
            [&b".*"[..], pattern].concat()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   191
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   192
        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
   193
            if pattern == b"." {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   194
                return vec![];
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   195
            }
42865
69195b6f8f97 rustfilepatterns: shorter code for concatenating slices
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42864
diff changeset
   196
            [escape_pattern(pattern).as_slice(), b"(?:/|$)"].concat()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   197
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   198
        PatternSyntax::RootFiles => {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   199
            let mut res = if pattern == b"." {
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44802
diff changeset
   200
                vec![]
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   201
            } else {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   202
                // Pattern is a directory name.
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44802
diff changeset
   203
                [escape_pattern(pattern).as_slice(), b"/"].concat()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   204
            };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   205
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   206
            // Anything after the pattern must be a non-directory.
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   207
            res.extend(b"[^/]+$");
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   208
            res
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   209
        }
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   210
        PatternSyntax::RelGlob => {
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   211
            let glob_re = glob_to_re(pattern);
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   212
            if let Some(rest) = glob_re.drop_prefix(b"[^/]*") {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   213
                [b".*", rest, GLOB_SUFFIX].concat()
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   214
            } else {
44593
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44304
diff changeset
   215
                [b"(?:.*/)?", glob_re.as_slice(), GLOB_SUFFIX].concat()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   216
            }
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   217
        }
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42863
diff changeset
   218
        PatternSyntax::Glob | PatternSyntax::RootGlob => {
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44802
diff changeset
   219
            [glob_to_re(pattern).as_slice(), GLOB_SUFFIX].concat()
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   220
        }
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   221
        PatternSyntax::Include | PatternSyntax::SubInclude => unreachable!(),
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   222
    }
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
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   225
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
   226
    [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
   227
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   228
/// 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
   229
#[cfg(unix)]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   230
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
   231
    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
   232
        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
   233
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   234
    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
   235
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   236
    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
   237
    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
   238
        // 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
   239
        // 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
   240
        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
   241
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   242
    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
   243
        .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
   244
        .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
   245
        .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
   246
            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
   247
                || (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
   248
                || (!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
   249
            {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   250
                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
   251
            } 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
   252
                acc.pop();
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   253
            }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   254
            acc
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   255
        });
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   256
    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
   257
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   258
    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
   259
        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
   260
        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
   261
        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
   262
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   263
    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
   264
        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
   265
    } else {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   266
        new_bytes
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   267
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   268
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   269
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   270
/// 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
   271
/// 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
   272
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
   273
    entry: &IgnorePattern,
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
   274
) -> Result<Option<Vec<u8>>, PatternError> {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   275
    let IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   276
        pattern, syntax, ..
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   277
    } = entry;
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   278
    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
   279
        PatternSyntax::RootGlob
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   280
        | PatternSyntax::Path
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   281
        | PatternSyntax::RelGlob
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   282
        | PatternSyntax::RootFiles => 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
   283
        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
   284
            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
   285
        }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   286
        _ => 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
   287
    };
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   288
    if *syntax == PatternSyntax::RootGlob
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   289
        && !pattern.iter().any(|b| GLOB_SPECIAL_CHARACTERS.contains(b))
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   290
    {
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
   291
        Ok(None)
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   292
    } else {
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   293
        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
   294
        entry.pattern = pattern;
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
   295
        Ok(Some(_build_single_regex(&entry)))
42327
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
lazy_static! {
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
   300
    static ref SYNTAXES: FastHashMap<&'static [u8], &'static [u8]> = {
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
   301
        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
   302
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   303
        m.insert(b"re".as_ref(), b"relre:".as_ref());
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   304
        m.insert(b"regexp".as_ref(), b"relre:".as_ref());
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   305
        m.insert(b"glob".as_ref(), b"relglob:".as_ref());
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   306
        m.insert(b"rootglob".as_ref(), b"rootglob:".as_ref());
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   307
        m.insert(b"include".as_ref(), b"include:".as_ref());
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   308
        m.insert(b"subinclude".as_ref(), b"subinclude:".as_ref());
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   309
        m
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   310
    };
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   311
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   312
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   313
#[derive(Debug)]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   314
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
   315
    /// (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
   316
    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
   317
    /// File path
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   318
    NoSuchFile(PathBuf),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   319
}
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   320
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   321
pub fn parse_pattern_file_contents<P: AsRef<Path>>(
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   322
    lines: &[u8],
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   323
    file_path: P,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   324
    warn: bool,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   325
) -> 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
   326
    let comment_regex = Regex::new(r"((?:^|[^\\])(?:\\\\)*)#.*").unwrap();
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   327
    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
   328
    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
   329
    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
   330
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   331
    let mut current_syntax = b"relre:".as_ref();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   332
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   333
    for (line_number, mut line) in lines.split(|c| *c == b'\n').enumerate() {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   334
        let line_number = line_number + 1;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   335
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   336
        let line_buf;
42635
30f8e786868c rust-filepatterns: use literal b'#' instead of cast
Yuya Nishihara <yuya@tcha.org>
parents: 42634
diff changeset
   337
        if line.contains(&b'#') {
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   338
            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
   339
                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
   340
            }
42636
12addcc7956c rust-filepatterns: unescape comment character property
Yuya Nishihara <yuya@tcha.org>
parents: 42635
diff changeset
   341
            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
   342
            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
   343
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   344
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   345
        let mut line = line.trim_end();
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   346
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   347
        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
   348
            continue;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   349
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   350
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   351
        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
   352
            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
   353
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   354
            if let Some(rel_syntax) = SYNTAXES.get(syntax) {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   355
                current_syntax = rel_syntax;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   356
            } 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
   357
                warnings.push(PatternFileWarning::InvalidSyntax(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   358
                    file_path.as_ref().to_owned(),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   359
                    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
   360
                ));
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   361
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   362
            continue;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   363
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   364
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   365
        let mut line_syntax: &[u8] = &current_syntax;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   366
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   367
        for (s, rels) in SYNTAXES.iter() {
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   368
            if let Some(rest) = line.drop_prefix(rels) {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   369
                line_syntax = rels;
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   370
                line = rest;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   371
                break;
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   372
            }
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   373
            if let Some(rest) = line.drop_prefix(&[s, &b":"[..]].concat()) {
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   374
                line_syntax = rels;
42863
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42841
diff changeset
   375
                line = rest;
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   376
                break;
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   377
            }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   378
        }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   379
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   380
        inputs.push(IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   381
            parse_pattern_syntax(&line_syntax).map_err(|e| match e {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   382
                PatternError::UnsupportedSyntax(syntax) => {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   383
                    PatternError::UnsupportedSyntaxInFile(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   384
                        syntax,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   385
                        file_path.as_ref().to_string_lossy().into(),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   386
                        line_number,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   387
                    )
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   388
                }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   389
                _ => e,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   390
            })?,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   391
            &line,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   392
            &file_path,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   393
        ));
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   394
    }
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   395
    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
   396
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   397
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   398
pub fn read_pattern_file<P: AsRef<Path>>(
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   399
    file_path: P,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   400
    warn: bool,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   401
) -> Result<(Vec<IgnorePattern>, Vec<PatternFileWarning>), PatternError> {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   402
    let mut f = match File::open(file_path.as_ref()) {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   403
        Ok(f) => Ok(f),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   404
        Err(e) => match e.kind() {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   405
            std::io::ErrorKind::NotFound => {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   406
                return Ok((
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   407
                    vec![],
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   408
                    vec![PatternFileWarning::NoSuchFile(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   409
                        file_path.as_ref().to_owned(),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   410
                    )],
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   411
                ))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   412
            }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   413
            _ => Err(e),
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   414
        },
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   415
    }?;
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   416
    let mut contents = Vec::new();
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   417
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   418
    f.read_to_end(&mut contents)?;
42327
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
    Ok(parse_pattern_file_contents(&contents, file_path, warn)?)
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   421
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   422
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   423
/// 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
   424
#[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
   425
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
   426
    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
   427
    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
   428
    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
   429
}
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   430
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   431
impl IgnorePattern {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   432
    pub fn new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   433
        syntax: PatternSyntax,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   434
        pattern: &[u8],
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   435
        source: impl AsRef<Path>,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   436
    ) -> Self {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   437
        Self {
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   438
            syntax,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   439
            pattern: 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
   440
            source: source.as_ref().to_owned(),
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
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   443
}
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   444
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   445
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
   446
44304
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   447
/// Wrapper for `read_pattern_file` that also recursively expands `include:`
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   448
/// patterns.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   449
///
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   450
/// `subinclude:` is not treated as a special pattern here: unraveling them
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   451
/// needs to occur in the "ignore" phase.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   452
pub fn get_patterns_from_file(
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   453
    pattern_file: impl AsRef<Path>,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   454
    root_dir: impl AsRef<Path>,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   455
) -> PatternResult<(Vec<IgnorePattern>, Vec<PatternFileWarning>)> {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   456
    let (patterns, mut warnings) = read_pattern_file(&pattern_file, true)?;
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   457
    let patterns = patterns
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   458
        .into_iter()
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   459
        .flat_map(|entry| -> PatternResult<_> {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   460
            let IgnorePattern {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   461
                syntax,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   462
                pattern,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   463
                source: _,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   464
            } = &entry;
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   465
            Ok(match syntax {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   466
                PatternSyntax::Include => {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   467
                    let inner_include =
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   468
                        root_dir.as_ref().join(get_path_from_bytes(&pattern));
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   469
                    let (inner_pats, inner_warnings) = get_patterns_from_file(
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   470
                        &inner_include,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   471
                        root_dir.as_ref(),
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   472
                    )?;
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   473
                    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
   474
                    inner_pats
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   475
                }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   476
                _ => vec![entry],
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   477
            })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   478
        })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   479
        .flatten()
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   480
        .collect();
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   481
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   482
    Ok((patterns, warnings))
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   483
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   484
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   485
/// Holds all the information needed to handle a `subinclude:` pattern.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   486
pub struct SubInclude {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   487
    /// 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
   488
    /// 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
   489
    /// 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
   490
    pub prefix: HgPathBuf,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   491
    /// 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
   492
    pub path: PathBuf,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   493
    /// 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
   494
    pub root: PathBuf,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   495
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   496
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   497
impl SubInclude {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   498
    pub fn new(
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   499
        root_dir: impl AsRef<Path>,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   500
        pattern: &[u8],
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   501
        source: impl AsRef<Path>,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   502
    ) -> Result<SubInclude, HgPathError> {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   503
        let normalized_source =
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   504
            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
   505
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   506
        let source_root = get_path_from_bytes(&normalized_source);
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   507
        let source_root = source_root.parent().unwrap_or(source_root.deref());
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   508
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   509
        let path = source_root.join(get_path_from_bytes(pattern));
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   510
        let new_root = path.parent().unwrap_or(path.deref());
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   511
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   512
        let prefix = canonical_path(&root_dir, &root_dir, new_root)?;
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   513
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   514
        Ok(Self {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   515
            prefix: path_to_hg_path_buf(prefix).and_then(|mut p| {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   516
                if !p.is_empty() {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   517
                    p.push(b'/');
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   518
                }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   519
                Ok(p)
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   520
            })?,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   521
            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
   522
            root: new_root.to_owned(),
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   523
        })
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   524
    }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   525
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   526
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   527
/// 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
   528
/// phase.
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   529
pub fn filter_subincludes(
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   530
    ignore_patterns: &[IgnorePattern],
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   531
    root_dir: impl AsRef<Path>,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   532
) -> Result<(Vec<SubInclude>, Vec<&IgnorePattern>), HgPathError> {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   533
    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
   534
    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
   535
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   536
    for ignore_pattern in ignore_patterns.iter() {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   537
        let IgnorePattern {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   538
            syntax,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   539
            pattern,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   540
            source,
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   541
        } = ignore_pattern;
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   542
        if *syntax == PatternSyntax::SubInclude {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   543
            subincludes.push(SubInclude::new(&root_dir, pattern, &source)?);
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   544
        } else {
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   545
            others.push(ignore_pattern)
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   546
        }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   547
    }
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   548
    Ok((subincludes, others))
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   549
}
2fe89bec8011 rust-filepatterns: add support for `include` and `subinclude` patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44303
diff changeset
   550
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   551
#[cfg(test)]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   552
mod tests {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   553
    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
   554
    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
   555
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   556
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   557
    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
   558
        let untouched =
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   559
            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
   560
        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
   561
        // All escape codes
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   562
        assert_eq!(
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   563
            escape_pattern(br#"()[]{}?*+-|^$\\.&~# \t\n\r\v\f"#),
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   564
            br#"\(\)\[\]\{\}\?\*\+\-\|\^\$\\\\\.\&\~\#\ \\t\\n\\r\\v\\f"#
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   565
                .to_vec()
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   566
        );
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   567
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   568
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   569
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   570
    fn glob_test() {
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   571
        assert_eq!(glob_to_re(br#"?"#), br#"."#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   572
        assert_eq!(glob_to_re(br#"*"#), br#"[^/]*"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   573
        assert_eq!(glob_to_re(br#"**"#), br#".*"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   574
        assert_eq!(glob_to_re(br#"**/a"#), br#"(?:.*/)?a"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   575
        assert_eq!(glob_to_re(br#"a/**/b"#), br#"a/(?:.*/)?b"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   576
        assert_eq!(glob_to_re(br#"[a*?!^][^b][!c]"#), br#"[a*?!^][\^b][^c]"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   577
        assert_eq!(glob_to_re(br#"{a,b}"#), br#"(?:a|b)"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   578
        assert_eq!(glob_to_re(br#".\*\?"#), br#"\.\*\?"#);
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   579
    }
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   580
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   581
    #[test]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   582
    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
   583
        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
   584
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   585
        assert_eq!(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   586
            parse_pattern_file_contents(lines, Path::new("file_path"), false)
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   587
                .unwrap()
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   588
                .0,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   589
            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
   590
                PatternSyntax::RelGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   591
                b"*.elc",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   592
                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
   593
            )],
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   594
        );
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   595
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   596
        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
   597
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   598
        assert_eq!(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   599
            parse_pattern_file_contents(lines, Path::new("file_path"), false)
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   600
                .unwrap()
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   601
                .0,
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   602
            vec![]
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   603
        );
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   604
        let lines = b"glob:**.o";
9609430d3625 rust-filepatterns: use bytes instead of String
Raphaël Gomès <rgomes@octobus.net>
parents: 42327
diff changeset
   605
        assert_eq!(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   606
            parse_pattern_file_contents(lines, Path::new("file_path"), false)
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   607
                .unwrap()
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42865
diff changeset
   608
                .0,
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   609
            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
   610
                PatternSyntax::RelGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   611
                b"**.o",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   612
                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
   613
            )]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   614
        );
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   615
    }
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   616
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   617
    #[test]
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   618
    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
   619
        assert_eq!(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   620
            build_single_regex(&IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   621
                PatternSyntax::RelGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   622
                b"rust/target/",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   623
                Path::new("")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   624
            ))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   625
            .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
   626
            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
   627
        );
44834
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   628
        assert_eq!(
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   629
            build_single_regex(&IgnorePattern::new(
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   630
                PatternSyntax::Regexp,
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   631
                br"rust/target/\d+",
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   632
                Path::new("")
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   633
            ))
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   634
            .unwrap(),
be6401a25726 rust-regex: add test for verbatim regex syntax
Raphaël Gomès <rgomes@octobus.net>
parents: 44833
diff changeset
   635
            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
   636
        );
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   637
    }
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   638
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   639
    #[test]
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   640
    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
   641
        assert_eq!(
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   642
            build_single_regex(&IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   643
                PatternSyntax::RootGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   644
                b"",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   645
                Path::new("")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   646
            ))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   647
            .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
   648
            None,
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   649
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   650
        assert_eq!(
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   651
            build_single_regex(&IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   652
                PatternSyntax::RootGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   653
                b"whatever",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   654
                Path::new("")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   655
            ))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   656
            .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
   657
            None,
42438
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   658
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   659
        assert_eq!(
44303
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   660
            build_single_regex(&IgnorePattern::new(
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   661
                PatternSyntax::RootGlob,
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   662
                b"*.o",
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   663
                Path::new("")
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   664
            ))
d42eea9a0494 rust-filepatterns: improve API and robustness for pattern files parsing
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   665
            .unwrap(),
44832
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44802
diff changeset
   666
            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
   667
        );
48f1f864d928 rust-regex: fix shortcut for exact matches
Raphaël Gomès <rgomes@octobus.net>
parents: 42437
diff changeset
   668
    }
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   669
}