From 114a809fbf1d36c3fc6a78aac27120ccb1d85064 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 27 Apr 2022 16:08:09 +0300 Subject: Add initial support for negotiating dependency configuration with existing dependents --- bpkg/pkg-build.cxx | 709 +++++++++++++++++---- .../dependency-alternatives/t11a/tex-0.1.0.tar.gz | Bin 0 -> 451 bytes .../dependency-alternatives/t11a/tex-0.2.0.tar.gz | Bin 0 -> 462 bytes .../dependency-alternatives/t11a/tex-0.3.0.tar.gz | Bin 0 -> 466 bytes .../dependency-alternatives/t11a/tix-0.1.0.tar.gz | Bin 0 -> 407 bytes .../dependency-alternatives/t11a/tux-1.0.0.tar.gz | Bin 0 -> 469 bytes tests/pkg-build.testscript | 423 +++++++++++- 7 files changed, 975 insertions(+), 157 deletions(-) create mode 100644 tests/common/dependency-alternatives/t11a/tex-0.1.0.tar.gz create mode 100644 tests/common/dependency-alternatives/t11a/tex-0.2.0.tar.gz create mode 100644 tests/common/dependency-alternatives/t11a/tex-0.3.0.tar.gz create mode 100644 tests/common/dependency-alternatives/t11a/tix-0.1.0.tar.gz create mode 100644 tests/common/dependency-alternatives/t11a/tux-1.0.0.tar.gz diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index a562a4e..94d83cf 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -386,26 +386,6 @@ namespace bpkg return make_pair (find_imaginary_stub (name), nullptr); } - // Try to find an available package corresponding to the specified selected - // package and, if not found, return a transient one. - // - static shared_ptr - find_available (const common_options& options, - database& db, - const shared_ptr& sp) - { - available_package_id pid (sp->name, sp->version); - for (database& db: dependent_repo_configs (db)) - { - shared_ptr ap (db.find (pid)); - - if (ap != nullptr && !ap->stub ()) - return ap; - } - - return make_available (options, db, sp); - } - // Create a transient (or fake, if you prefer) available_package object // corresponding to the specified selected object. Note that the package // locations list is left empty and that the returned repository fragment @@ -456,6 +436,55 @@ namespace bpkg return make_pair (move (ap), move (rf)); } + // Try to find an available package corresponding to the specified selected + // package and, if not found, return a transient one. + // + static shared_ptr + find_available (const common_options& options, + database& db, + const shared_ptr& sp) + { + available_package_id pid (sp->name, sp->version); + for (database& ddb: dependent_repo_configs (db)) + { + shared_ptr ap (ddb.find (pid)); + + if (ap != nullptr && !ap->stub ()) + return ap; + } + + return make_available (options, db, sp); + } + + // As above but also pair the available package with the repository fragment + // the available package comes from. Note that the package locations list is + // left empty and that the returned repository fragment could be NULL if the + // package is an orphan. + // + static pair, + lazy_shared_ptr> + find_available_fragment (const common_options& options, + database& db, + const shared_ptr& sp) + { + available_package_id pid (sp->name, sp->version); + for (database& ddb: dependent_repo_configs (db)) + { + shared_ptr ap (ddb.find (pid)); + + if (ap != nullptr && !ap->stub ()) + { + if (shared_ptr f = ddb.find ( + sp->repository_fragment.canonical_name ())) + return make_pair (ap, + lazy_shared_ptr (ddb, + move (f))); + } + } + + return make_pair (find_available (options, db, sp), nullptr); + } + // Return true if the version constraint represents the wildcard version. // static inline bool @@ -1107,8 +1136,16 @@ namespace bpkg struct postponed_configuration { - using packages = small_vector; - using dependents_map = map>; + using packages = small_vector; + + struct dependent_info + { + bool existing; + size_t position; + packages dependencies; + }; + + using dependents_map = map; using dependencies_set = set; // Note that for a cluster based on an existing dependent, only @@ -1125,13 +1162,15 @@ namespace bpkg // Add dependencies of a new dependent. // postponed_configuration (config_package&& dependent, + bool existing, size_t position, packages&& deps) { assert (position != 0); dependencies.insert (deps.begin (), deps.end ()); - dependents.emplace (move (dependent), make_pair (position, move (deps))); + dependents.emplace (move (dependent), + dependent_info {existing, position, move (deps)}); } // Add dependency of an existing dependent. @@ -1184,9 +1223,7 @@ namespace bpkg { for (auto& d: c.dependents) { - auto i (dependents.emplace (d.first, - make_pair (d.second.first, - move (d.second.second)))); + auto i (dependents.emplace (d.first, move (d.second))); // The being merged clusters should never intersect by dependents. // @@ -1245,7 +1282,7 @@ namespace bpkg bool first (true); for (const auto& dt: dependents) { - const packages& ds (dt.second.second); + const packages& ds (dt.second.dependencies); if (find (ds.begin (), ds.end (), d) != ds.end ()) { @@ -1256,7 +1293,7 @@ namespace bpkg r += dt.first.string (); r += '/'; - r += to_string (dt.second.first); + r += to_string (dt.second.position); } } @@ -1279,6 +1316,7 @@ namespace bpkg // void add (config_package dependent, + bool existing, size_t position, postponed_configuration::packages&& dependencies, bool allow_negotiated = false) @@ -1308,6 +1346,7 @@ namespace bpkg if (c.contains_dependency (dependencies)) { postponed_configuration tc (move (dependent), + existing, position, move (dependencies)); @@ -1327,6 +1366,7 @@ namespace bpkg i = insert_after (j, postponed_configuration ( move (dependent), + existing, position, move (dependencies))); @@ -1518,6 +1558,63 @@ namespace bpkg } }; + // Map of existing dependent packages whose participation in dependencies + // configuration negotiation need to be postponed because they will be + // built. + // + // Note that while negotiating configuration for dependencies among their + // dependents with configuration clauses we also need to consider + // configuration clauses of dependents which are already configured. We, + // however, may later discover that such an existing package needs to be + // built (upgraded, reconfigured, etc), in which case we need to note to + // postpone such a premature negotiation participation for this dependent + // and re-collect from scratch. + // + struct postponed_dependent + { + bool build; // The dependent is being built or dropped. + bool config; // Has config clause for being built dependencies. + }; + + class postponed_dependents: public map + { + public: + // If the package is an existing dependent which has already participated + // in negotiation of configuration for its dependencies (belongs to some + // configuration cluster as a dependent and is marked as existing), then + // add it to the map and return true. + // + // Regradless if the dependent is just postponed or was postponed earlier, + // mark it as being built. + // + bool + postpone (const config_package& cp, + const postponed_configurations& postponed_cfgs) + { + auto i (find (cp)); + + if (i == end ()) + { + for (const postponed_configuration& cfg: postponed_cfgs) + { + auto i (cfg.dependents.find (cp)); + if (i != cfg.dependents.end () && i->second.existing) + { + emplace (cp, + postponed_dependent {true /* build */, + true /* config */}); + + return true; + } + } + } + else + i->second.build = true; + + return false; + } + }; + struct build_packages: build_package_list { build_packages () = default; @@ -1651,6 +1748,13 @@ namespace bpkg : scratch_collection ("package version replacement") {} }; + struct postpone_dependent: scratch_collection + { + postpone_dependent () + : scratch_collection ("prematurely cfg-negotiated existing " + "dependent") {} + }; + using verify_package_build_function = void (const build_package&, bool scratch); @@ -1662,11 +1766,12 @@ namespace bpkg const function& apc, bool initial_collection, replaced_versions& replaced_vers, + postponed_dependents& postponed_dpts, + postponed_configurations& postponed_cfgs, build_package_refs* dep_chain = nullptr, postponed_packages* postponed_repo = nullptr, postponed_packages* postponed_alts = nullptr, postponed_dependencies* postponed_deps = nullptr, - postponed_configurations* postponed_cfgs = nullptr, const function& vpb = nullptr) { using std::swap; // ...and not list::swap(). @@ -1678,8 +1783,7 @@ namespace bpkg bool recursive (dep_chain != nullptr); assert ((postponed_repo != nullptr) == recursive && (postponed_alts != nullptr) == recursive && - (postponed_deps != nullptr) == recursive && - (postponed_cfgs != nullptr) == recursive); + (postponed_deps != nullptr) == recursive); // Only builds are allowed here. // @@ -1708,6 +1812,21 @@ namespace bpkg l5 ([&]{trace << "replacement: " << pkg.available_name_version_db ();}); } + // If the package is postponed as an existing dependent prematurely + // participated in configuration negotiation for its dependencies, then + // re-collect from scratch. + // + if (postponed_dpts.postpone (cp, postponed_cfgs)) + { + l5 ([&]{trace << "cannot collect prematurely cfg-negotiated " + << "existing dependent " << cp << ", throwing";}); + + if (vpb) + vpb (pkg, true /* scratch */); + + throw postpone_dependent (); + } + auto i (map_.find (cp)); // If we already have an entry for this package name, then we have to @@ -1944,12 +2063,13 @@ namespace bpkg apc, initial_collection, replaced_vers, + postponed_dpts, + postponed_cfgs, *dep_chain, postponed_repo, postponed_alts, 0 /* max_alt_index */, - *postponed_deps, - *postponed_cfgs); + *postponed_deps); return &p; } @@ -2040,12 +2160,13 @@ namespace bpkg const function& apc, bool initial_collection, replaced_versions& replaced_vers, + postponed_dependents& postponed_dpts, + postponed_configurations& postponed_cfgs, build_package_refs& dep_chain, postponed_packages* postponed_repo, postponed_packages* postponed_alts, size_t max_alt_index, - postponed_dependencies& postponed_deps, - postponed_configurations& postponed_cfgs) + postponed_dependencies& postponed_deps) { tracer trace ("collect_build_prerequisites"); @@ -2080,51 +2201,20 @@ namespace bpkg pkg.reconfigure () && postponed_cfgs.find_dependency (cp) == nullptr) { - for (database& ddb: pdb.dependent_configs ()) - { - for (auto& pd: query_dependents (ddb, nm, pdb)) - { - shared_ptr dsp ( - ddb.load (pd.name)); + vector cds ( + query_configuring_dependents (options, pdb, nm, postponed_dpts)); - shared_ptr dap ( - find_available (options, ddb, dsp)); - - for (const dependency_alternatives& das: dap->dependencies) - { - // Note that we also need to consider the dependency's - // build-time flag and check if the package can be resolved as a - // dependency via this specific depends manifest value (think of - // unlikely but possible situation that a dependent depends both - // runtime and build-time on the same dependency). - // - linked_databases ddbs ( - ddb.dependency_configs (nm, das.buildtime)); + if (!cds.empty ()) + { + configuring_dependent& cd (cds.front ()); - if (find (ddbs.begin (), ddbs.end (), pdb) == ddbs.end ()) - continue; + l5 ([&]{trace << "cfg-postpone dependency " + << pkg.available_name_version_db () + << " of existing dependent " << *cd.selected + << cd.db;}); - for (const dependency_alternative& da: das) - { - if (da.prefer || da.require) - { - for (const dependency& d: da) - { - if (d.name == nm) - { - l5 ([&]{trace << "cfg-postpone dependency " - << pkg.available_name_version_db () - << " of existing dependent " << *dsp - << ddb;}); - - postponed_cfgs.add (move (cp)); - return; - } - } - } - } - } - } + postponed_cfgs.add (move (cp)); + return; } } @@ -2155,15 +2245,21 @@ namespace bpkg if (src_conf) { - repointed_dependents::const_iterator i (rpt_depts.find (cp)); + { + repointed_dependents::const_iterator i (rpt_depts.find (cp)); + + if (i != rpt_depts.end ()) + rpt_prereq_flags = &i->second; + } - if (i != rpt_depts.end ()) - rpt_prereq_flags = &i->second; + postponed_dependents::const_iterator i; - if (!ud && - rpt_prereq_flags == nullptr && + if (!ud && + rpt_prereq_flags == nullptr && (pkg.config_vars.empty () || - !has_buildfile_clause (ap->dependencies))) + !has_buildfile_clause (ap->dependencies)) && + ((i = postponed_dpts.find (cp)) == postponed_dpts.end () || + !i->second.config)) { l5 ([&]{trace << "skip configured " << pkg.available_name_version_db ();}); @@ -3061,11 +3157,12 @@ namespace bpkg &apc, initial_collection, &replaced_vers, + &postponed_cfgs, + &postponed_dpts, &dep_chain, postponed_repo, postponed_alts, &postponed_deps, - &postponed_cfgs, &di, &trace, this] @@ -3209,11 +3306,12 @@ namespace bpkg apc, initial_collection, replaced_vers, + postponed_dpts, + postponed_cfgs, nullptr /* dep_chain */, nullptr /* postponed_repo */, nullptr /* postponed_alts */, nullptr /* postponed_deps */, - nullptr /* postponed_cfgs */, verify)); // Do not recursively collect a dependency of a dependent with @@ -3349,6 +3447,7 @@ namespace bpkg } cfgs.add (cp, + false /* existing */, di + 1, postponed_configuration::packages ({dcp}), true /* allow_negotiated */); @@ -3371,7 +3470,7 @@ namespace bpkg const config_package& cp (p.first); const postponed_configuration::packages& deps ( - p.second.second); + p.second.dependencies); // Collect all the potentially indirect dependents of // this package which belong to the same cluster and @@ -3422,7 +3521,7 @@ namespace bpkg // dependency and skip it if that's not the case. // const postponed_configuration::packages& ds ( - dv.second.second); + dv.second.dependencies); if (find (ds.begin (), ds.end (), p) == ds.end ()) continue; @@ -3442,7 +3541,7 @@ namespace bpkg return p.first == d; })); - size_t pos (dv.second.first); + size_t pos (dv.second.position); if (i == depts.end ()) depts.push_back (make_pair (ref (d), pos)); @@ -3468,9 +3567,9 @@ namespace bpkg assert (i != cfg.dependents.end ()); const postponed_configuration::packages& ddeps ( - i->second.second); + i->second.dependencies); - size_t dpos (i->second.first); + size_t dpos (i->second.position); if (dpos >= dp.second) continue; @@ -3493,6 +3592,16 @@ namespace bpkg // to stash it in collect_depts() for each // resulting dependent. // + // @@ Actually this failure can be premature, + // since later we could end up replacing the + // problematic dependent with a different + // version (which doesn't introduce a cycle) + // via some of it's dependency's + // constraint. This may happen on the same + // execution plan refinement iteration or on + // some later iteration, caused by the + // user-specified dependency constraint. + // fail << "package " << str (dp.first) << " negotiates configuration of " << str (d) << " before its (potentially " @@ -3563,12 +3672,13 @@ namespace bpkg apc, initial_collection, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, postponed_repo, postponed_alts, 0 /* max_alt_index */, - postponed_deps, - postponed_cfgs); + postponed_deps); } // Postpone a dependent that has configuration clauses and the @@ -3579,7 +3689,10 @@ namespace bpkg // if (!cfg_deps.empty ()) { - postponed_cfgs.add (move (cp), di + 1, move (cfg_deps)); + postponed_cfgs.add (move (cp), + false /* existing */, + di + 1, + move (cfg_deps)); return false; } @@ -3905,10 +4018,11 @@ namespace bpkg const pkg_build_options& o, const repointed_dependents& rpt_depts, replaced_versions& replaced_vers, + postponed_dependents& postponed_dpts, + postponed_configurations& postponed_cfgs, postponed_packages& postponed_repo, postponed_packages& postponed_alts, postponed_dependencies& postponed_deps, - postponed_configurations& postponed_cfgs, const function& fdb, const function& apc) { @@ -3986,20 +4100,38 @@ namespace bpkg apc, true /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, &dep_chain, &postponed_repo, &postponed_alts, - &postponed_deps, - &postponed_cfgs); + &postponed_deps); } } // Collect the package being dropped. // void - collect_drop (database& db, shared_ptr sp) + collect_drop (database& db, + shared_ptr sp, + postponed_dependents& postponed_dpts, + const postponed_configurations& postponed_cfgs) { - const package_name& nm (sp->name); + tracer trace ("collect_drop"); + + config_package cp (db, sp->name); + + // If the package is postponed as an existing dependent prematurely + // participated in configuration negotiation for its dependencies, then + // re-collect from scratch. + // + if (postponed_dpts.postpone (cp, postponed_cfgs)) + { + l5 ([&]{trace << "cannot drop prematurely cfg-negotiated " + << "existing dependent " << cp << ", throwing";}); + + throw postpone_dependent (); + } build_package p { build_package::drop, @@ -4025,7 +4157,7 @@ namespace bpkg false, // Required by dependents. 0}; // State flags. - auto i (map_.find (db, nm)); + auto i (map_.find (cp)); if (i != map_.end ()) { @@ -4037,8 +4169,7 @@ namespace bpkg bp = move (p); } else - map_.emplace (config_package {db, nm}, - data_type {end (), move (p)}); + map_.emplace (move (cp), data_type {end (), move (p)}); } // Collect the package being unheld. @@ -4096,11 +4227,12 @@ namespace bpkg const function& apc, bool initial_collection, replaced_versions& replaced_vers, + postponed_dependents& postponed_dpts, + postponed_configurations& postponed_cfgs, postponed_packages& postponed_repo, postponed_packages& postponed_alts, size_t max_alt_index, - postponed_dependencies& postponed_deps, - postponed_configurations& postponed_cfgs) + postponed_dependencies& postponed_deps) { auto mi (map_.find (db, name)); assert (mi != map_.end ()); @@ -4114,12 +4246,13 @@ namespace bpkg apc, initial_collection, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, &postponed_repo, &postponed_alts, max_alt_index, - postponed_deps, - postponed_cfgs); + postponed_deps); } // Note: depth is only used for tracing. @@ -4127,10 +4260,11 @@ namespace bpkg void collect_build_postponed (const pkg_build_options& o, replaced_versions& replaced_vers, + postponed_dependents& postponed_dpts, + postponed_configurations& postponed_cfgs, postponed_packages& postponed_repo, postponed_packages& postponed_alts, postponed_dependencies& postponed_deps, - postponed_configurations& postponed_cfgs, const function& fdb, const repointed_dependents& rpt_depts, const function& apc, @@ -4221,14 +4355,126 @@ namespace bpkg // without configuration clause (see // collect_build_prerequisites() implementation for details). // - // - After existing dependents are re-collected, should we make - // sure that they do not introduce a dependency cycle (as we do - // for new dependents)? + // - When re-evaluate an existing dependent we need to realize that + // some of it configured dependencies can be in some other + // clusters. // assert (!pcfg->negotiated); + // Re-evaluate existing dependents with configuration clause of this + // config dependencies up to these dependencies. Omit dependents which + // are already being built or dropped. + // + // Note that this will result in adding these dependents to this + // cluster. + // + // @@ Also note that we need to watch carefully if the re-evaluation + // may end up with merge of pcfg into some other cluster. If this + // case pcfg pointer will be invalidated which we will need to + // handle somehow. + // + // @@ TMP For now, instead of the proper re-evaluation, just add these + // dependents to this cluster using position 1 for their + // dependencies. Note that it will not cause merge since the + // dependencies are all in this cluster already. + // + // Map such dependents to the dependencies it applies configuration + // to. Also, while at it, collect the information which is required + // for a dependent re-evaluation and its subsequent recursive + // collection. + // + { + struct dependent_info + { + shared_ptr selected; + shared_ptr available; + lazy_shared_ptr repository_fragment; + postponed_configuration::packages dependencies; + }; + + map dependents; + + for (const config_package& p: pcfg->dependencies) + { + for (configuring_dependent& cd: + query_configuring_dependents (o, + p.db, + p.name, + postponed_dpts)) + { + config_package cp (cd.db, cd.selected->name); + + auto i ( + dependents.emplace (move (cp), + dependent_info { + move (cd.selected), + move (cd.available), + move (cd.repository_fragment), + postponed_configuration::packages ()})); + + i.first->second.dependencies.push_back (p); + } + } + + if (!dependents.empty ()) + { + l5 ([&]{trace << "re-evaluate existing dependents";}); + + for (auto& d: dependents) + { + config_package cp (d.first); + dependent_info& di (d.second); + postponed_configuration::packages& ds (di.dependencies); + + build_package p { + build_package::build, + cp.db, + move (di.selected), + move (di.available), + move (di.repository_fragment), + nullopt, // Dependencies. + nullopt, // Package skeleton. + nullopt, // Postponed dependency alternatives. + false, // Recursive collection. + nullopt, // Hold package. + nullopt, // Hold version. + {}, // Constraints. + false, // System. + false, // Keep output directory. + false, // Disfigure (from-scratch reconf). + false, // Configure-only. + nullopt, // Checkout root. + false, // Checkout purge. + strings (), // Configuration variables. + set ( + ds.begin (), ds.end ()), // Required by (dependency). + false, // Required by dependents. + 0}; // State flags. + + collect_build (o, + move (p), + fdb, + rpt_depts, + apc, + true /* initial_collection */, + replaced_vers, + postponed_dpts, + postponed_cfgs); + + // @@ Re-evaluate up-to the cluster's dependencies. + + postponed_cfgs.add (move (cp), + true /* existing */, + 1, + move (ds)); + } + } + } + l5 ([&]{trace << "cfg-negotiate begin " << *pcfg;}); + // @@ Negotiate configuration. + // Being negotiated (so can only be up-negotiated). // pcfg->negotiated = false; @@ -4257,12 +4503,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, &postponed_repo, &postponed_alts, 0 /* max_alt_index */, - postponed_deps, - postponed_cfgs); + postponed_deps); } // Continue processing dependents with this config. @@ -4271,6 +4518,13 @@ namespace bpkg for (const auto& p: pcfg->dependents) { + // @@ TMP Re-evaluated existing dependents should not be + // distingushed from others here (they will also have + // postponed_dependency_alternatives present, etc). + // + if (p.second.existing) + continue; + build_package* b (this->entered_build (p.first)); assert (b != nullptr && b->postponed_dependency_alternatives); @@ -4284,12 +4538,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, &postponed_repo, &postponed_alts, b->postponed_dependency_alternatives->size (), - postponed_deps, - postponed_cfgs); + postponed_deps); } // Negotiated (so can only be rolled back). @@ -4331,12 +4586,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, &prs, &pas, 0 /* max_alt_index */, - postponed_deps, - postponed_cfgs); + postponed_deps); } // Save the potential new dependency alternative-related postpones. @@ -4397,10 +4653,11 @@ namespace bpkg { collect_build_postponed (o, replaced_vers, + postponed_dpts, + postponed_cfgs, postponed_repo, postponed_alts, postponed_deps, - postponed_cfgs, fdb, rpt_depts, apc, @@ -4520,12 +4777,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, &prs, &pas, i, - postponed_deps, - postponed_cfgs); + postponed_deps); prog = (pas.find (p) == pas.end () || ndep != p->dependencies->size ()); @@ -4587,12 +4845,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, nullptr, nullptr, 0, - postponed_deps, - postponed_cfgs); + postponed_deps); assert (false); // Can't be here. } @@ -4608,12 +4867,13 @@ namespace bpkg apc, false /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, dep_chain, nullptr, nullptr, 0, - postponed_deps, - postponed_cfgs); + postponed_deps); assert (false); // Can't be here. } @@ -4920,6 +5180,149 @@ namespace bpkg p.second.position = end (); } + // Verify that builds ordering is consistent across all the data + // structures and the ordering expectations are fulfilled (real build + // actions are all ordered, etc). + // + void + verify_ordering () const + { + for (const auto& b: map_) + { + const build_package& bp (b.second.package); + + auto i (find_if (begin (), end (), + [&bp] (const build_package& p) {return &p == &bp;})); + + // List ordering must properly be reflected in the tree entries. + // + assert (i == b.second.position); + + // Pre-entered builds must never be ordered and the real build actions + // (builds, adjustments, etc) must all be ordered. + // + // Note that the later was not the case until we've implemented + // re-collection from scratch after the package version replacement + // (see replaced_versions for details). Before that the whole + // dependency trees from the being replaced dependent stayed in the + // map. + // + assert (bp.action.has_value () == (i != end ())); + } + } + + private: + // Return the list of existing dependents that potentially has a + // configuration clause for this (being built) dependency. Skip the being + // built or postponed dependents. + // + struct configuring_dependent + { + reference_wrapper db; + shared_ptr selected; + shared_ptr available; + + // Can be NULL (orphan). + // + lazy_shared_ptr repository_fragment; + }; + + vector + query_configuring_dependents (const pkg_build_options& options, + database& db, + const package_name& name, + postponed_dependents& postponed_dpts) + { + vector r; + + for (database& ddb: db.dependent_configs ()) + { + for (auto& pd: query_dependents (ddb, name, db)) + { + config_package cp (ddb, pd.name); + + // Ignore dependent which is already being built or dropped. + // + const build_package* p (entered_build (cp)); + + if (p != nullptr && + p->action && + (*p->action == build_package::build || + *p->action == build_package::drop)) + continue; + + shared_ptr dsp ( + ddb.load (pd.name)); + + pair, + lazy_shared_ptr> rp ( + find_available_fragment (options, ddb, dsp)); + + shared_ptr& dap (rp.first); + + // See it this dependent potentially configures the specified + // dependency. + // + bool conf (false); + for (const dependency_alternatives& das: dap->dependencies) + { + // Note that we also need to consider the dependency's + // build-time flag and check if the package can be resolved as a + // dependency via this specific depends manifest value (think of + // unlikely but possible situation that a dependent depends both + // runtime and build-time on the same dependency). + // + linked_databases ddbs ( + ddb.dependency_configs (name, das.buildtime)); + + if (find (ddbs.begin (), ddbs.end (), db) == ddbs.end ()) + continue; + + for (const dependency_alternative& da: das) + { + if (da.prefer || da.require) + { + for (const dependency& d: da) + { + if (d.name == name) + { + conf = true; + break; + } + } + + if (conf) + break; + } + } + + if (conf) + break; + } + + // If the dependent's participation in dependencies configuration + // negotiation is postponed, then mark it as still configuring some + // dependency. Otherwise, add it to the resulting list. + // + if (conf) + { + auto i (postponed_dpts.find (cp)); + if (i == postponed_dpts.end ()) + { + r.push_back (configuring_dependent {ddb, + move (dsp), + move (dap), + move (rp.second)}); + } + else + i->second.config = true; + } + } + } + + return r; + } + private: struct config_package_name { @@ -8046,6 +8449,7 @@ namespace bpkg replaced_versions replaced_vers; postponed_dependencies postponed_deps; + postponed_dependents postponed_dpts; // Map the repointed dependents to the replacement flags (see // repointed_dependents for details), unless --no-move is specified. @@ -8326,8 +8730,9 @@ namespace bpkg if (scratch_exe) { - postponed_deps.clear (); replaced_vers.clear (); + postponed_dpts.clear (); + postponed_deps.clear (); scratch_exe = false; } @@ -8335,15 +8740,21 @@ namespace bpkg { // Reset to detect bogus entries. // + for (auto& rv: replaced_vers) + rv.second.replaced = false; + + for (auto& pd: postponed_dpts) + { + pd.second.build = false; + pd.second.config = false; + } + for (auto& pd: postponed_deps) { pd.second.wout_config = false; - pd.second.with_config = false; + pd.second.with_config = false; } - for (auto& rv: replaced_vers) - rv.second.replaced = false; - scratch_col = false; } @@ -8382,7 +8793,9 @@ namespace bpkg rpt_depts, add_priv_cfg, true /* initial_collection */, - replaced_vers); + replaced_vers, + postponed_dpts, + postponed_cfgs); // Collect all the prerequisites of the user selection. // @@ -8406,11 +8819,12 @@ namespace bpkg add_priv_cfg, true /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, postponed_repo, postponed_alts, 0 /* max_alt_index */, - postponed_deps, - postponed_cfgs); + postponed_deps); } else { @@ -8459,10 +8873,11 @@ namespace bpkg pkgs.collect_repointed_dependents (o, rpt_depts, replaced_vers, + postponed_dpts, + postponed_cfgs, postponed_repo, postponed_alts, postponed_deps, - postponed_cfgs, find_prereq_database, add_priv_cfg); } @@ -8481,7 +8896,10 @@ namespace bpkg if (d.available == nullptr) { - pkgs.collect_drop (ddb, ddb.load (d.name)); + pkgs.collect_drop (ddb, + ddb.load (d.name), + postponed_dpts, + postponed_cfgs); } else { @@ -8534,11 +8952,12 @@ namespace bpkg add_priv_cfg, true /* initial_collection */, replaced_vers, + postponed_dpts, + postponed_cfgs, &dep_chain, &postponed_repo, &postponed_alts, - &postponed_deps, - &postponed_cfgs); + &postponed_deps); } } @@ -8571,10 +8990,11 @@ namespace bpkg !postponed_cfgs.empty ()) pkgs.collect_build_postponed (o, replaced_vers, + postponed_dpts, + postponed_cfgs, postponed_repo, postponed_alts, postponed_deps, - postponed_cfgs, find_prereq_database, rpt_depts, add_priv_cfg); @@ -8610,6 +9030,22 @@ namespace bpkg ++i; } + // Erase + // + for (auto i (postponed_dpts.begin ()); i != postponed_dpts.end (); ) + { + if (!i->second.build) + { + l5 ([&]{trace << "erase bogus postponement of existing " + << "dependent " << i->first + << " cfg-negotiation";}); + + i = postponed_dpts.erase (i); + } + else + ++i; + } + restore_repointed_dependents (); // Commit linking of private configurations that were potentially @@ -8691,6 +9127,9 @@ namespace bpkg } } +#ifndef NDEBUG + pkgs.verify_ordering (); +#endif // Now, as we are done with package builds collecting/ordering, erase // the replacements from the repointed dependents prerequisite sets // and persist the changes. diff --git a/tests/common/dependency-alternatives/t11a/tex-0.1.0.tar.gz b/tests/common/dependency-alternatives/t11a/tex-0.1.0.tar.gz new file mode 100644 index 0000000..eb7d09f Binary files /dev/null and b/tests/common/dependency-alternatives/t11a/tex-0.1.0.tar.gz differ diff --git a/tests/common/dependency-alternatives/t11a/tex-0.2.0.tar.gz b/tests/common/dependency-alternatives/t11a/tex-0.2.0.tar.gz new file mode 100644 index 0000000..0b21183 Binary files /dev/null and b/tests/common/dependency-alternatives/t11a/tex-0.2.0.tar.gz differ diff --git a/tests/common/dependency-alternatives/t11a/tex-0.3.0.tar.gz b/tests/common/dependency-alternatives/t11a/tex-0.3.0.tar.gz new file mode 100644 index 0000000..836a032 Binary files /dev/null and b/tests/common/dependency-alternatives/t11a/tex-0.3.0.tar.gz differ diff --git a/tests/common/dependency-alternatives/t11a/tix-0.1.0.tar.gz b/tests/common/dependency-alternatives/t11a/tix-0.1.0.tar.gz new file mode 100644 index 0000000..2badf78 Binary files /dev/null and b/tests/common/dependency-alternatives/t11a/tix-0.1.0.tar.gz differ diff --git a/tests/common/dependency-alternatives/t11a/tux-1.0.0.tar.gz b/tests/common/dependency-alternatives/t11a/tux-1.0.0.tar.gz new file mode 100644 index 0000000..62c4e73 Binary files /dev/null and b/tests/common/dependency-alternatives/t11a/tux-1.0.0.tar.gz differ diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index 79cce38..fc41224 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -195,19 +195,27 @@ # | |-- buz-1.0.0.tar.gz -> bux {require {config.bux.extras=true}} # | |-- tax-1.0.0.tar.gz -> libbar {require {config.libbar.extras=true}}, # | | libfoo +# | |-- tex-0.1.0.tar.gz -> libfoo {require {config.libfoo.extras=true}} +# | |-- tex-0.2.0.tar.gz -> libbar, +# | | libfoo {require {config.libfoo.extras=true}} +# | |-- tex-0.3.0.tar.gz -> libbar {require {config.libbar.extras=true}}, +# | | libfoo {require {config.libfoo.extras=true}} # | |-- tex-1.0.0.tar.gz -> libbar {require {config.libbar.extras=true}}, # | | libfoo {require {config.libfoo.extras=true}} +# | |-- tix-0.1.0.tar.gz # | |-- tix-1.0.0.tar.gz -> libbar {require {config.libbar.extras=true}}, # | | tex {require {config.tex.extras=true}} # | |-- tiz-1.0.0.tar.gz -> tex {require {config.tex.extras=true}}, # | | libbar {require {config.libbar.extras=true}} +# | |-- toz-0.1.0.tar.gz # | |-- toz-1.0.0.tar.gz -> libbaz {require {config.libbaz.extras=true}}, # | | libfoo {require {config.libfoo.extras=true}}, # | | libbar {require {config.libbar.extras=true}} -# | |-- toz-0.1.0.tar.gz # | |-- tez-1.0.0.tar.gz -> libbox {require {config.libbox.extras=true}}, # | | toz == 0.1.0 {require {config.toz.extras=true}}, # | | libbar {require {config.libbar.extras=true}} +# | |-- tux-1.0.0.tar.gz -> libbox {require {config.libbox.extras=true}}, +# | | tix == 0.1.0 # | |-- dex-1.0.0.tar.gz -> bar {require {config.bar.extras=true}}, # | | libfoo {require {config.libfoo.extras=true}} # | |-- dix-1.0.0.tar.gz -> libbar {require {config.libbar.extras=true}}, @@ -4671,6 +4679,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end fux/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {foo fox | libfoo->{foo/1 fox/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -5062,6 +5071,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone fix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {fix | foo->{fix/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin foo/1.0.0 @@ -5113,6 +5123,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone fix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {fix | foo->{fix/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin foo/1.0.0 @@ -5127,6 +5138,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end fix/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {fix | foo->{fix/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {foo | libfoo->{foo/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -5214,22 +5226,21 @@ test.options += --no-progress { $clone_cfg; - $* foo 2>!; -#\ $* foo 2>>~%EOE%; %.* - trace: pkg_build: refine execution plan from scratch + trace: pkg_build: refine package collection/plan execution from scratch %.* trace: collect_build: add foo/1.0.0 trace: collect_build_prerequisites: begin foo/1.0.0 %.* trace: collect_build: add libfoo/1.0.0 trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent foo/1.0.0 - trace: postponed_configurations::add: create {foo | libfoo} + trace: postponed_configurations::add: create {foo | libfoo->{foo/1}} trace: collect_build_prerequisites: postpone foo/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin - trace: collect_build_postponed (1): cfg-negotiate begin {foo | libfoo} + %.* + trace: collect_build_postponed (1): cfg-negotiate begin {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 trace: collect_build_prerequisites: end libfoo/1.0.0 @@ -5238,66 +5249,73 @@ test.options += --no-progress %.* trace: collect_build_prerequisites: skip cfg-negotiated dependency libfoo/1.0.0 of dependent foo/1.0.0 trace: collect_build_prerequisites: end foo/1.0.0 - trace: collect_build_postponed (1): cfg-negotiate end {foo | libfoo} + trace: collect_build_postponed (1): cfg-negotiate end {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): end trace: collect_build_postponed (0): end trace: execute_plan: simulate: yes %.* EOE -#\ # Upgrade the dependency. # - $* ?libfoo/0.1.0 2>!; -#\ $* ?libfoo/0.1.0 2>>~%EOE%; %.* - trace: pkg_build: refine execution plan + trace: pkg_build: refine package collection/plan execution from scratch + %.* + trace: execute_plan: simulate: yes + %.* + trace: evaluate_dependency: libfoo/1.0.0: update to libfoo/0.1.0 + %.* + trace: pkg_build: refine package collection/plan execution %.* trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent foo/1.0.0 - trace: postponed_configurations::add: create { | libfoo} + trace: postponed_configurations::add: create { | libfoo->{}} trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin - trace: collect_build_postponed (1): cfg-negotiate begin { | libfoo} + %.* + trace: collect_build_postponed (1): re-evaluate existing dependents + trace: collect_build: add foo/1.0.0 + trace: postponed_configurations::add: add {foo | libfoo->{foo/1}} to { | libfoo->{}} + trace: collect_build_postponed (1): cfg-negotiate begin {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/0.1.0 trace: collect_build_prerequisites: end libfoo/0.1.0 trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents - trace: collect_build_postponed (1): cfg-negotiate end { | libfoo} + trace: collect_build_postponed (1): cfg-negotiate end {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): end trace: collect_build_postponed (0): end %.* trace: execute_plan: simulate: yes %.* EOE -#\ # Reconfigure the dependency. # - $* libfoo/0.1.0 +{ config.libfoo.extras=true } 2>!; -#\ $* libfoo/0.1.0 +{ config.libfoo.extras=true } 2>>~%EOE%; %.* - trace: pkg_build: refine execution plan from scratch + trace: pkg_build: refine package collection/plan execution from scratch %.* trace: collect_build: add libfoo/0.1.0 %.* trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent foo/1.0.0 - trace: postponed_configurations::add: create { | libfoo} + trace: postponed_configurations::add: create { | libfoo->{}} trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin - trace: collect_build_postponed (1): cfg-negotiate begin { | libfoo} + %.* + trace: collect_build_postponed (1): re-evaluate existing dependents + trace: collect_build: add foo/1.0.0 + trace: postponed_configurations::add: add {foo | libfoo->{foo/1}} to { | libfoo->{}} + trace: collect_build_postponed (1): cfg-negotiate begin {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: skip configured libfoo/0.1.0 trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents - trace: collect_build_postponed (1): cfg-negotiate end { | libfoo} + trace: collect_build_postponed (1): cfg-negotiate end {foo | libfoo->{foo/1}} trace: collect_build_postponed (1): end trace: collect_build_postponed (0): end %.* trace: execute_plan: simulate: yes %.* EOE -#\ $pkg_status -r >>EOO; !libfoo configured !0.1.0 available 1.0.0 @@ -6385,6 +6403,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6401,6 +6420,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {toz | libbaz->{toz/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbaz/1.0.0 @@ -6444,6 +6464,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6458,6 +6479,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {toz | libbaz->{toz/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbaz/1.0.0 @@ -6472,6 +6494,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone toz/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {toz | libbaz->{toz/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6508,6 +6531,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6522,6 +6546,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6562,6 +6587,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6576,6 +6602,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6590,6 +6617,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tez | libbox->{tez/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6610,6 +6638,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (0): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6624,6 +6653,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tez | libbox->{tez/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6638,6 +6668,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6658,6 +6689,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (1): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6672,6 +6704,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tez | toz->{tez/2}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tax tez | libbar->{tax/1 tez/3}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6715,6 +6748,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6731,6 +6765,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6745,6 +6780,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tez | libbox->{tez/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6765,6 +6801,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (0): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tez | libbox->{tez/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -6779,6 +6816,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tez | libbox->{tez/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6795,6 +6833,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6815,6 +6854,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (1): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tez | toz->{tez/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin toz/0.1.0 @@ -6829,6 +6869,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tez/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tez | toz->{tez/2}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tax tez | libbar->{tax/1 tez/3}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6921,6 +6962,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tex tix | libbar->{tex/1 tix/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -6987,6 +7029,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tix | libbar->{tix/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7002,6 +7045,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tix/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tix | libbar->{tix/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin tex/1.0.0 @@ -7018,6 +7062,21 @@ test.options += --no-progress EOE } + # @@ This test fails complaining about cycle introduced with tix/1.0.0. + # However 1.0.0 as an intermediate version for tix and the final + # version is 0.1.0 (as constrained by tux). Thus, the failure is + # premature. + # + #\ + : args-tex-tix-tux + : + { + $clone_cfg; + + $* tex tix tux 2>| + } + #\ + : args-tex-tiz : : Note that tiz is a correct version of tix, which fixes the @@ -7065,6 +7124,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tiz/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tiz | tex->{tiz/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin tex/1.0.0 @@ -7083,6 +7143,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tiz/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tiz | tex->{tiz/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tex tiz | libbar->{tex/1 tiz/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7102,6 +7163,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tiz/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tex tiz | libbar->{tex/1 tiz/2}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -7163,6 +7225,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tiz/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tiz | tex->{tiz/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin tex/1.0.0 @@ -7181,6 +7244,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone tiz/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tiz | tex->{tiz/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tex tiz | libbar->{tex/1 tiz/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7200,6 +7264,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tiz/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tex tiz | libbar->{tex/1 tiz/2}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -7228,6 +7293,161 @@ test.options += --no-progress $pkg_drop tiz } + + : existing + : + { + +$clone_cfg + + : negotiate + : + { + $clone_cfg; + + # Dependencies: + # + # tex: depends: libbar(c) + # depends: libfoo(c) + # + # tix: depends: libbar(c) + # depends: tex(c) + # + $* tex 2>>~%EOE%; + %.* + trace: pkg_build: refine package collection/plan execution from scratch + %.* + trace: collect_build: add tex/1.0.0 + trace: collect_build_prerequisites: begin tex/1.0.0 + %.* + trace: collect_build: add libbar/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tex/1.0.0 + trace: postponed_configurations::add: create {tex | libbar->{tex/1}} + trace: collect_build_prerequisites: postpone tex/1.0.0 + trace: collect_build_postponed (0): begin + trace: collect_build_postponed (1): begin + %.* + trace: collect_build_postponed (1): cfg-negotiate begin {tex | libbar->{tex/1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libbar/1.0.0 + trace: collect_build_prerequisites: end libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume tex/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libbar/1.0.0 of dependent tex/1.0.0 + %.* + trace: collect_build: add libfoo/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent tex/1.0.0 + trace: postponed_configurations::add: create {tex | libfoo->{tex/2}} + trace: collect_build_prerequisites: postpone tex/1.0.0 + trace: collect_build_postponed (1): cfg-negotiate end {tex | libbar->{tex/1}} + trace: collect_build_postponed (2): begin + %.* + trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/2}} + trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libfoo/1.0.0 + trace: collect_build_prerequisites: end libfoo/1.0.0 + trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume tex/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libfoo/1.0.0 of dependent tex/1.0.0 + trace: collect_build_prerequisites: end tex/1.0.0 + trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/2}} + trace: collect_build_postponed (2): end + trace: collect_build_postponed (1): end + trace: collect_build_postponed (0): end + trace: execute_plan: simulate: yes + %.* + EOE + + # Configuration clusters: + # + # {tix | libbar->{tix/1}} + # {tix | tex->{tix/2}} + # + # Fail at: + # + # tex -> libbar + # + $* tix 2>>~%EOE% != 0; + %.* + trace: pkg_build: refine package collection/plan execution from scratch + %.* + trace: collect_build: add tix/1.0.0 + trace: collect_build_prerequisites: begin tix/1.0.0 + %.* + trace: collect_build: add libbar/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tix/1.0.0 + trace: postponed_configurations::add: create {tix | libbar->{tix/1}} + trace: collect_build_prerequisites: postpone tix/1.0.0 + trace: collect_build_postponed (0): begin + trace: collect_build_postponed (1): begin + %.* + trace: collect_build_postponed (1): re-evaluate existing dependents + trace: collect_build: add tex/1.0.0 + trace: postponed_configurations::add: add {tex | libbar->{tex/1}} to {tix | libbar->{tix/1}} + trace: collect_build_postponed (1): cfg-negotiate begin {tex tix | libbar->{tex/1 tix/1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: skip configured libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume tix/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libbar/1.0.0 of dependent tix/1.0.0 + %.* + trace: collect_build: cannot collect prematurely cfg-negotiated existing dependent tex, throwing + trace: pkg_build: collection failed due to prematurely cfg-negotiated existing dependent, retry from scratch + %.* + trace: pkg_build: refine package collection/plan execution from scratch + %.* + trace: collect_build: add tix/1.0.0 + trace: collect_build_prerequisites: begin tix/1.0.0 + %.* + trace: collect_build: add libbar/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tix/1.0.0 + trace: postponed_configurations::add: create {tix | libbar->{tix/1}} + trace: collect_build_prerequisites: postpone tix/1.0.0 + trace: collect_build_postponed (0): begin + trace: collect_build_postponed (1): begin + %.* + trace: collect_build_postponed (1): cfg-negotiate begin {tix | libbar->{tix/1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: skip configured libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume tix/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libbar/1.0.0 of dependent tix/1.0.0 + %.* + trace: collect_build: add tex/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency tex/1.0.0 of dependent tix/1.0.0 + trace: postponed_configurations::add: create {tix | tex->{tix/2}} + trace: collect_build_prerequisites: postpone tix/1.0.0 + trace: collect_build_postponed (1): cfg-negotiate end {tix | libbar->{tix/1}} + trace: collect_build_postponed (2): begin + %.* + trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2}} + trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin tex/1.0.0 + %.* + trace: collect_build_prerequisites: cannot cfg-postpone dependency libbar/1.0.0 of dependent tex/1.0.0 (collected prematurely), checking for configuration cycle + trace: collect_build_prerequisites: negotiated: {tix | libbar->{tix/1}} + trace: collect_build_prerequisites: being negotiated: {tix | tex->{tix/2}} + trace: postponed_configurations::add: add {tex | libbar->{tex/1}} to {tix | libbar->{tix/1}} + trace: collect_build_prerequisites: verifying {tex tix | libbar->{tex/1 tix/1}} + error: package tix/1.0.0 negotiates configuration of libbar/1.0.0 before its (potentially indirect) dependency tex/1.0.0 negotiates configuration of libbar/1.0.0 + info: consider reordering dependencies of tix/1.0.0 + %.* + EOE + + # @@ These tests fail complaining on tix/1.0.0->tex/1.0.0 cycle. + # However, we downgrade tex to 0.1.0 or 0.2.0 for which there + # is no cycle (0.2.0 depends on libbar without config clause and + # 0.1.0 doesn't depend at all). + # + #$* tix ?tex/0.1.0 2>|; + #$* tix ?tex/0.2.0 2>|; + + $pkg_drop tex + } + } } : indirect @@ -7294,6 +7514,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {dix tax | libbar->{dix/1 tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7318,6 +7539,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {dix tax | libbar->{dix/1 tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7331,6 +7553,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (0): cfg-negotiation of {dix tax | libbar->{dix/1 tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7349,6 +7572,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dex/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {dex | bar->{dex/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {bar dix tax | libbar->{bar/1 dix/1 tax/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7374,6 +7598,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {bar dix tax | libbar->{bar/1 dix/1 tax/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {dex | libfoo->{dex/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -7385,6 +7610,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dex/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {dex | libfoo->{dex/2}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {dix | libbox->{dix/2}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7400,6 +7626,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dix/1.0.0 trace: collect_build_postponed (4): cfg-negotiate end {dix | libbox->{dix/2}} trace: collect_build_postponed (5): begin + %.* trace: collect_build_postponed (5): cfg-negotiate begin {dix | dox->{dix/3}} trace: collect_build_postponed (5): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -7465,6 +7692,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dix/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {dix | libbar->{dix/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7480,6 +7708,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dix/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {dix | libbar->{dix/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {dix | libbox->{dix/2}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7495,6 +7724,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dix/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {dix | libbox->{dix/2}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {dix | dox->{dix/3}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -7510,6 +7740,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dix/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {dix | dox->{dix/3}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {dox | dex->{dox/1}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dex/1.0.0 @@ -7525,6 +7756,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dox/1.0.0 trace: collect_build_postponed (4): cfg-negotiate end {dox | dex->{dox/1}} trace: collect_build_postponed (5): begin + %.* trace: collect_build_postponed (5): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (5): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7595,6 +7827,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7611,6 +7844,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7624,6 +7858,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (0): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7642,6 +7877,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dex/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {dex | bar->{dex/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {bar tax | libbar->{bar/1 tax/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7659,6 +7895,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {bar tax | libbar->{bar/1 tax/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {diz | dox->{diz/1}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -7694,6 +7931,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7708,6 +7946,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {diz | dox->{diz/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -7726,6 +7965,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {diz | dox->{diz/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {dox | dex->{dox/1}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dex/1.0.0 @@ -7741,6 +7981,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dox/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {dox | dex->{dox/1}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {diz | libbox->{diz/2}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7763,6 +8004,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (0): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {diz | dox->{diz/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -7781,6 +8023,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {diz | dox->{diz/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7795,6 +8038,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {dox | dex->{dox/1}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dex/1.0.0 @@ -7810,6 +8054,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dox/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {dox | dex->{dox/1}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {diz | libbox->{diz/2}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7832,6 +8077,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (1): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {dox | dex->{dox/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dex/1.0.0 @@ -7847,6 +8093,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dox/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {dox | dex->{dox/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {tax | libbar->{tax/1}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7861,6 +8108,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {tax | libbar->{tax/1}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {diz | libbox->{diz/2}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7883,6 +8131,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (2): cfg-negotiation of {tax | libbar->{tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {diz | libbox->{diz/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -7897,6 +8146,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {diz | libbox->{diz/2}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {diz tax | libbar->{diz/3 tax/1}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7915,6 +8165,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (4): cfg-negotiate end {diz tax | libbar->{diz/3 tax/1}} trace: collect_build_postponed (5): begin + %.* trace: collect_build_postponed (5): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (5): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7934,6 +8185,7 @@ test.options += --no-progress trace: collect_build_prerequisites: no configuration cycle, throwing trace: collect_build_postponed (3): cfg-negotiation of {diz tax | libbar->{diz/3 tax/1}} failed due to dependency libbar, try next trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -7952,6 +8204,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dex/1.0.0 trace: collect_build_postponed (4): cfg-negotiate end {dex | bar->{dex/1}} trace: collect_build_postponed (5): begin + %.* trace: collect_build_postponed (5): cfg-negotiate begin {bar diz tax | libbar->{bar/1 diz/3 tax/1}} trace: collect_build_postponed (5): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -7973,6 +8226,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end tax/1.0.0 trace: collect_build_postponed (5): cfg-negotiate end {bar diz tax | libbar->{bar/1 diz/3 tax/1}} trace: collect_build_postponed (6): begin + %.* trace: collect_build_postponed (6): cfg-negotiate begin {dex | libfoo->{dex/2}} trace: collect_build_postponed (6): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -8049,6 +8303,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (0): begin trace: collect_build_postponed (1): begin + %.* trace: collect_build_postponed (1): cfg-negotiate begin {diz | dox->{diz/1}} trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dox/1.0.0 @@ -8068,6 +8323,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (1): cfg-negotiate end {diz | dox->{diz/1}} trace: collect_build_postponed (2): begin + %.* trace: collect_build_postponed (2): cfg-negotiate begin {dox | dex->{dox/1}} trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin dex/1.0.0 @@ -8083,6 +8339,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end dox/1.0.0 trace: collect_build_postponed (2): cfg-negotiate end {dox | dex->{dox/1}} trace: collect_build_postponed (3): begin + %.* trace: collect_build_postponed (3): cfg-negotiate begin {diz | libbox->{diz/2}} trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbox/1.0.0 @@ -8098,6 +8355,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone diz/1.0.0 trace: collect_build_postponed (3): cfg-negotiate end {diz | libbox->{diz/2}} trace: collect_build_postponed (4): begin + %.* trace: collect_build_postponed (4): cfg-negotiate begin {dex | bar->{dex/1}} trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin bar/1.0.0 @@ -8116,6 +8374,7 @@ test.options += --no-progress trace: collect_build_prerequisites: postpone dex/1.0.0 trace: collect_build_postponed (4): cfg-negotiate end {dex | bar->{dex/1}} trace: collect_build_postponed (5): begin + %.* trace: collect_build_postponed (5): cfg-negotiate begin {bar diz | libbar->{bar/1 diz/3}} trace: collect_build_postponed (5): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libbar/1.0.0 @@ -8131,6 +8390,7 @@ test.options += --no-progress trace: collect_build_prerequisites: end diz/1.0.0 trace: collect_build_postponed (5): cfg-negotiate end {bar diz | libbar->{bar/1 diz/3}} trace: collect_build_postponed (6): begin + %.* trace: collect_build_postponed (6): cfg-negotiate begin {dex | libfoo->{dex/2}} trace: collect_build_postponed (6): recursively collect cfg-negotiated dependencies trace: collect_build_prerequisites: begin libfoo/1.0.0 @@ -8165,6 +8425,125 @@ test.options += --no-progress $pkg_drop diz } + + : existing + : + { + +$clone_cfg + + : negotiate + : + { + $clone_cfg; + + # Dependencies: + # + # dex: depends: bar(c) + # depends: libfoo(c) + # + # bar: depends: libbar(c) + # + # dix: depends: libbar(c) + # depends: libbox(c) # causes postponment and initial cluster finished negotiating + # depends: dox(c) + # + # dox: dex(c) + # + $* dex 2>!; + + # @@ Here we would expect to fail due to the config cycle but we + # don't. + # + # Fail at: + # + # + #\ + $* dix 2>>~%EOE% != 0; + %.* + trace: pkg_build: refine package collection/plan execution from scratch + %.* + trace: collect_build: add dix/1.0.0 + trace: collect_build_prerequisites: begin dix/1.0.0 + %.* + trace: collect_build: add libbar/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent dix/1.0.0 + trace: postponed_configurations::add: create {dix | libbar->{dix/1}} + trace: collect_build_prerequisites: postpone dix/1.0.0 + trace: collect_build_postponed (0): begin + trace: collect_build_postponed (1): begin + %.* + trace: collect_build_postponed (1): re-evaluate existing dependents + trace: collect_build: add bar/1.0.0 + trace: postponed_configurations::add: add {bar | libbar->{bar/1}} to {dix | libbar->{dix/1}} + trace: collect_build_postponed (1): cfg-negotiate begin {bar dix | libbar->{bar/1 dix/1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: skip configured libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume dix/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libbar/1.0.0 of dependent dix/1.0.0 + %.* + trace: collect_build: add libbox/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libbox/1.0.0 of dependent dix/1.0.0 + trace: postponed_configurations::add: create {dix | libbox->{dix/2}} + trace: collect_build_prerequisites: postpone dix/1.0.0 + trace: collect_build_postponed (1): cfg-negotiate end {bar dix | libbar->{bar/1 dix/1}} + trace: collect_build_postponed (2): begin + %.* + trace: collect_build_postponed (2): cfg-negotiate begin {dix | libbox->{dix/2}} + trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libbox/1.0.0 + trace: collect_build_prerequisites: end libbox/1.0.0 + trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume dix/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency libbox/1.0.0 of dependent dix/1.0.0 + %.* + trace: collect_build: add dox/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency dox/1.0.0 of dependent dix/1.0.0 + trace: postponed_configurations::add: create {dix | dox->{dix/3}} + trace: collect_build_prerequisites: postpone dix/1.0.0 + trace: collect_build_postponed (2): cfg-negotiate end {dix | libbox->{dix/2}} + trace: collect_build_postponed (3): begin + %.* + trace: collect_build_postponed (3): cfg-negotiate begin {dix | dox->{dix/3}} + trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin dox/1.0.0 + %.* + trace: collect_build: add dex/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency dex/1.0.0 of dependent dox/1.0.0 + trace: postponed_configurations::add: create {dox | dex->{dox/1}} + trace: collect_build_prerequisites: postpone dox/1.0.0 + trace: collect_build_postponed (3): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume dix/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency dox/1.0.0 of dependent dix/1.0.0 + trace: collect_build_prerequisites: end dix/1.0.0 + trace: collect_build_postponed (3): cfg-negotiate end {dix | dox->{dix/3}} + trace: collect_build_postponed (4): begin + %.* + trace: collect_build_postponed (4): cfg-negotiate begin {dox | dex->{dox/1}} + trace: collect_build_postponed (4): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: skip configured dex/1.0.0 + trace: collect_build_postponed (4): recursively collect cfg-negotiated dependents + trace: collect_build_prerequisites: resume dox/1.0.0 + %.* + trace: collect_build_prerequisites: skip cfg-negotiated dependency dex/1.0.0 of dependent dox/1.0.0 + trace: collect_build_prerequisites: end dox/1.0.0 + trace: collect_build_postponed (4): cfg-negotiate end {dox | dex->{dox/1}} + trace: collect_build_postponed (4): end + trace: collect_build_postponed (3): end + trace: collect_build_postponed (2): end + trace: collect_build_postponed (1): end + trace: collect_build_postponed (0): end + trace: execute_plan: simulate: yes + %.* + EOE + #\ + + $pkg_drop dex + } + } } } } -- cgit v1.1