From 309cccfffc15657dd8654aa6a14e444bb47417ae Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 21 Feb 2022 22:54:05 +0300 Subject: Increment version iteration for external packages on buildfiles change --- bpkg/pkg-unpack.cxx | 138 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 21 deletions(-) (limited to 'bpkg/pkg-unpack.cxx') diff --git a/bpkg/pkg-unpack.cxx b/bpkg/pkg-unpack.cxx index bc3452b..b38a750 100644 --- a/bpkg/pkg-unpack.cxx +++ b/bpkg/pkg-unpack.cxx @@ -58,26 +58,18 @@ namespace bpkg // package object which may replace the existing one. // static shared_ptr - pkg_unpack (const common_options& o, - database& db, + pkg_unpack (database& db, transaction& t, - package_name n, - version v, - const package_info* pi, - dir_path d, - repository_location rl, + package_name&& n, + version&& v, + dir_path&& d, + repository_location&& rl, + shared_ptr&& p, + optional&& mc, + optional&& bc, bool purge, bool simulate) { - tracer trace ("pkg_unpack"); - - tracer_guard tg (db, trace); - - optional mc; - - if (!simulate) - mc = package_checksum (o, d, pi); - // Make the package path absolute and normalized. If the package is inside // the configuration, use the relative path. This way we can move the // configuration around. @@ -87,8 +79,6 @@ namespace bpkg if (d.sub (db.config)) d = d.leaf (db.config); - shared_ptr p (db.find (n)); - if (p != nullptr) { // Clean up the source directory and archive of the package we are @@ -117,6 +107,7 @@ namespace bpkg p->src_root = move (d); p->purge_src = purge; p->manifest_checksum = move (mc); + p->buildfiles_checksum = move (bc); db.update (p); } @@ -135,6 +126,7 @@ namespace bpkg move (d), purge, move (mc), + move (bc), nullopt, // No output directory yet. {}}); // No prerequisites captured yet. @@ -144,7 +136,59 @@ namespace bpkg assert (p->external ()); t.commit (); - return p; + return move (p); + } + + template + static shared_ptr + pkg_unpack (const common_options& o, + database& db, + transaction& t, + package_name n, + version v, + const vector& deps, + const package_info* pi, + dir_path d, + repository_location rl, + bool purge, + bool simulate) + { + tracer trace ("pkg_unpack"); + + tracer_guard tg (db, trace); + + shared_ptr p (db.find (n)); + + optional mc; + optional bc; + + if (!simulate) + { + mc = package_checksum (o, d, pi); + + // Calculate the buildfiles checksum if the package has any buildfile + // clauses in the dependencies. Always calculate it over the buildfiles + // since the package is external. + // + if ((p != nullptr && p->manifest_checksum == mc) + ? p->buildfiles_checksum.has_value () + : has_buildfile_clause (deps)) + bc = package_buildfiles_checksum (nullopt /* bootstrap_build */, + nullopt /* root_build */, + d); + } + + return pkg_unpack (db, + t, + move (n), + move (v), + move (d), + move (rl), + move (p), + move (mc), + move (bc), + purge, + simulate); } shared_ptr @@ -207,6 +251,7 @@ namespace bpkg t, move (m.name), move (m.version), + m.dependencies, &pvi.info, d, repository_location (), @@ -272,6 +317,7 @@ namespace bpkg t, move (n), move (v), + ap->dependencies, nullptr /* package_info */, path_cast (rl.path () / pl->location), rl, @@ -282,6 +328,7 @@ namespace bpkg shared_ptr pkg_unpack (const common_options& co, database& db, + database& rdb, transaction& t, const package_name& name, bool simulate) @@ -309,13 +356,17 @@ namespace bpkg // Also, since we must have verified the archive during fetch, // here we can just assume what the resulting directory will be. // - dir_path d (c / dir_path (p->name.string () + '-' + p->version.string ())); + const package_name& n (p->name); + const version& v (p->version); + + dir_path d (c / dir_path (n.string () + '-' + v.string ())); if (exists (d)) fail << "package directory " << d << " already exists"; auto_rmdir arm; optional mc; + optional bc; if (!simulate) { @@ -347,12 +398,52 @@ namespace bpkg } mc = package_checksum (co, d, nullptr /* package_info */); + + // Calculate the buildfiles checksum if the package has any buildfile + // clauses in the dependencies. + // + // Note that we may not have the available package (e.g., fetched as an + // existing package archive rather than from an archive repository), in + // which case we need to parse the manifest to retrieve the + // dependencies. This is unfortunate, but is probably not a big deal + // performance-wise given that this is not too common and we are running + // an archive unpacking process anyway. + // + shared_ptr ap ( + rdb.find (available_package_id (n, v))); + + if (ap != nullptr) + { + if (has_buildfile_clause (ap->dependencies)) + bc = package_buildfiles_checksum (ap->bootstrap_build, + ap->root_build, + d); + } + else + { + // Note that we don't need to translate the package version here since + // the manifest comes from an archive and so has a proper version + // already. + // + package_manifest m ( + pkg_verify (co, + d, + true /* ignore_unknown */, + false /* load_buildfiles */, + function ())); + + if (has_buildfile_clause (m.dependencies)) + bc = package_buildfiles_checksum (m.bootstrap_build, + m.root_build, + d); + } } p->src_root = d.leaf (); // For now assuming to be in configuration. p->purge_src = true; p->manifest_checksum = move (mc); + p->buildfiles_checksum = move (bc); p->state = package_state::unpacked; @@ -416,7 +507,12 @@ namespace bpkg // "unpack" it from the directory-based repository. // p = v.empty () - ? pkg_unpack (o, db, t, n, false /* simulate */) + ? pkg_unpack (o, + db /* pdb */, + db /* rdb */, + t, + n, + false /* simulate */) : pkg_unpack (o, db /* pdb */, db /* rdb */, -- cgit v1.1