From f5c57941eff05ffd59c640148bd9da0951da1840 Mon Sep 17 00:00:00 2001 From: Colin Woodbury Date: Fri, 7 Jun 2024 06:26:29 +0900 Subject: [PATCH] feat(core): account for `provides` in depgraph visualisation --- rust/aura-core/src/deps.rs | 94 +++++++++++++++++++------------------- rust/aura-core/src/lib.rs | 26 +++++++++++ 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/rust/aura-core/src/deps.rs b/rust/aura-core/src/deps.rs index 0b369eb2b..87c19016c 100644 --- a/rust/aura-core/src/deps.rs +++ b/rust/aura-core/src/deps.rs @@ -108,35 +108,38 @@ impl<'a> PkgGraph<'a> { where D: DbLike, { - indices.get(parent).cloned().or_else(|| { - db.get_pkg(parent).ok().map(|p| { - let ix = graph.add_node((parent, p.groups().first())); - indices.insert(parent, ix); - let next = limit.map(|l| l - 1); - - if next.is_none() || next > Some(0) { - // Dependencies required at runtime. - for d in p.depends().iter() { + let true_pkg = db.get_pkg(parent).ok().or_else(|| db.provides(parent))?; + let name = true_pkg.name(); + debug!("Found {} providing {}", name, parent); + + indices.get(name).cloned().or_else(|| { + let ix = graph.add_node((name, true_pkg.groups().first())); + debug!("Added {} at {}", name, ix.index()); + indices.insert(name, ix); + let next = limit.map(|l| l - 1); + + if next.is_none() || next > Some(0) { + // Dependencies required at runtime. + for d in true_pkg.depends().iter() { + if let Some(dix) = + PkgGraph::add_dep(db, graph, indices, next, optional, d.name()) + { + graph.update_edge(ix, dix, DepType::Hard); + } + } + + if optional { + for d in true_pkg.optdepends().iter() { if let Some(dix) = PkgGraph::add_dep(db, graph, indices, next, optional, d.name()) { - graph.add_edge(ix, dix, DepType::Hard); - } - } - - if optional { - for d in p.optdepends().iter() { - if let Some(dix) = - PkgGraph::add_dep(db, graph, indices, next, optional, d.name()) - { - graph.add_edge(ix, dix, DepType::Opt); - } + graph.update_edge(ix, dix, DepType::Opt); } } } + } - ix - }) + Some(ix) }) } @@ -153,37 +156,36 @@ impl<'a> PkgGraph<'a> { where D: DbLike, { - indices.get(child).cloned().or_else(|| { - db.get_pkg(child).ok().map(|p| { - // We pull the name back out of the summoned `Package` instead - // of using the given `child: &str` to avoid lifetime issues. - let name = p.name(); - let ix = graph.add_node((name, p.groups().first())); - indices.insert(name, ix); - let next = limit.map(|l| l - 1); - - if next.is_none() || next > Some(0) { - for parent in p.required_by() { + let true_pkg = db.get_pkg(child).ok().or_else(|| db.provides(child))?; + let name = true_pkg.name(); + debug!("Found {} providing {}", name, child); + + indices.get(name).cloned().or_else(|| { + let ix = graph.add_node((name, true_pkg.groups().first())); + indices.insert(name, ix); + let next = limit.map(|l| l - 1); + + if next.is_none() || next > Some(0) { + for parent in true_pkg.required_by() { + if let Some(pix) = + PkgGraph::add_parent(db, graph, indices, next, optional, &parent) + { + graph.update_edge(pix, ix, DepType::Hard); + } + } + + if optional { + for parent in true_pkg.optional_for() { if let Some(pix) = PkgGraph::add_parent(db, graph, indices, next, optional, &parent) { - graph.add_edge(pix, ix, DepType::Hard); - } - } - - if optional { - for parent in p.optional_for() { - if let Some(pix) = - PkgGraph::add_parent(db, graph, indices, next, optional, &parent) - { - graph.add_edge(pix, ix, DepType::Opt); - } + graph.update_edge(pix, ix, DepType::Opt); } } } + } - ix - }) + Some(ix) }) } } diff --git a/rust/aura-core/src/lib.rs b/rust/aura-core/src/lib.rs index 8a4066f57..8a207cb11 100644 --- a/rust/aura-core/src/lib.rs +++ b/rust/aura-core/src/lib.rs @@ -26,6 +26,11 @@ pub trait DbLike { fn get_pkg<'a, S>(&'a self, name: S) -> Result<&'a alpm::Package, alpm::Error> where S: Into>; + + /// Find a package that provides some name. + fn provides<'a, S>(&'a self, name: S) -> Option<&'a alpm::Package> + where + S: Into>; } impl DbLike for Db { @@ -35,6 +40,13 @@ impl DbLike for Db { { self.pkg(name) } + + fn provides<'a, S>(&'a self, _: S) -> Option<&'a alpm::Package> + where + S: Into>, + { + None + } } impl DbLike for AlpmList<'_, &Db> { @@ -44,6 +56,13 @@ impl DbLike for AlpmList<'_, &Db> { { self.pkg(name) } + + fn provides<'a, S>(&'a self, name: S) -> Option<&'a alpm::Package> + where + S: Into>, + { + self.find_satisfier(name) + } } /// A combination of both database sources. @@ -74,6 +93,13 @@ impl<'b, 'c> DbLike for Dbs<'b, 'c> { .get_pkg(v.clone()) .or_else(|_| self.syncs.get_pkg(v)) } + + fn provides<'a, S>(&'a self, name: S) -> Option<&'a alpm::Package> + where + S: Into>, + { + self.syncs.find_satisfier(name) + } } /// The simplest form a package.