summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-11-18 01:44:45 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-11-18 01:44:45 +0000
commit78398b7ebe114f56eacbe4445a11ff2dfd10dfe7 (patch)
treeb7f5da9748e8985f646248b20ab86d9d3cf0e5dd /src
parentdb02762ee1b012a137bb48a51e90ddf8826fe449 (diff)
downloadgentoo-utils-78398b7ebe114f56eacbe4445a11ff2dfd10dfe7.tar.gz
support ::repo syntax
Diffstat (limited to 'src')
-rw-r--r--src/atom/mod.rs4
-rw-r--r--src/atom/parsers.rs65
2 files changed, 53 insertions, 16 deletions
diff --git a/src/atom/mod.rs b/src/atom/mod.rs
index 3be42bb..54de7ee 100644
--- a/src/atom/mod.rs
+++ b/src/atom/mod.rs
@@ -103,6 +103,9 @@ pub enum UseDepCondition {
Question,
}
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Repo(String);
+
#[derive(Clone, Debug, PartialEq, Eq, Get)]
pub struct UseDep {
negate: Option<UseDepNegate>,
@@ -132,6 +135,7 @@ pub struct Atom {
name: Name,
version: Option<(VersionOperator, Version, Option<Wildcard>)>,
slot: Option<Slot>,
+ repo: Option<Repo>,
#[get(kind = "deref")]
usedeps: Vec<UseDep>,
}
diff --git a/src/atom/parsers.rs b/src/atom/parsers.rs
index 7bcf5c6..59bd23f 100644
--- a/src/atom/parsers.rs
+++ b/src/atom/parsers.rs
@@ -5,7 +5,7 @@ use mon::{Parser, ParserIter, alphanumeric, r#if, numeric1, one_of, tag};
use crate::{
Parseable,
atom::{
- Atom, Blocker, Category, Cp, Cpv, Name, Slot, SlotName, SlotOperator, UseDep,
+ Atom, Blocker, Category, Cp, Cpv, Name, Repo, Slot, SlotName, SlotOperator, UseDep,
UseDepCondition, UseDepNegate, UseDepSign, Version, VersionNumber, VersionNumbers,
VersionOperator, VersionSuffix, VersionSuffixKind, VersionSuffixes, Wildcard,
},
@@ -201,6 +201,21 @@ impl<'a> Parseable<'a, &'a str> for UseDepSign {
}
}
+//A slot name may contain any of the characters [A-Za-z0-9+_.-]. It must not begin with a hyphen, a dot or a plus sign.
+impl<'a> Parseable<'a, &'a str> for Repo {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ let start = alphanumeric().or(one_of("_".chars()));
+ let rest = alphanumeric().or(one_of("+_.-".chars())).repeated().many();
+
+ start
+ .and(rest)
+ .recognize()
+ .map(|output: &str| Repo(output.to_string()))
+ }
+}
+
impl<'a> Parseable<'a, &'a str> for UseDep {
type Parser = impl Parser<&'a str, Output = Self>;
@@ -288,15 +303,19 @@ impl<'a> Parseable<'a, &'a str> for Atom {
.and(Category::parser())
.and(Name::parser().preceded_by(tag("/")))
.and(Slot::parser().preceded_by(tag(":")).opt())
+ .and(Repo::parser().preceded_by(tag("::")).opt())
.and(usedeps())
- .map(|((((blocker, category), name), slot), usedeps)| Atom {
- blocker,
- category,
- name,
- version: None,
- slot,
- usedeps: usedeps.unwrap_or(Vec::new()),
- });
+ .map(
+ |(((((blocker, category), name), slot), repo), usedeps)| Atom {
+ blocker,
+ category,
+ name,
+ version: None,
+ slot,
+ repo,
+ usedeps: usedeps.unwrap_or(Vec::new()),
+ },
+ );
let with_version = Blocker::parser()
.opt()
@@ -306,16 +325,22 @@ impl<'a> Parseable<'a, &'a str> for Atom {
.and(Version::parser().preceded_by(tag("-")))
.and(tag("*").map(|_| Wildcard).opt())
.and(Slot::parser().preceded_by(tag(":")).opt())
+ .and(Repo::parser().preceded_by(tag("::")).opt())
.and(usedeps())
- .verify_output(|(((((((_, version_operator), _), _), _), star), _), _)| {
- matches!(
- (version_operator, star),
- (VersionOperator::Eq, Some(_) | None) | (_, None)
- )
- })
+ .verify_output(
+ |((((((((_, version_operator), _), _), _), star), _), _), _)| {
+ matches!(
+ (version_operator, star),
+ (VersionOperator::Eq, Some(_) | None) | (_, None)
+ )
+ },
+ )
.map(
|(
- ((((((blocker, version_operator), category), name), version), star), slot),
+ (
+ ((((((blocker, version_operator), category), name), version), star), slot),
+ repo,
+ ),
usedeps,
)| {
Atom {
@@ -324,6 +349,7 @@ impl<'a> Parseable<'a, &'a str> for Atom {
name,
version: Some((version_operator, version, star)),
slot,
+ repo,
usedeps: usedeps.unwrap_or(Vec::new()),
}
},
@@ -503,6 +529,13 @@ mod test {
}
#[test]
+ fn test_with_repo() {
+ let it = InputIter::new("=foo/bar-1.0.0:slot/sub=::gentoo[a,b,c]");
+
+ Atom::parser().check_finished(it).unwrap();
+ }
+
+ #[test]
fn test_against_fuzzer_false_positives() {
let atoms = [
"media-libs/libsdl2[haptitick(+),sound(+)vd,eio(+)]",