annotate rust/hg-core/src/sparse.rs @ 52280:f4aede0f01af

rust-manifest: use `memchr` crate for all byte-finding needs While writing a very dumb manifest diffing algorithm for a proof-of-concept I saw that `Manifest::find_by_path` was much slower than I was expecting. It turns out that the Rust stdlib uses slow (all is relative) code when searching for byte positions for reasons ranging from portability, SIMD API stability, nobody doing the work, etc. `memch` is much faster for these purposes, so let's use it. I was measuring ~670ms of profile time in `find_by_path`, after this patch it went down to ~230ms.
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 12 Nov 2024 23:20:04 +0100
parents ae1ab6d71f4a
children f33b87b46135 77b95a4abbb2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
1 use std::{collections::HashSet, fmt::Display, path::Path};
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
2
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
3 use format_bytes::{format_bytes, write_bytes, DisplayBytes};
49485
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,
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
7 exit_codes::STATE_ERROR,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
8 filepatterns::parse_pattern_file_contents,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
9 matchers::{
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
10 AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
11 UnionMatcher,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
12 },
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
13 narrow::VALID_PREFIXES,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
14 operations::cat,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
15 repo::Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
16 requirements::SPARSE_REQUIREMENT,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
17 utils::{hg_path::HgPath, SliceExt},
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
18 IgnorePattern, PatternError, PatternFileWarning, PatternSyntax, Revision,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
19 NULL_REVISION,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
20 };
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
21
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
22 /// Command which is triggering the config read
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
23 #[derive(Copy, Clone, Debug)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
24 pub enum SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
25 Sparse,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
26 Narrow,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
27 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
28
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
29 impl DisplayBytes for SparseConfigContext {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
30 fn display_bytes(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
31 &self,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
32 output: &mut dyn std::io::Write,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
33 ) -> std::io::Result<()> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
34 match self {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
35 SparseConfigContext::Sparse => write_bytes!(output, b"sparse"),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
36 SparseConfigContext::Narrow => write_bytes!(output, b"narrow"),
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 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
40
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
41 impl Display for SparseConfigContext {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
43 match self {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
44 SparseConfigContext::Sparse => write!(f, "sparse"),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
45 SparseConfigContext::Narrow => write!(f, "narrow"),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
46 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
47 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
48 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
49
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
50 /// Possible warnings when reading sparse configuration
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
51 #[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
52 pub enum SparseWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
53 /// Warns about improper paths that start with "/"
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
54 RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
55 context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
56 line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
57 },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
58 /// 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
59 ProfileNotFound { profile: Vec<u8>, rev: Revision },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
60 #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
61 Pattern(PatternFileWarning),
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
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
64 /// Parsed sparse config
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
65 #[derive(Debug, Default)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
66 pub struct SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
67 // Line-separated
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
68 pub(crate) includes: Vec<u8>,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
69 // Line-separated
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
70 pub(crate) excludes: Vec<u8>,
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
71 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
72 pub(crate) warnings: Vec<SparseWarning>,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
73 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
74
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
75 /// All possible errors when reading sparse/narrow config
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
76 #[derive(Debug, derive_more::From)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
77 pub enum SparseConfigError {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
78 IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
79 context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
80 },
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
81 EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
82 context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
83 line: Vec<u8>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
84 },
49489
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
85 /// 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
86 IncludesInNarrow,
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
87 /// 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
88 /// entire pattern for context.
7c93e38a0bbd rhg-status: add support for narrow clones
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49485
diff changeset
89 InvalidNarrowPrefix(Vec<u8>),
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
90 #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
91 HgError(HgError),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
92 #[from]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
93 PatternError(PatternError),
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
52039
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
96 impl From<SparseConfigError> for HgError {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
97 fn from(value: SparseConfigError) -> Self {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
98 match value {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
99 SparseConfigError::IncludesAfterExcludes { context } => {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
100 HgError::Abort {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
101 message: format!(
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
102 "{} config cannot have includes after excludes",
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
103 context,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
104 ),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
105 detailed_exit_code: STATE_ERROR,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
106 hint: None,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
107 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
108 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
109 SparseConfigError::EntryOutsideSection { context, line } => {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
110 HgError::Abort {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
111 message: format!(
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
112 "{} config entry outside of section: {}",
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
113 context,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
114 String::from_utf8_lossy(&line)
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
115 ),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
116 detailed_exit_code: STATE_ERROR,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
117 hint: None,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
118 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
119 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
120 SparseConfigError::IncludesInNarrow => HgError::Abort {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
121 message: "including other spec files using '%include' is not \
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
122 supported in narrowspec"
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
123 .to_string(),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
124 detailed_exit_code: STATE_ERROR,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
125 hint: None,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
126 },
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
127 SparseConfigError::InvalidNarrowPrefix(vec) => HgError::Abort {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
128 message: String::from_utf8_lossy(&format_bytes!(
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
129 b"invalid prefix on narrow pattern: {}",
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
130 vec
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
131 ))
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
132 .to_string(),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
133 detailed_exit_code: STATE_ERROR,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
134 hint: Some(format!(
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
135 "narrow patterns must begin with one of the following: {}",
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
136 VALID_PREFIXES.join(", ")
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
137 )),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
138 },
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
139 SparseConfigError::HgError(hg_error) => hg_error,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
140 SparseConfigError::PatternError(pattern_error) => HgError::Abort {
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
141 message: pattern_error.to_string(),
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
142 detailed_exit_code: STATE_ERROR,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
143 hint: None,
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
144 },
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
145 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
146 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
147 }
ae1ab6d71f4a rust: implement `From<SparseConfigWarning>` for `HgError`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50854
diff changeset
148
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
149 /// 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
150 pub(crate) fn parse_config(
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
151 raw: &[u8],
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
152 context: SparseConfigContext,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
153 ) -> Result<SparseConfig, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
154 let mut includes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
155 let mut excludes = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
156 let mut profiles = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
157 let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
158
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
159 #[derive(PartialEq, Eq)]
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
160 enum Current {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
161 Includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
162 Excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
163 None,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49489
diff changeset
164 }
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
165
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
166 let mut current = Current::None;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
167 let mut in_section = false;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
168
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
169 for line in raw.split(|c| *c == b'\n') {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
170 let line = line.trim();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
171 if line.is_empty() || line[0] == b'#' {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
172 // empty or comment line, skip
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
173 continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
174 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
175 if line.starts_with(b"%include ") {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
176 let profile = line[b"%include ".len()..].trim();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
177 if !profile.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
178 profiles.insert(profile.into());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
179 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
180 } else if line == b"[include]" {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
181 if in_section && current == Current::Includes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
182 return Err(SparseConfigError::IncludesAfterExcludes {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
183 context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
184 });
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
185 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
186 in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
187 current = Current::Includes;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
188 continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
189 } else if line == b"[exclude]" {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
190 in_section = true;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
191 current = Current::Excludes;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
192 } else {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
193 if current == Current::None {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
194 return Err(SparseConfigError::EntryOutsideSection {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
195 context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
196 line: line.into(),
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 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
199 if line.trim().starts_with(b"/") {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
200 warnings.push(SparseWarning::RootWarning {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
201 context,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
202 line: line.into(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
203 });
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
204 continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
205 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
206 match current {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
207 Current::Includes => {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
208 includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
209 includes.extend(line.iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
210 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
211 Current::Excludes => {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
212 excludes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
213 excludes.extend(line.iter());
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 Current::None => unreachable!(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
216 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
217 }
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
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
220 Ok(SparseConfig {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
221 includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
222 excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
223 profiles,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
224 warnings,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
225 })
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
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
228 fn read_temporary_includes(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
229 repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
230 ) -> 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
231 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
232 if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
233 return Ok(vec![]);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
234 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
235 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
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 /// Obtain sparse checkout patterns for the given revision
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
239 fn patterns_for_rev(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
240 repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
241 rev: Revision,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
242 ) -> Result<Option<SparseConfig>, SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
243 if !repo.has_sparse() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
244 return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
245 }
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
246 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
247
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
248 if raw.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
249 return Ok(None);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
250 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
251
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
252 let mut config = parse_config(&raw, SparseConfigContext::Sparse)?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
253
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
254 if !config.profiles.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
255 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
256 let mut visited = HashSet::new();
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
257
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
258 while let Some(profile) = profiles.pop() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
259 if visited.contains(&profile) {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
260 continue;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
261 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
262 visited.insert(profile.to_owned());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
263
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
264 let output =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
265 cat(repo, &rev.to_string(), vec![HgPath::new(&profile)])
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(
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
268 "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
269 .to_string(),
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
270 )
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
271 })?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
272 if output.results.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
273 config.warnings.push(SparseWarning::ProfileNotFound {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
274 profile: profile.to_owned(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
275 rev,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
276 })
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
277 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
278
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
279 let subconfig = parse_config(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
280 &output.results[0].1,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
281 SparseConfigContext::Sparse,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
282 )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
283 if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
284 config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
285 config.includes.extend(&subconfig.includes);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
286 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
287 if !subconfig.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
288 config.includes.push(b'\n');
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
289 config.excludes.extend(&subconfig.excludes);
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 config.warnings.extend(subconfig.warnings.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
292 profiles.extend(subconfig.profiles.into_iter());
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
293 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
294
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
295 config.profiles = visited;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
296 }
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 if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
299 config.includes.extend(b"\n.hg*");
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
300 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
301
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
302 Ok(Some(config))
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
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
305 /// Obtain a matcher for sparse working directories.
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
306 pub fn matcher(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
307 repo: &Repo,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
308 ) -> Result<(Box<dyn Matcher + Sync>, Vec<SparseWarning>), SparseConfigError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
309 let mut warnings = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
310 if !repo.requirements().contains(SPARSE_REQUIREMENT) {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
311 return Ok((Box::new(AlwaysMatcher), warnings));
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
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
314 let parents = repo.dirstate_parents()?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
315 let mut revs = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
316 let p1_rev =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
317 repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
318 .rev_from_node(parents.p1.into())
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
319 .map_err(|_| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
320 HgError::corrupted(
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
321 "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
322 )
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
323 })?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
324 if p1_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
325 revs.push(p1_rev)
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 p2_rev =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
328 repo.changelog()?
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
329 .rev_from_node(parents.p2.into())
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
330 .map_err(|_| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
331 HgError::corrupted(
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
332 "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
333 )
49485
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 if p2_rev != NULL_REVISION {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
336 revs.push(p2_rev)
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
337 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
338 let mut matchers = vec![];
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
339
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
340 for rev in revs.iter() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
341 let config = patterns_for_rev(repo, *rev);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
342 if let Ok(Some(config)) = config {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
343 warnings.extend(config.warnings);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
344 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
345 if !config.includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
346 let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
347 &config.includes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
348 Path::new(""),
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50818
diff changeset
349 Some(PatternSyntax::Glob),
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50818
diff changeset
350 false,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
351 false,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
352 )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
353 warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
354 m = Box::new(IncludeMatcher::new(patterns)?);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
355 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
356 if !config.excludes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
357 let (patterns, subwarnings) = parse_pattern_file_contents(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
358 &config.excludes,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
359 Path::new(""),
50854
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50818
diff changeset
360 Some(PatternSyntax::Glob),
796b5d6693a4 rust: simplify pattern file parsing
Spencer Baugh <sbaugh@janestreet.com>
parents: 50818
diff changeset
361 false,
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
362 false,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
363 )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
364 warnings.extend(subwarnings.into_iter().map(From::from));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
365 m = Box::new(DifferenceMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
366 m,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
367 Box::new(IncludeMatcher::new(patterns)?),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
368 ));
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
369 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
370 matchers.push(m);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
371 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
372 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
373 let result: Box<dyn Matcher + Sync> = match matchers.len() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
374 0 => Box::new(AlwaysMatcher),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
375 1 => matchers.pop().expect("1 is equal to 0"),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
376 _ => Box::new(UnionMatcher::new(matchers)),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
377 };
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
378
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
379 let matcher =
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
380 force_include_matcher(result, &read_temporary_includes(repo)?)?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
381 Ok((matcher, warnings))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
382 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
383
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
384 /// 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
385 /// testing against the actual matcher
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
386 fn force_include_matcher(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
387 result: Box<dyn Matcher + Sync>,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
388 temp_includes: &[Vec<u8>],
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
389 ) -> Result<Box<dyn Matcher + Sync>, PatternError> {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
390 if temp_includes.is_empty() {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
391 return Ok(result);
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
392 }
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
393 let forced_include_matcher = IncludeMatcher::new(
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
394 temp_includes
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
395 .iter()
49485
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
396 .map(|include| {
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
397 IgnorePattern::new(PatternSyntax::Path, include, Path::new(""))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
398 })
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
399 .collect(),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
400 )?;
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
401 Ok(Box::new(UnionMatcher::new(vec![
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
402 Box::new(forced_include_matcher),
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
403 result,
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
404 ])))
ffd4b1f1c9cb rhg: add sparse support
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
405 }