From 74bcab9dfa50647dd6615f261f2c2bc9f5a38951 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 13 Feb 2016 16:30:31 +0200 Subject: Offer in pkg-build to drop prerequisite packages that are no longer necessary This can happen if a package that is being upgraded/downgraded changes its dependencies. --- bpkg/pkg-build.cxx | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'bpkg/pkg-build.cxx') diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 6138317..06281ff 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -1133,6 +1134,22 @@ namespace bpkg // We are also going to combine purge/fetch/unpack into a single step // and use the replace mode so it will become just fetch/unpack. // + // Almost forgot, there is one more thing: when we upgrade or downgrade a + // package, it may change the list of its prerequisites. Which means we + // may end up with packages that are no longer necessary and it would be + // nice to offer to drop those. This, howeve, is a tricky business and is + // the domain of pkg_drop(). For example, a prerequisite may still have + // other dependents (so it looks like we shouldn't be dropping it) but + // they are all from the "drop set" (so we should offer to drop it after + // all); pkg_drop() knows how to deal with all this. + // + // So what we are going to do is this: before disfiguring packages we will + // collect all their old prerequisites. This will be the "potentially to + // drop" list. Then, after configuration, when the new dependencies are + // established, we will pass them to pkg_drop() whose job will be to + // figure out which ones can be dropped, prompt the user, etc. + // + set> drop_pkgs; // disfigure // @@ -1150,6 +1167,20 @@ namespace bpkg // always leave the configuration in a valid state. // transaction t (db.begin ()); + + // Collect prerequisites to be potentially dropped. + // + if (!o.keep_prerequisite ()) + { + for (const auto& pair: sp->prerequisites) + { + shared_ptr pp (pair.first.load ()); + + if (!pp->hold_package) + drop_pkgs.insert (move (pp)); + } + } + pkg_disfigure (c, o, t, sp); // Commits the transaction. assert (sp->state == package_state::unpacked); @@ -1292,6 +1323,12 @@ namespace bpkg } } + // Now that we have the final dependency state, see if we need to drop + // packages that are no longer necessary. + // + if (!drop_pkgs.empty ()) + pkg_drop (c, o, db, drop_pkgs, !o.yes ()); + if (o.configure_only ()) return 0; -- cgit v1.1