From aac298fcef914b99cf28d9cf1f4f58cc6714fb92 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 9 Aug 2021 21:46:16 +0300 Subject: Don't create private configurations in private configurations --- bpkg/database.cxx | 72 +++++++++++++++++++++++++++++++++++++++++++++- bpkg/database.hxx | 36 +++++++++++++++++++++++ bpkg/pkg-build.cxx | 36 +++++++++++------------ tests/pkg-build.testscript | 50 ++++++++++++++++---------------- tests/pkg-drop.testscript | 58 ++++++++++++++++++++++++++++++------- 5 files changed, 196 insertions(+), 56 deletions(-) diff --git a/bpkg/database.cxx b/bpkg/database.cxx index 6724582..22cd61a 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -653,10 +653,27 @@ namespace bpkg const linked_databases& lds (db.implicit_links (true /* attach */, sys_rep)); + // New boundary type. + // + const std::string& nbt (db.type == bt ? bt : empty_string); + // Skip the self-link. // for (auto i (lds.begin () + 1); i != lds.end (); ++i) - add (*i, db.type, db.type == bt ? bt : empty_string, add); + { + database& ldb (*i); + add (ldb, db.type, nbt, add); + + // If this configuration is of the build2 type, then also add the + // private host configurations of its implicitly linked + // configurations. + // + if (db.type == build2_config_type) + { + if (database* hdb = ldb.private_config (host_config_type)) + add (*hdb, db.type, nbt, add); + } + } }; add (*this, @@ -750,6 +767,21 @@ namespace bpkg // for (auto i (lcs.begin () + 1); i != lcs.end (); ++i) add (i->db, db.type, add); + + // If this is a private host configuration, then also add the parent's + // explicitly linked configurations of the build2 type. + // + if (db.private_ () && db.type == host_config_type) + { + const linked_configs& lcs (db.parent_config ().explicit_links ()); + + for (auto i (lcs.begin () + 1); i != lcs.end (); ++i) + { + database& ldb (i->db); + if (ldb.type == build2_config_type) + add (ldb, db.type, add); + } + } }; add (*this, type, add); @@ -824,6 +856,44 @@ namespace bpkg << config_orig << endf; } + database& database:: + parent_config (bool sys_rep) + { + assert (private_ ()); + + dir_path pd (config.directory ().directory ()); // Parent configuration. + const linked_databases& lds (implicit_links (true /* attach */, sys_rep)); + + // Skip the self-link. + // + for (auto i (lds.begin () + 1); i != lds.end (); ++i) + { + if (i->get ().config == pd) + return *i; + } + + // This should not happen normally and is likely to be the result of some + // bpkg misuse. + // + fail << "configuration " << pd << " is not linked to its private " + << "configuration " << config << endf; + } + + database* database:: + private_config (const std::string& type) + { + assert (!explicit_links_.empty ()); + + auto r (find_if (explicit_links_.begin () + 1, explicit_links_.end (), + [&type] (const linked_config& lc) + { + database& db (lc.db); + return db.private_ () && db.type == type; + })); + + return r != explicit_links_.end () ? &r->db.get () : nullptr; + } + bool database:: main () { diff --git a/bpkg/database.hxx b/bpkg/database.hxx index bf52ecb..32169bb 100644 --- a/bpkg/database.hxx +++ b/bpkg/database.hxx @@ -198,6 +198,13 @@ namespace bpkg // So for the above link chain only cfg2 configuration is included for a // build-time dependency foo and none for libbuild2-foo. // + // - While traversing through a private configuration of the host type + // consider the parent's explicitly linked configurations of the build2 + // type as also being explicitly linked to this private + // configuration. Note that build system module dependencies of packages + // in private host configurations are resolved from the parent's + // explicitly linked configurations of the build2 type. + // linked_databases dependency_configs (); @@ -215,6 +222,13 @@ namespace bpkg // configurations for dependents of a build-time dependency in host // configuration). // + // While traversing through a configuration of the build2 type consider + // private host configurations of its implicitly linked configurations as + // also being implicitly linked to this build2 configuration. Note that + // build system module dependencies of packages in private host + // configurations are resolved from the parent's explicitly linked + // configurations of the build2 type. + // linked_databases dependent_configs (bool sys_rep = false); @@ -243,6 +257,28 @@ namespace bpkg database& find_dependency_config (const uuid_type&); + // Return true if this configuration is private (i.e. its parent directory + // name is `.bpkg`). + // + bool + private_ () + { + return config.directory ().leaf () == bpkg_dir; + } + + // Return the implicitly linked configuration containing this + // configuration and issue diagnostics and fail if not found. Assume that + // this configuration is private. + // + database& + parent_config (bool sys_rep = false); + + // Return a private configuration of the specified type, if present, and + // NULL otherwise. + // + database* + private_config (const string& type); + // Return an empty string for the main database and the original // configuration directory path in the `[]` form otherwise. // diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 3ce9f43..e20909b 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -1154,33 +1154,31 @@ namespace bpkg // only one of them has the suitable type, then we use that. If there // are multiple of them, then we fail advising the user to pick one // explicitly. If there are none, then we create the private - // configuration and use that. + // configuration and use that. If the current configuration is + // private, then search/create in the parent configuration instead. // // Note that if the user has explicitly specified the configuration // for this dependency on the command line (using --config-*), then // this configuration is used as the starting point for this search. // - if (da.buildtime && dsp == nullptr) + if (da.buildtime && + dsp == nullptr && + ddb->type != buildtime_dependency_type (dn)) { - database* db (nullptr); + database* db (nullptr); + database& sdb (ddb->private_ () ? ddb->parent_config () : *ddb); + const string& type (buildtime_dependency_type (dn)); - // Note that the first returned link is for ddb itself. + // Skip the self-link. // - for (const linked_config& lc: ddb->explicit_links ()) + const linked_configs& lcs (sdb.explicit_links ()); + for (auto i (lcs.begin () + 1); i != lcs.end (); ++i) { - database& ldb (lc.db); + database& ldb (i->db); if (ldb.type == type) { - // We are done if the self-link is of the suitable type. - // - if (lc.id == 0) - { - db = &ldb; - break; - } - if (db == nullptr) db = &ldb; else @@ -1250,7 +1248,7 @@ namespace bpkg // outdated database schema version, etc. // cfg_create (options, - ddb->config_orig / cd, + sdb.config_orig / cd, optional (type) /* name */, type /* type */, mods, @@ -1261,8 +1259,8 @@ namespace bpkg // Note that we will copy the name from the configuration unless // it clashes with one of the existing links. // - shared_ptr lc (cfg_link (*ddb, - ddb->config / cd, + shared_ptr lc (cfg_link (sdb, + sdb.config / cd, true /* relative */, nullopt /* name */, true /* sys_rep */)); @@ -1271,9 +1269,9 @@ namespace bpkg // containing configuration database, for their subsequent re- // link. // - priv_cfgs.emplace_back (*ddb, move (cd)); + priv_cfgs.emplace_back (sdb, move (cd)); - db = &ddb->find_attached (*lc->id); + db = &sdb.find_attached (*lc->id); } ddb = db; // Switch to the dependency configuration. diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index be507f3..b316094 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -4589,14 +4589,14 @@ else { $clone_cfg; - $* libbar <'y' 2>>~%EOE% &cfg/.bpkg/host/***; - % new libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\] \(required by foo \[cfg..bpkg.host.\]\)% + $* libbar <'y' 2>>~%EOE% &cfg/.bpkg/host/*** &cfg/.bpkg/build2/***; + % new libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\] \(required by foo \[cfg..bpkg.host.\]\)% % new libbaz/1.0.0 \[cfg..bpkg.host.\] \(required by foo \[cfg..bpkg.host.\]\)% % new foo/1.0.0 \[cfg..bpkg.host.\] \(required by libbar\)% % new libbaz/1.0.0 \(required by libbar\)% new libbar/1.0.0 - %continue\? \[Y/n\] fetched libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% - %unpacked libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %continue\? \[Y/n\] fetched libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% + %unpacked libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %fetched libbaz/1.0.0 \[cfg..bpkg.host.\]% %unpacked libbaz/1.0.0 \[cfg..bpkg.host.\]% %fetched foo/1.0.0 \[cfg..bpkg.host.\]% @@ -4605,7 +4605,7 @@ else unpacked libbaz/1.0.0 fetched libbar/1.0.0 unpacked libbar/1.0.0 - %configured libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %configured libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %configured libbaz/1.0.0 \[cfg..bpkg.host.\]% %configured foo/1.0.0 \[cfg..bpkg.host.\]% configured libbaz/1.0.0 @@ -4618,7 +4618,7 @@ else !libbar configured 1.0.0 foo [cfg/.bpkg/host/] configured 1.0.0 libbaz [cfg/.bpkg/host/] configured 1.0.0 - libbuild2-bar [cfg/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [cfg/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 EOO @@ -4626,16 +4626,16 @@ else $* libbar <'y' 2>>~%EOE%; % upgrade libbaz/1.1.0 \[cfg..bpkg.host.\] \(required by foo \[cfg..bpkg.host.\]\)% - % drop libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\] \(unused\)% + % drop libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\] \(unused\)% % upgrade foo/1.1.0 \[cfg..bpkg.host.\] \(required by libbar\)% upgrade libbar/1.1.0 %continue\? \[Y/n\] disfigured libbar/1.0.0% %disfigured foo/1.0.0 \[cfg..bpkg.host.\]% - %disfigured libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %disfigured libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %disfigured libbaz/1.0.0 \[cfg..bpkg.host.\]% %fetched libbaz/1.1.0 \[cfg..bpkg.host.\]% %unpacked libbaz/1.1.0 \[cfg..bpkg.host.\]% - %purged libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %purged libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %fetched foo/1.1.0 \[cfg..bpkg.host.\]% %unpacked foo/1.1.0 \[cfg..bpkg.host.\]% fetched libbar/1.1.0 @@ -4866,7 +4866,7 @@ else % new libbaz/1.0.0 \[t2.\]% new foo/1.0.0 %continue\? \[Y.n\] fetched libbuild2-bar/1.0.0 \[t1..bpkg.build2.\]% - unpacked libbuild2-bar/1.0.0 [t1/.bpkg/build2/] + %unpacked libbuild2-bar/1.0.0 \[t1..bpkg.build2.\]% %fetched libbaz/1.0.0 \[t2.\]% %unpacked libbaz/1.0.0 \[t2.\]% fetched foo/1.0.0 @@ -5255,7 +5255,7 @@ else y EOI % drop libbaz/1.0.0 \[h2.\] \(unused\)% - % new libbuild2-bar/1.0.0 \[h1/.bpkg/build2.\] \(required by foo\)% + % new libbuild2-bar/1.0.0 \[h1..bpkg.build2.\] \(required by foo\)% new libbaz/1.0.0 downgrade foo/1.0.0 reconfigure libbar/1.0.0 (dependent of libbaz) @@ -5451,7 +5451,7 @@ else !libbar configured 1.0.0 foo [t1/.bpkg/host/] configured 1.0.0 libbaz [t1/.bpkg/host/] configured 1.0.0 - libbuild2-bar [t1/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [t1/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 EOO @@ -5466,19 +5466,19 @@ else EOI % new libbaz/1.1.0 \[h1.\] \(required by foo \[h1.\]\)% % new foo/1.1.0 \[h1.\]% - % drop libbuild2-bar/1.0.0 \[t1..bpkg.host..bpkg.build2.\] \(unused\)% + % drop libbuild2-bar/1.0.0 \[t1..bpkg.build2.\] \(unused\)% % drop libbaz/1.0.0 \[t1..bpkg.host.\] \(unused\)% % drop foo/1.0.0 \[t1..bpkg.host.\] \(unused\)% upgrade libbar/1.1.0 continue? [Y/n] disfigured libbar/1.0.0 %disfigured foo/1.0.0 \[t1..bpkg.host.\]% %disfigured libbaz/1.0.0 \[t1..bpkg.host.\]% - %disfigured libbuild2-bar/1.0.0 \[t1..bpkg.host..bpkg.build2.\]% + %disfigured libbuild2-bar/1.0.0 \[t1..bpkg.build2.\]% %fetched libbaz/1.1.0 \[h1.\]% %unpacked libbaz/1.1.0 \[h1.\]% %fetched foo/1.1.0 \[h1.\]% %unpacked foo/1.1.0 \[h1.\]% - %purged libbuild2-bar/1.0.0 \[t1..bpkg.host..bpkg.build2.\]% + %purged libbuild2-bar/1.0.0 \[t1..bpkg.build2.\]% %purged libbaz/1.0.0 \[t1..bpkg.host.\]% %purged foo/1.0.0 \[t1..bpkg.host.\]% fetched libbar/1.1.0 @@ -5575,7 +5575,7 @@ else !libbar configured 1.0.0 foo [t1/.bpkg/host/] configured 1.0.0 libbaz [t1/.bpkg/host/] configured 1.0.0 - libbuild2-bar [t1/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [t1/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 EOO @@ -5614,7 +5614,7 @@ else !libbar configured 1.0.0 available 1.1.0 foo [t1/.bpkg/host/] configured 1.0.0 available 1.1.0 libbaz [t1/.bpkg/host/] configured 1.0.0 available 1.1.0 - libbuild2-bar [t1/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [t1/.bpkg/build2/] configured 1.0.0 !libbaz [t2/] configured 1.1.0 !libbaz [t2/] configured 1.1.0 EOO @@ -5633,7 +5633,7 @@ else !libbar configured 1.0.0 foo [t1/.bpkg/host/] configured 1.0.0 libbaz [t1/.bpkg/host/] configured 1.0.0 - libbuild2-bar [t1/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [t1/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 EOO @@ -5670,7 +5670,7 @@ else !libbar configured 1.0.0 available 1.1.0 foo [t1/.bpkg/host/] configured 1.0.0 available 1.1.0 libbaz [t1/.bpkg/host/] configured 1.0.0 available 1.1.0 - libbuild2-bar [t1/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [t1/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 available 1.1.0 !libbar [t2/] configured 1.1.0 foo [t2/.bpkg/host/] configured 1.1.0 @@ -5787,15 +5787,15 @@ else $* libbiz <>~%EOE% &cfg/.bpkg/build2/*** &cfg/.bpkg/host/***; y EOI - % new libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\] \(required by foo \[cfg..bpkg.host.\]\)% + % new libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\] \(required by foo \[cfg..bpkg.host.\]\)% % new libbaz/1.0.0 \[cfg..bpkg.host.\] \(required by foo \[cfg..bpkg.host.\]\)% % new foo/1.0.0 \[cfg..bpkg.host.\] \(required by libbiz\)% % new libbaz/1.0.0 \[cfg..bpkg.build2.\] \(required by libbuild2-foo \[cfg..bpkg.build2.\]\)% % new libbuild2-foo/1.0.0 \[cfg..bpkg.build2.\] \(required by libbiz\)% new libbaz/1.0.0 (required by libbiz) new libbiz/1.0.0 - %continue\? \[Y/n\] fetched libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% - %unpacked libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %continue\? \[Y/n\] fetched libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% + %unpacked libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %fetched libbaz/1.0.0 \[cfg..bpkg.host.\]% %unpacked libbaz/1.0.0 \[cfg..bpkg.host.\]% %fetched foo/1.0.0 \[cfg..bpkg.host.\]% @@ -5808,7 +5808,7 @@ else unpacked libbaz/1.0.0 fetched libbiz/1.0.0 unpacked libbiz/1.0.0 - %configured libbuild2-bar/1.0.0 \[cfg..bpkg.host..bpkg.build2.\]% + %configured libbuild2-bar/1.0.0 \[cfg..bpkg.build2.\]% %configured libbaz/1.0.0 \[cfg..bpkg.host.\]% %configured foo/1.0.0 \[cfg..bpkg.host.\]% %configured libbaz/1.0.0 \[cfg..bpkg.build2.\]% @@ -5823,7 +5823,7 @@ else !libbiz configured 1.0.0 foo [cfg/.bpkg/host/] configured 1.0.0 libbaz [cfg/.bpkg/host/] configured 1.0.0 - libbuild2-bar [cfg/.bpkg/host/.bpkg/build2/] configured 1.0.0 + libbuild2-bar [cfg/.bpkg/build2/] configured 1.0.0 libbaz configured 1.0.0 libbuild2-foo [cfg/.bpkg/build2/] configured 1.0.0 libbaz [cfg/.bpkg/build2/] configured 1.0.0 @@ -5921,7 +5921,7 @@ else $* libbix 2>>/~%EOE% != 0 error: building build system module libbuild2-bar in multiple configurations - % info: cfg(2|3)/.bpkg/host/.bpkg/build2/%{2} + % info: cfg(2|3)/.bpkg/build2/%{2} EOE } } diff --git a/tests/pkg-drop.testscript b/tests/pkg-drop.testscript index 930c4f3..83fa13b 100644 --- a/tests/pkg-drop.testscript +++ b/tests/pkg-drop.testscript @@ -486,10 +486,10 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 cp -pr ../cfg-bar ./; cp -pr ../cfg-foo ./; - $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes 2>!; - $pkg_build libbaz 2>!; + $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes; + $pkg_build libbaz; - $pkg_build '?libbar' +{ --config-id 1 } 2>!; + $pkg_build '?libbar' +{ --config-id 1 }; $* libbaz <>/~%EOE% y @@ -517,14 +517,14 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 cp -pr ../cfg-bar ./; cp -pr ../cfg-foo ./; - $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes 2>!; - $pkg_build libbaz 2>!; + $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes; + $pkg_build libbaz; # Make sure that dependents of a package being dropped can be found in # implicitly linked configurations recursively. Note that configuring # libbar as system, we make libbaz an only dependent of libfoo. # - $pkg_build '?sys:libbar' +{ --config-id 1 } 2>!; + $pkg_build '?sys:libbar' +{ --config-id 1 }; $pkg_status -r libbaz >>/EOO; !libbaz configured 1.1.0 @@ -575,8 +575,8 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 $cfg_link -d cfg-bar cfg; $cfg_link -d cfg-foo cfg-bar; - $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes 2>!; - $pkg_build libbaz 2>!; + $pkg_build libbar@"$rep/t4b" -d cfg-bar ?libfoo +{ --config-id 2 } --trust-yes; + $pkg_build libbaz; $pkg_status -r libbaz >>/EOO; !libbaz configured 1.1.0 @@ -632,7 +632,7 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 $clone_cfg; cp -pr ../cfg2 ./; - $pkg_build libbar --yes &cfg2/.bpkg/build2/*** >!; + $pkg_build libbar --yes &cfg2/.bpkg/build2/***; $* libbar <>/~%EOE%; y @@ -669,7 +669,7 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 $clone_cfg; cp -pr ../cfg2 ./; - $pkg_build libbar --yes &cfg2/.bpkg/build2/*** >!; + $pkg_build libbar --yes &cfg2/.bpkg/build2/***; $* -d cfg2 libbaz <>/~%EOE%; y @@ -702,13 +702,49 @@ $* libfoo/1.0.0 2>>~%EOE% != 0 $pkg_status -r libbar >'libbar available 1.0.0' } + : drop-private-dependency + : + { + $clone_root_cfg && $rep_add $rep/t7a && $rep_fetch; + + $pkg_build libbar --yes &cfg/.bpkg/host/*** &cfg/.bpkg/build2/***; + + $* -d cfg/.bpkg/build2/ libbuild2-bar <>/~%EOE% + y + y + y + EOI + following dependent packages will have to be dropped as well: + foo [cfg/.bpkg/host/] (requires libbuild2-bar) + libbar [cfg/] (requires foo [cfg/.bpkg/host/]) + %drop dependent packages\? \[y.N\] following dependencies were automatically built but will no longer be used:% + libbaz [cfg/.bpkg/host/] + libbaz [cfg/] + %drop unused packages\? \[Y.n\] drop libbar \[cfg/\]% + drop foo [cfg/.bpkg/host/] + drop libbuild2-bar + drop libbaz [cfg/.bpkg/host/] + drop libbaz [cfg/] + %continue\? \[Y.n\] disfigured libbar \[cfg/\]% + disfigured foo [cfg/.bpkg/host/] + disfigured libbuild2-bar + disfigured libbaz [cfg/.bpkg/host/] + disfigured libbaz [cfg/] + purged libbar [cfg/] + purged foo [cfg/.bpkg/host/] + purged libbuild2-bar + purged libbaz [cfg/.bpkg/host/] + purged libbaz [cfg/] + EOE + } + : skip-deleted-dependency : { $clone_cfg; cp -pr ../cfg2 ./; - $pkg_build libbar --yes >! &cfg/lib*/*** &cfg/lib* &cfg2/.bpkg/build2/***; + $pkg_build libbar --yes &cfg/lib*/*** &cfg/lib* &cfg2/.bpkg/build2/***; mv cfg cfg.tmp; -- cgit v1.1