Skip to content

Commit 424ad62

Browse files
committed
feat!: an API for matching attributes.
An implementation for `Search<Attributes>` along with various breaking modifications of the original module and type layout.
1 parent fc28701 commit 424ad62

26 files changed

+1707
-1066
lines changed

Cargo.lock

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-attributes/Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@ doctest = false
1414

1515
[features]
1616
## Data structures implement `serde::Serialize` and `serde::Deserialize`.
17-
serde1 = ["serde", "bstr/serde", "gix-glob/serde1"]
17+
serde1 = ["serde", "bstr/serde", "gix-glob/serde1", "kstring/serde"]
1818

1919
[dependencies]
20-
gix-features = { version = "^0.28.0", path = "../gix-features" }
21-
gix-path = { version = "^0.7.2", path = "../gix-path" }
20+
gix-path = { version = "^0.7.3", path = "../gix-path" }
2221
gix-quote = { version = "^0.4.3", path = "../gix-quote" }
2322
gix-glob = { version = "^0.5.5", path = "../gix-glob" }
2423

2524
bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"]}
25+
smallvec = "1.10.0"
26+
kstring = "2.0.0"
2627
unicode-bom = "2.0.2"
2728
thiserror = "1.0.26"
2829
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}
30+
log = "0.4.17"
2931

3032
document-features = { version = "0.2.1", optional = true }
3133

3234
[dev-dependencies]
3335
gix-testtools = { path = "../tests/tools"}
36+
gix-utils = { path = "../gix-utils" }
3437

3538
[package.metadata.docs.rs]
3639
all-features = true

gix-attributes/src/lib.rs

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1-
//! Parse `.gitattribute` and `.gitignore` files and provide utilities to match against them.
1+
//! Parse `.gitattribute` files and provide utilities to match against them.
22
//!
33
//! ## Feature Flags
44
#![cfg_attr(
55
feature = "document-features",
66
cfg_attr(doc, doc = ::document_features::document_features!())
77
)]
88
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
9-
#![deny(missing_docs, rust_2018_idioms)]
10-
#![forbid(unsafe_code)]
9+
#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
1110

12-
use std::path::PathBuf;
13-
14-
use bstr::{BStr, BString};
1511
pub use gix_glob as glob;
12+
use kstring::{KString, KStringRef};
1613

1714
mod assignment;
1815
///
1916
pub mod name;
20-
mod state;
17+
///
18+
pub mod state;
2119

22-
mod match_group;
23-
pub use match_group::{Attributes, Ignore, Match, Pattern};
20+
///
21+
pub mod search;
2422

2523
///
2624
pub mod parse;
27-
/// Parse attribute assignments line by line from `bytes`.
25+
26+
/// Parse attribute assignments line by line from `bytes`, and fail the operation on error.
27+
///
28+
/// For leniency, ignore errors using `filter_map(Result::ok)` for example.
2829
pub fn parse(bytes: &[u8]) -> parse::Lines<'_> {
2930
parse::Lines::new(bytes)
3031
}
@@ -42,7 +43,7 @@ pub enum StateRef<'a> {
4243
/// The attribute is set to the given value, which followed the `=` sign.
4344
/// Note that values can be empty.
4445
#[cfg_attr(feature = "serde1", serde(borrow))]
45-
Value(&'a BStr),
46+
Value(state::ValueRef<'a>),
4647
/// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign.
4748
Unspecified,
4849
}
@@ -59,19 +60,19 @@ pub enum State {
5960
Unset,
6061
/// The attribute is set to the given value, which followed the `=` sign.
6162
/// Note that values can be empty.
62-
Value(BString), // TODO(performance): Is there a non-utf8 compact_str/KBString crate? See https://github.com/cobalt-org/kstring/issues/37#issuecomment-1446777265 .
63+
Value(state::Value),
6364
/// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign.
6465
Unspecified,
6566
}
6667

6768
/// Represents a validated attribute name
6869
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
6970
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
70-
pub struct Name(pub(crate) String); // TODO(performance): See if `KBString` or `compact_string` could be meaningful here.
71+
pub struct Name(pub(crate) KString);
7172

7273
/// Holds a validated attribute name as a reference
73-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
74-
pub struct NameRef<'a>(&'a str);
74+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
75+
pub struct NameRef<'a>(KStringRef<'a>);
7576

7677
/// Name an attribute and describe it's assigned state.
7778
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
@@ -84,54 +85,42 @@ pub struct Assignment {
8485
}
8586

8687
/// Holds validated attribute data as a reference
87-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
88+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
8889
pub struct AssignmentRef<'a> {
8990
/// The name of the attribute.
9091
pub name: NameRef<'a>,
9192
/// The state of the attribute.
9293
pub state: StateRef<'a>,
9394
}
9495

95-
/// A grouping of lists of patterns while possibly keeping associated to their base path.
96+
/// A grouping of lists of patterns while possibly keeping associated to their base path in order to find matches.
9697
///
9798
/// Pattern lists with base path are queryable relative to that base, otherwise they are relative to the repository root.
9899
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
99-
pub struct MatchGroup<T: Pattern = Attributes> {
100+
pub struct Search {
100101
/// A list of pattern lists, each representing a patterns from a file or specified by hand, in the order they were
101102
/// specified in.
102103
///
103-
/// During matching, this order is reversed.
104-
pub patterns: Vec<PatternList<T>>,
104+
/// When matching, this order is reversed.
105+
patterns: Vec<gix_glob::search::pattern::List<search::Attributes>>,
105106
}
106107

107-
/// A list of patterns which optionally know where they were loaded from and what their base is.
108+
/// A list of known global sources for git attribute files in order of ascending precedence.
108109
///
109-
/// Knowing their base which is relative to a source directory, it will ignore all path to match against
110-
/// that don't also start with said base.
111-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
112-
pub struct PatternList<T: Pattern> {
113-
/// Patterns and their associated data in the order they were loaded in or specified,
114-
/// the line number in its source file or its sequence number (_`(pattern, value, line_number)`_).
110+
/// This means that values from the first variant will be returned first.
111+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
112+
pub enum Source {
113+
/// The attribute file that the installation itself ships with.
114+
GitInstallation,
115+
/// System-wide attributes file. This is typically defined as
116+
/// `$(prefix)/etc/gitattributes` (where prefix is the git-installation directory).
117+
System,
118+
/// This is `<xdg-config-home>/git/attributes` and is git application configuration per user.
115119
///
116-
/// During matching, this order is reversed.
117-
pub patterns: Vec<PatternMapping<T::Value>>,
118-
119-
/// The path from which the patterns were read, or `None` if the patterns
120-
/// don't originate in a file on disk.
121-
pub source: Option<PathBuf>,
122-
123-
/// The parent directory of source, or `None` if the patterns are _global_ to match against the repository root.
124-
/// It's processed to contain slashes only and to end with a trailing slash, and is relative to the repository root.
125-
pub base: Option<BString>,
120+
/// Note that there is no `~/.gitattributes` file.
121+
Git,
122+
/// The configuration of the repository itself, located in `$GIT_DIR/info/attributes`.
123+
Local,
126124
}
127125

128-
/// An association of a pattern with its value, along with a sequence number providing a sort order in relation to its peers.
129-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
130-
pub struct PatternMapping<T> {
131-
/// The pattern itself, like `/target/*`
132-
pub pattern: gix_glob::Pattern,
133-
/// The value associated with the pattern.
134-
pub value: T,
135-
/// Typically the line number in the file the pattern was parsed from.
136-
pub sequence_number: usize,
137-
}
126+
mod source;

0 commit comments

Comments
 (0)