config: don't leak nested-group names into the flat package set
expand_group inserted the group's own name into `resolved` (the package
accumulator), so a nested-group reference (kde-desktop -> dbus-services)
added a bogus "dbus-services" package. `repo cook --filesystem` then
failed with 'Package PackageName("dbus-services") not found'.
Track expanded GROUP names in a separate `expanded` set used only for
dedup/cycle short-circuit; only real leaf package names go into
`resolved`. Groups contribute their members, never themselves.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+17
-8
@@ -108,7 +108,8 @@ impl Config {
|
||||
// detect cycles via a stack of currently-visiting names.
|
||||
let mut resolved_here: BTreeSet<String> = BTreeSet::new();
|
||||
let mut visiting: Vec<String> = Vec::new();
|
||||
self.expand_group(name, &mut visiting, &mut resolved_here)?;
|
||||
let mut expanded_groups: BTreeSet<String> = BTreeSet::new();
|
||||
self.expand_group(name, &mut visiting, &mut resolved_here, &mut expanded_groups)?;
|
||||
for pkg in &resolved_here {
|
||||
// Mark a group-expanded package for install using the SAME
|
||||
// representation an explicit `pkg = {}` entry deserializes to
|
||||
@@ -140,9 +141,16 @@ impl Config {
|
||||
&self,
|
||||
name: &str,
|
||||
visiting: &mut Vec<String>,
|
||||
// ACTUAL package names accumulated so far (this is what gets installed).
|
||||
resolved: &mut BTreeSet<String>,
|
||||
// Group names already fully expanded — tracked SEPARATELY from
|
||||
// `resolved` so a group's own name never leaks into the package set
|
||||
// (a nested-group reference like `kde-desktop` -> `dbus-services` must
|
||||
// expand to expat/dbus, NOT add a bogus "dbus-services" package that
|
||||
// `repo` then fails to cook with "Package not found").
|
||||
expanded: &mut BTreeSet<String>,
|
||||
) -> Result<()> {
|
||||
if resolved.contains(name) {
|
||||
if expanded.contains(name) {
|
||||
return Ok(());
|
||||
}
|
||||
if visiting.iter().any(|n| n == name) {
|
||||
@@ -173,17 +181,18 @@ impl Config {
|
||||
visiting.push(name.to_string());
|
||||
for member in &group.packages {
|
||||
if self.package_groups.contains_key(member) {
|
||||
self.expand_group(member, visiting, resolved)?;
|
||||
self.expand_group(member, visiting, resolved, expanded)?;
|
||||
} else {
|
||||
// Treat as a package name. It's an error only if neither
|
||||
// group nor package exists; we'll surface that at the end.
|
||||
// For now, record it so the cycle detector sees it; the
|
||||
// final install will surface the missing-package error.
|
||||
// A leaf member: an actual package name. (If it names neither a
|
||||
// group nor a real package, the missing-package error surfaces
|
||||
// later at repo/install time.)
|
||||
resolved.insert(member.clone());
|
||||
}
|
||||
}
|
||||
visiting.pop();
|
||||
resolved.insert(name.to_string());
|
||||
// Mark this GROUP as expanded (dedup / short-circuit only). Do NOT put
|
||||
// it in `resolved` — it is a group, not a package.
|
||||
expanded.insert(name.to_string());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user