aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/pkg-build.cxx108
1 files changed, 79 insertions, 29 deletions
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 395fb14..721fe77 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -342,9 +342,9 @@ namespace bpkg
}
};
- using build_packages = list<reference_wrapper<build_package>>;
+ using build_package_list = list<reference_wrapper<build_package>>;
- struct build_package_map: build_packages
+ struct build_packages: build_package_list
{
// Collect the package. Return its pointer if this package version was, in
// fact, added to the map and NULL if it was already there or the existing
@@ -1082,6 +1082,13 @@ namespace bpkg
}
}
+ void
+ clear ()
+ {
+ build_package_list::clear ();
+ map_.clear ();
+ }
+
private:
struct data_type
{
@@ -1092,6 +1099,12 @@ namespace bpkg
map<string, data_type> map_;
};
+ struct drop_package
+ {
+ shared_ptr<selected_package> selected;
+ };
+ using drop_package_list = vector<drop_package>;
+
using pkg_options = pkg_build_pkg_options;
struct pkg_arg
@@ -1348,7 +1361,8 @@ namespace bpkg
execute_plan (const pkg_build_options&,
const dir_path&,
database&,
- build_packages&,
+ build_package_list&,
+ drop_package_list&
bool,
set<shared_ptr<selected_package>>& drop_pkgs);
@@ -1387,10 +1401,10 @@ namespace bpkg
database db (open (c, trace)); // Also populates the system repository.
// Note that the session spans all our transactions. The idea here is that
- // selected_package objects in the build_package_map below will be cached
- // in this session. When subsequent transactions modify any of these
- // objects, they will modify the cached instance, which means our list
- // will always "see" their updated state.
+ // selected_package objects in build_packages below will be cached in this
+ // session. When subsequent transactions modify any of these objects, they
+ // will modify the cached instance, which means our list will always "see"
+ // their updated state.
//
// Also note that rep_fetch() must be called in session.
//
@@ -2072,17 +2086,20 @@ namespace bpkg
t.commit ();
}
- // Assemble the list of packages we will need to build.
+ // Assemble the list of packages we will need to build and drop.
//
- build_package_map pkgs;
+ build_packages build_pkgs;
+ drop_package_list drop_pkgs;
+
{
// Iteratively refine the plan with dependency up/down-grades/drops.
//
- // @@ TODO: maybe not build_package, maybe just name & version so that
- // we don't end up with selected_package object that has been rolled
- // back?
- //
- vector<build_package> dep_pkgs;
+ struct dep_pkg
+ {
+ string name;
+ build::version version; // Drop if empty, up/down-grade otherwise.
+ };
+ vector<dep_pkg> dep_pkgs;
for (bool refine (true), scratch (true); refine; )
{
@@ -2090,6 +2107,9 @@ namespace bpkg
if (scratch)
{
+ build_pkgs.clear ();
+ drop_pkgs.clear ();
+
// Pre-collect user selection to make sure dependency-forced
// up/down-grades are handled properly (i.e., the order in which we
// specify packages on the command line does not matter).
@@ -2117,8 +2137,13 @@ namespace bpkg
// appear in the plan last (could also do it as a post-
// collection step if less hairy).
//
- for (const build_package& p: dep_pkgs)
- pkgs.collect (o, c, db, p, true /* recursively */);
+ for (const dep_pkg& p: dep_pkgs)
+ {
+ if (p.version.empty ())
+ drop_pkgs.push_back (...);
+ else
+ build_pkgs.collect (o, c, db, p, true /* recursively */);
+ }
// Now that we have collected all the package versions that we need to
// build, arrange them in the "dependency order", that is, with every
@@ -2170,16 +2195,23 @@ namespace bpkg
old_sp = *sp;
// We also need to perform the execution on the copy of the
- // build_package objects to preserve their original ones. Note that
+ // build/drop_package objects to preserve the original ones. Note that
// the selected package objects will still be changed so we will
// reload them afterwards (see below).
//
{
- vector<build_package> tmp_pkgs (pkgs.begin (), pkgs.end ());
- build_packages ref_pkgs (tmp_pkgs.begin (), tmp_pkgs.end ());
+ vector<build_package> bs (build_pkgs.begin (), build_pkgs.end ());
+ vector<drop_package> ds (drop_pkgs.begin (), drop_pkgs.end ());
set<shared_ptr<selected_package>> dummy;
- execute_plan (o, c, db, ref_pkgs, true /* simulate */, dummy);
+
+ execute_plan (o,
+ c,
+ db,
+ build_package_list (b_pkgs.begin (), b_pkgs.end ()),
+ ds,
+ true /* simulate */,
+ dummy);
}
// Verify that none of the previously-made upgrade/downgrade/drop
@@ -2212,6 +2244,9 @@ namespace bpkg
{
version v (evaluate_dependency (p));
+ // Note that the order of packages to drop is correct by
+ // construction.
+ //
if (v != p->version)
{
dep_pkgs.push_back (p->name, v);
@@ -2230,17 +2265,24 @@ namespace bpkg
// First reload all the selected_package object that could have been
// modified (conceptually, we should only modify what's on the
- // plan).
+ // plan). And in case of drop the object is removed from the session
+ // so we need to bring it back.
//
- // Note: we use the original pkgs list since the executed one may
+ // Note: we use the original pkgs lists since the executed one may
// contain newly created (but now gone) selected_package objects.
//
- for (build_package& p: pkgs)
+ for (build_package& p: build_pkgs)
{
if (p.selected != nullptr)
db.reload (*p.selected);
}
+ for (drop_package& p: drop_pkgs)
+ {
+ ses.cache_insert (db, p.selected->name, p.selected);
+ db.reload (*p.selected);
+ }
+
// Now drop all the newly created selected_package objects. The
// tricky part is to distinguish newly created ones from newly
// loaded (and potentially cached).
@@ -2372,6 +2414,8 @@ namespace bpkg
//
plan += (plan.empty () ? " " : "\n ") + act;
}
+
+ //@@ TODO: print drop_pkgs plan.
}
if (o.print_only ())
@@ -2435,15 +2479,20 @@ namespace bpkg
// above). This case we handle in house.
//
- set<shared_ptr<selected_package>> drop_pkgs;
- execute_plan (o, c, db, pkgs, false /* simulate */, drop_pkgs);
+ set<shared_ptr<selected_package>> drop_pkgs_dummy;
+ execute_plan (o,
+ c,
+ db,
+ build_pkgs,
+ drop_pkgs,
+ false /* simulate */, drop_pkgs_dummy);
// Now that we have the final dependency state, see if we need to drop
// packages that are no longer necessary.
//
if (!drop_pkgs.empty ())
- drop_pkgs = pkg_drop (
- c, o, db, drop_pkgs, !(o.yes () || o.drop_prerequisite ()));
+ drop_pkgs_dummy = pkg_drop (
+ c, o, db, drop_pkgs_dummy, !(o.yes () || o.drop_prerequisite ()));
if (o.configure_only ())
return 0;
@@ -2480,7 +2529,7 @@ namespace bpkg
// Note that it is entirely possible this package got dropped so
// we need to check for that.
//
- if (drop_pkgs.find (sp) == drop_pkgs.end ())
+ if (drop_pkgs_dummy.find (sp) == drop_pkgs_dummy.end ())
upkgs.push_back (pkg_command_vars {sp, strings ()});
}
}
@@ -2501,7 +2550,8 @@ namespace bpkg
execute_plan (const pkg_build_options& o,
const dir_path& c,
database& db,
- build_packages& pkgs,
+ build_package_list& build_pkgs,
+ drop_package_list& drop_pkgs,
bool simulate,
set<shared_ptr<selected_package>>& drop_pkgs)
{