rust/hg-core/src/sparse.rs
author Arseniy Alekseyev <aalekseyev@janestreet.com>
Thu, 10 Aug 2023 19:00:19 +0100
branchstable
changeset 50818 28c0fcff24e5
parent 49930 e98fd81bb151
child 50854 796b5d6693a4
permissions -rw-r--r--
rhg: fix the bug where sparse config is interpreted as relglob instead of glob relglob apparently (in contrast with relpath) matches everywhere in the tree, whereas glob only matches at the root. The python version interprets these patterns as "glob" (see "normalize(include, b'glob', ...)" in match.py)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     1
use std::{collections::HashSet, path::Path};
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     2
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     3
use format_bytes::{write_bytes, DisplayBytes};
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     4
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     5
use crate::{
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     6
    errors::HgError,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     7
    filepatterns::parse_pattern_file_contents,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     8
    matchers::{
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     9
        AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    10
        UnionMatcher,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    11
    },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    12
    operations::cat,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    13
    repo::Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    14
    requirements::SPARSE_REQUIREMENT,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    15
    utils::{hg_path::HgPath, SliceExt},
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    16
    IgnorePattern, PatternError, PatternFileWarning, PatternSyntax, Revision,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    17
    NULL_REVISION,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    18
};
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    19
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    20
/// Command which is triggering the config read
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    21
#[derive(Copy, Clone, Debug)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    22
pub enum SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    23
    Sparse,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    24
    Narrow,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    25
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    26
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    27
impl DisplayBytes for SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    28
    fn display_bytes(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    29
        &self,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    30
        output: &mut dyn std::io::Write,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    31
    ) -> std::io::Result<()> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    32
        match self {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    33
            SparseConfigContext::Sparse => write_bytes!(output, b"sparse"),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    34
            SparseConfigContext::Narrow => write_bytes!(output, b"narrow"),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    35
        }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    36
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    37
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    38
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    39
/// Possible warnings when reading sparse configuration
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    40
#[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    41
pub enum SparseWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    42
    /// Warns about improper paths that start with "/"
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    43
    RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    44
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    45
        line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    46
    },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    47
    /// Warns about a profile missing from the given changelog revision
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    48
    ProfileNotFound { profile: Vec<u8>, rev: Revision },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    49
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    50
    Pattern(PatternFileWarning),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    51
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    52
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    53
/// Parsed sparse config
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    54
#[derive(Debug, Default)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    55
pub struct SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    56
    // Line-separated
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    57
    pub(crate) includes: Vec<u8>,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    58
    // Line-separated
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    59
    pub(crate) excludes: Vec<u8>,
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    60
    pub(crate) profiles: HashSet<Vec<u8>>,
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    61
    pub(crate) warnings: Vec<SparseWarning>,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    62
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    63
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    64
/// All possible errors when reading sparse/narrow config
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    65
#[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    66
pub enum SparseConfigError {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    67
    IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    68
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    69
    },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    70
    EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    71
        context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    72
        line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    73
    },
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    74
    /// Narrow config does not support '%include' directives
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    75
    IncludesInNarrow,
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    76
    /// An invalid pattern prefix was given to the narrow spec. Includes the
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    77
    /// entire pattern for context.
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    78
    InvalidNarrowPrefix(Vec<u8>),
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    79
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    80
    HgError(HgError),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    81
    #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    82
    PatternError(PatternError),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    83
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    84
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    85
/// Parse sparse config file content.
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
    86
pub(crate) fn parse_config(
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    87
    raw: &[u8],
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    88
    context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    89
) -> Result<SparseConfig, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    90
    let mut includes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    91
    let mut excludes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    92
    let mut profiles = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    93
    let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    94
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    95
    #[derive(PartialEq, Eq)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    96
    enum Current {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    97
        Includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    98
        Excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    99
        None,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49489
diff changeset
   100
    }
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   101
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   102
    let mut current = Current::None;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   103
    let mut in_section = false;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   104
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   105
    for line in raw.split(|c| *c == b'\n') {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   106
        let line = line.trim();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   107
        if line.is_empty() || line[0] == b'#' {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   108
            // empty or comment line, skip
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   109
            continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   110
        }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   111
        if line.starts_with(b"%include ") {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   112
            let profile = line[b"%include ".len()..].trim();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   113
            if !profile.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   114
                profiles.insert(profile.into());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   115
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   116
        } else if line == b"[include]" {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   117
            if in_section && current == Current::Includes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   118
                return Err(SparseConfigError::IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   119
                    context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   120
                });
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   121
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   122
            in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   123
            current = Current::Includes;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   124
            continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   125
        } else if line == b"[exclude]" {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   126
            in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   127
            current = Current::Excludes;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   128
        } else {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   129
            if current == Current::None {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   130
                return Err(SparseConfigError::EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   131
                    context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   132
                    line: line.into(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   133
                });
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   134
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   135
            if line.trim().starts_with(b"/") {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   136
                warnings.push(SparseWarning::RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   137
                    context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   138
                    line: line.into(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   139
                });
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   140
                continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   141
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   142
            match current {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   143
                Current::Includes => {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   144
                    includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   145
                    includes.extend(line.iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   146
                }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   147
                Current::Excludes => {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   148
                    excludes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   149
                    excludes.extend(line.iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   150
                }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   151
                Current::None => unreachable!(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   152
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   153
        }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   154
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   155
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   156
    Ok(SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   157
        includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   158
        excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   159
        profiles,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   160
        warnings,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   161
    })
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   162
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   163
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   164
fn read_temporary_includes(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   165
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   166
) -> Result<Vec<Vec<u8>>, SparseConfigError> {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   167
    let raw = repo.hg_vfs().try_read("tempsparse")?.unwrap_or_default();
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   168
    if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   169
        return Ok(vec![]);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   170
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   171
    Ok(raw.split(|c| *c == b'\n').map(ToOwned::to_owned).collect())
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   172
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   173
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   174
/// Obtain sparse checkout patterns for the given revision
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   175
fn patterns_for_rev(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   176
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   177
    rev: Revision,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   178
) -> Result<Option<SparseConfig>, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   179
    if !repo.has_sparse() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   180
        return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   181
    }
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   182
    let raw = repo.hg_vfs().try_read("sparse")?.unwrap_or_default();
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   183
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   184
    if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   185
        return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   186
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   187
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   188
    let mut config = parse_config(&raw, SparseConfigContext::Sparse)?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   189
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   190
    if !config.profiles.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   191
        let mut profiles: Vec<Vec<u8>> = config.profiles.into_iter().collect();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   192
        let mut visited = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   193
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   194
        while let Some(profile) = profiles.pop() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   195
            if visited.contains(&profile) {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   196
                continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   197
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   198
            visited.insert(profile.to_owned());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   199
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   200
            let output =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   201
                cat(repo, &rev.to_string(), vec![HgPath::new(&profile)])
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   202
                    .map_err(|_| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   203
                        HgError::corrupted(
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   204
                            "dirstate points to non-existent parent node"
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   205
                                .to_string(),
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   206
                        )
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   207
                    })?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   208
            if output.results.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   209
                config.warnings.push(SparseWarning::ProfileNotFound {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   210
                    profile: profile.to_owned(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   211
                    rev,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   212
                })
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   213
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   214
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   215
            let subconfig = parse_config(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   216
                &output.results[0].1,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   217
                SparseConfigContext::Sparse,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   218
            )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   219
            if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   220
                config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   221
                config.includes.extend(&subconfig.includes);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   222
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   223
            if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   224
                config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   225
                config.excludes.extend(&subconfig.excludes);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   226
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   227
            config.warnings.extend(subconfig.warnings.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   228
            profiles.extend(subconfig.profiles.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   229
        }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   230
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   231
        config.profiles = visited;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   232
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   233
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   234
    if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   235
        config.includes.extend(b"\n.hg*");
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   236
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   237
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   238
    Ok(Some(config))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   239
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   240
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   241
/// Obtain a matcher for sparse working directories.
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   242
pub fn matcher(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   243
    repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   244
) -> Result<(Box<dyn Matcher + Sync>, Vec<SparseWarning>), SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   245
    let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   246
    if !repo.requirements().contains(SPARSE_REQUIREMENT) {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   247
        return Ok((Box::new(AlwaysMatcher), warnings));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   248
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   249
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   250
    let parents = repo.dirstate_parents()?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   251
    let mut revs = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   252
    let p1_rev =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   253
        repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   254
            .rev_from_node(parents.p1.into())
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   255
            .map_err(|_| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   256
                HgError::corrupted(
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   257
                    "dirstate points to non-existent parent node".to_string(),
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   258
                )
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   259
            })?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   260
    if p1_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   261
        revs.push(p1_rev)
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   262
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   263
    let p2_rev =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   264
        repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   265
            .rev_from_node(parents.p2.into())
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   266
            .map_err(|_| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   267
                HgError::corrupted(
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   268
                    "dirstate points to non-existent parent node".to_string(),
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   269
                )
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   270
            })?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   271
    if p2_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   272
        revs.push(p2_rev)
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   273
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   274
    let mut matchers = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   275
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   276
    for rev in revs.iter() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   277
        let config = patterns_for_rev(repo, *rev);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   278
        if let Ok(Some(config)) = config {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   279
            warnings.extend(config.warnings);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   280
            let mut m: Box<dyn Matcher + Sync> = Box::new(AlwaysMatcher);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   281
            if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   282
                let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   283
                    &config.includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   284
                    Path::new(""),
50818
28c0fcff24e5 rhg: fix the bug where sparse config is interpreted as relglob instead of glob
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49930
diff changeset
   285
                    Some(b"glob:".as_ref()),
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   286
                    false,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   287
                )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   288
                warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   289
                m = Box::new(IncludeMatcher::new(patterns)?);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   290
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   291
            if !config.excludes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   292
                let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   293
                    &config.excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   294
                    Path::new(""),
50818
28c0fcff24e5 rhg: fix the bug where sparse config is interpreted as relglob instead of glob
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49930
diff changeset
   295
                    Some(b"glob:".as_ref()),
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   296
                    false,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   297
                )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   298
                warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   299
                m = Box::new(DifferenceMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   300
                    m,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   301
                    Box::new(IncludeMatcher::new(patterns)?),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   302
                ));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   303
            }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   304
            matchers.push(m);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   305
        }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   306
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   307
    let result: Box<dyn Matcher + Sync> = match matchers.len() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   308
        0 => Box::new(AlwaysMatcher),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   309
        1 => matchers.pop().expect("1 is equal to 0"),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   310
        _ => Box::new(UnionMatcher::new(matchers)),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   311
    };
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   312
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   313
    let matcher =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   314
        force_include_matcher(result, &read_temporary_includes(repo)?)?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   315
    Ok((matcher, warnings))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   316
}
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   317
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   318
/// Returns a matcher that returns true for any of the forced includes before
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   319
/// testing against the actual matcher
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   320
fn force_include_matcher(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   321
    result: Box<dyn Matcher + Sync>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   322
    temp_includes: &[Vec<u8>],
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   323
) -> Result<Box<dyn Matcher + Sync>, PatternError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   324
    if temp_includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   325
        return Ok(result);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   326
    }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   327
    let forced_include_matcher = IncludeMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   328
        temp_includes
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
   329
            .iter()
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   330
            .map(|include| {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   331
                IgnorePattern::new(PatternSyntax::Path, include, Path::new(""))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   332
            })
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   333
            .collect(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   334
    )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   335
    Ok(Box::new(UnionMatcher::new(vec![
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   336
        Box::new(forced_include_matcher),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   337
        result,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   338
    ])))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   339
}