aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-08-08 15:28:25 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-09-25 11:35:25 +0300
commitbbf4d75525f54a41ebf38608c193f5787128c590 (patch)
treef66707abaaf18d15b339615fcfd24a56278b079a
parent6f40a051db7ef6c42c4856f0608ce1dad4fcf609 (diff)
Fix configuration negotiation in pkg-build to re-evaluate being reconfigured existing dependents
-rw-r--r--bpkg/package.cxx12
-rw-r--r--bpkg/package.hxx60
-rw-r--r--bpkg/package.xml24
-rw-r--r--bpkg/pkg-build-collect.cxx2105
-rw-r--r--bpkg/pkg-build-collect.hxx314
-rw-r--r--bpkg/pkg-build.cxx142
-rw-r--r--bpkg/pkg-configure.cxx91
-rw-r--r--bpkg/pkg-configure.hxx18
-rw-r--r--bpkg/pkg-disfigure.cxx5
-rw-r--r--tests/common/dependency-alternatives/t11a/biz-0.1.0.tar.gzbin0 -> 416 bytes
-rw-r--r--tests/common/dependency-alternatives/t11a/bus-0.1.0.tar.gzbin0 -> 448 bytes
-rw-r--r--tests/common/dependency-alternatives/t11a/libbiz-0.1.0.tar.gzbin0 -> 401 bytes
-rw-r--r--tests/common/dependency-alternatives/t11a/libbiz-1.0.0.tar.gzbin0 -> 409 bytes
-rw-r--r--tests/common/dependency-alternatives/t8a/tpx-1.0.0.tar.gzbin0 -> 496 bytes
-rw-r--r--tests/common/dependency-alternatives/t8a/twx-1.0.0.tar.gzbin0 -> 431 bytes
-rw-r--r--tests/pkg-build.testscript1396
16 files changed, 2321 insertions, 1846 deletions
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index 56f4221..aca3550 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -296,12 +296,18 @@ namespace bpkg
// The package is in at least fetched state, which means we should
// be able to get its manifest.
//
- const optional<path>& a (sp->archive);
-
+ // @@ PERF We should probably implement the available package caching not
+ // to parse the same manifests multiple times during all that build
+ // plan refinement iterations. What should be the cache key? Feels like
+ // it should be the archive/directory path. Note that the package
+ // manifests can potentially differ in different external package
+ // directories for the same version iteration. Testing showed 6%
+ // speedup on tests (debug/sanitized).
+ //
package_manifest m (
sp->state == package_state::fetched
? pkg_verify (options,
- a->absolute () ? *a : db.config_orig / *a,
+ sp->effective_archive (db.config_orig),
true /* ignore_unknown */,
false /* ignore_toolchain */,
false /* expand_values */,
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 947393b..06278cd 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -32,7 +32,7 @@
//
#define DB_SCHEMA_VERSION_BASE 12
-#pragma db model version(DB_SCHEMA_VERSION_BASE, 24, closed)
+#pragma db model version(DB_SCHEMA_VERSION_BASE, 25, closed)
namespace bpkg
{
@@ -1086,37 +1086,9 @@ namespace bpkg
//
optional<version_constraint> constraint;
- // Position of the first dependency alternative with a configuration
- // clause, if any.
- //
- // Specifically, if there is such an alternative then this is a pair of
- // 1-based indexes of the respective depends value (first) and the
- // dependency alternative (second) in the dependent's manifest. Otherwise,
- // this is a pair of zeros.
- //
- // For example, for the following dependent the position for libfoo/1.2.0
- // prerequisite will be {2,2}:
- //
- // libbar: depends: libfoo >= 1.1.0
- // depends: libfox | libfoo >= 1.2.0 {require {...}}
- //
- pair<size_t, size_t> config_position;
-
// Database mapping.
//
#pragma db member(constraint) column("")
-
- #pragma db member(config_position) transient
-
- #pragma db member(config_dependency_index) \
- virtual(size_t) \
- access(config_position.first) \
- default(0)
-
- #pragma db member(config_alternative_index) \
- virtual(size_t) \
- access(config_position.second) \
- default(0)
};
// Note that the keys for this map need to be created with the database
@@ -1265,6 +1237,16 @@ namespace bpkg
package_prerequisites prerequisites;
+ // 1-based indexes of the selected dependency alternatives which the
+ // prerequisite packages are resolved from. Parallel to the dependencies
+ // member of the respective available package. Entries which don't
+ // correspond to a selected alternative (toolchain build-time dependency,
+ // not enabled alternatives, etc) are set to 0.
+ //
+ using indexes_type = vector<size_t>; // Make sure ODB maps it portably.
+ indexes_type dependency_alternatives;
+ odb::section dependency_alternatives_section;
+
// Project configuration variable names and their sources.
//
vector<config_variable> config_variables;
@@ -1363,6 +1345,11 @@ namespace bpkg
#pragma db member(prerequisites) id_column("package") \
key_column("") value_column("")
+ #pragma db member(dependency_alternatives) id_column("package") \
+ value_column("position") section(dependency_alternatives_section)
+
+ #pragma db member(dependency_alternatives_section) load(lazy) update(always)
+
#pragma db member(config_variables) id_column("package") value_column("")
// For the sake of simplicity let's not calculate the checksum during
@@ -1595,21 +1582,6 @@ namespace bpkg
#pragma db column("pp.package")
package_name name;
- #pragma db transient
- pair<size_t, size_t> config_position;
-
- #pragma db member(config_dependency_index) \
- column("pp.config_dependency_index") \
- virtual(size_t) \
- access(config_position.first) \
- default(0)
-
- #pragma db member(config_alternative_index) \
- column("pp.config_alternative_index") \
- virtual(size_t) \
- access(config_position.second) \
- default(0)
-
#pragma db column("pp.")
optional<version_constraint> constraint;
};
diff --git a/bpkg/package.xml b/bpkg/package.xml
index 343f27a..07595af 100644
--- a/bpkg/package.xml
+++ b/bpkg/package.xml
@@ -1,4 +1,28 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
+ <changeset version="25">
+ <alter-table name="main.selected_package_prerequisites">
+ <drop-column name="config_dependency_index"/>
+ <drop-column name="config_alternative_index"/>
+ </alter-table>
+ <add-table name="main.selected_package_dependency_alternatives" kind="container">
+ <column name="package" type="TEXT" null="true" options="COLLATE NOCASE"/>
+ <column name="index" type="INTEGER" null="true"/>
+ <column name="position" type="INTEGER" null="true"/>
+ <foreign-key name="package_fk" on-delete="CASCADE">
+ <column name="package"/>
+ <references table="main.selected_package">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ <index name="selected_package_dependency_alternatives_package_i">
+ <column name="package"/>
+ </index>
+ <index name="selected_package_dependency_alternatives_index_i">
+ <column name="index"/>
+ </index>
+ </add-table>
+ </changeset>
+
<changeset version="24">
<alter-table name="main.selected_package">
<add-column name="config_checksum" type="TEXT" null="true" default="''"/>
diff --git a/bpkg/pkg-build-collect.cxx b/bpkg/pkg-build-collect.cxx
index d08f0f8..a52bba5 100644
--- a/bpkg/pkg-build-collect.cxx
+++ b/bpkg/pkg-build-collect.cxx
@@ -102,6 +102,7 @@ namespace bpkg
return !system &&
(dependencies ||
selected->version != available_version () ||
+ (flags & build_recollect) != 0 ||
((!config_vars.empty () || skeleton) &&
has_buildfile_clause (available->dependencies)) ||
rpt_depts.find (package_key (db, name ())) != rpt_depts.end ());
@@ -119,6 +120,7 @@ namespace bpkg
(selected->system () != system ||
selected->version != available_version () ||
replace () ||
+ (flags & build_recollect) != 0 ||
(!system && (!config_vars.empty () || disfigure)))));
}
@@ -342,7 +344,9 @@ namespace bpkg
package_skeleton& build_package::
init_skeleton (const common_options& options,
- const shared_ptr<available_package>& override)
+ const shared_ptr<available_package>& override,
+ optional<dir_path> src_root,
+ optional<dir_path> out_root)
{
shared_ptr<available_package> ap (override != nullptr
? override
@@ -365,9 +369,7 @@ namespace bpkg
ap = nullptr;
}
- optional<dir_path> src_root, out_root;
-
- if (ap != nullptr)
+ if (!src_root && ap != nullptr)
{
src_root = external_dir ();
out_root = (src_root && !disfigure
@@ -613,26 +615,6 @@ namespace bpkg
return false;
}
- const pair<size_t, size_t>* postponed_configuration::
- existing_dependent_position (const package_key& p) const
- {
- const pair<size_t, size_t>* r (nullptr);
-
- auto i (dependents.find (p));
- if (i != dependents.end () && i->second.existing)
- {
- for (const dependency& d: i->second.dependencies)
- {
- if (r == nullptr || d.position < *r)
- r = &d.position;
- }
-
- assert (r != nullptr);
- }
-
- return r;
- }
-
void postponed_configuration::
merge (postponed_configuration&& c)
{
@@ -653,10 +635,6 @@ namespace bpkg
for (dependency& sd: sdi.dependencies)
ddi.add (move (sd));
-
- // As in add() above.
- //
- assert (ddi.existing || !sdi.existing);
}
else
dependents.emplace (d.first, move (d.second));
@@ -1164,17 +1142,18 @@ namespace bpkg
build_package* build_packages::
collect_build (const pkg_build_options& options,
build_package pkg,
- const function<find_database_function>& fdb,
- const repointed_dependents& rpt_depts,
- const function<add_priv_cfg_function>& apc,
- bool initial_collection,
replaced_versions& replaced_vers,
postponed_configurations& postponed_cfgs,
build_package_refs* dep_chain,
+ bool initial_collection,
+ const function<find_database_function>& fdb,
+ const function<add_priv_cfg_function>& apc,
+ const repointed_dependents* rpt_depts,
postponed_packages* postponed_repo,
postponed_packages* postponed_alts,
+ postponed_packages* postponed_recs,
+ postponed_existing_dependencies* postponed_edeps,
postponed_dependencies* postponed_deps,
- postponed_positions* postponed_poss,
unacceptable_alternatives* unacceptable_alts,
const function<verify_package_build_function>& vpb)
{
@@ -1188,10 +1167,13 @@ namespace bpkg
// See the above notes.
//
bool recursive (dep_chain != nullptr);
- assert ((postponed_repo != nullptr) == recursive &&
+ assert ((fdb != nullptr) == recursive &&
+ (rpt_depts != nullptr) == recursive &&
+ (postponed_repo != nullptr) == recursive &&
(postponed_alts != nullptr) == recursive &&
+ (postponed_recs != nullptr) == recursive &&
+ (postponed_edeps != nullptr) == recursive &&
(postponed_deps != nullptr) == recursive &&
- (postponed_poss != nullptr) == recursive &&
(unacceptable_alts != nullptr) == recursive);
// Only builds are allowed here.
@@ -1391,7 +1373,7 @@ namespace bpkg
// altogether if we are the only dependent (so that it doesn't
// influence any subsequent dependent) or (2) making sure our
// constraint is a sub-constraint of any other constraint and
- // removing it from the dependency build_package. Maybe/later.
+ // removing it from the dependency build_package. Maybe/later.
//
// NOTE: remember to update collect_drop() if changing anything
// here.
@@ -1445,7 +1427,13 @@ namespace bpkg
auto i (cfg.dependents.find (pk));
if (i != cfg.dependents.end () && i->second.existing)
+ {
+ l5 ([&]{trace << "existing dependent " << *pkg.selected << pkg.db
+ << " needs to be replaced with "
+ << pkg.available_name_version_db ();});
+
replace_ver (pkg);
+ }
}
}
@@ -1484,40 +1472,42 @@ namespace bpkg
if (recursive)
collect_build_prerequisites (options,
p,
+ *dep_chain,
+ initial_collection,
fdb,
- rpt_depts,
apc,
- initial_collection,
+ *rpt_depts,
replaced_vers,
- *dep_chain,
postponed_repo,
postponed_alts,
0 /* max_alt_index */,
+ *postponed_recs,
+ *postponed_edeps,
*postponed_deps,
postponed_cfgs,
- *postponed_poss,
*unacceptable_alts);
return &p;
}
- void build_packages::
+ optional<vector<postponed_configuration::dependency>> build_packages::
collect_build_prerequisites (const pkg_build_options& options,
build_package& pkg,
+ build_package_refs& dep_chain,
+ bool initial_collection,
const function<find_database_function>& fdb,
- const repointed_dependents& rpt_depts,
const function<add_priv_cfg_function>& apc,
- bool initial_collection,
+ const repointed_dependents& rpt_depts,
replaced_versions& replaced_vers,
- build_package_refs& dep_chain,
postponed_packages* postponed_repo,
postponed_packages* postponed_alts,
size_t max_alt_index,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies& postponed_edeps,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
- postponed_positions& postponed_poss,
unacceptable_alternatives& unacceptable_alts,
- pair<size_t, size_t> reeval_pos)
+ optional<pair<size_t, size_t>> reeval_pos)
{
// NOTE: don't forget to update collect_build_postponed() if changing
// anything in this function.
@@ -1530,21 +1520,25 @@ namespace bpkg
database& pdb (pkg.db);
package_key pk (pdb, nm);
- bool reeval (reeval_pos.first != 0);
+ bool pre_reeval (reeval_pos && reeval_pos->first == 0);
+ assert (!pre_reeval || reeval_pos->second == 0);
+
+ bool reeval (reeval_pos && reeval_pos->first != 0);
+ assert (!reeval || reeval_pos->second != 0);
- // The being re-evaluated dependent cannot be recursively collected yet.
- // Also, we don't expect it being configured as system.
+ // The being (pre-)re-evaluated dependent cannot be recursively collected
+ // yet. Also, we don't expect it being configured as system.
//
// Note that the configured package can still be re-evaluated after
// collect_build_prerequisites() has been called but didn't end up with
// the recursive collection.
//
- assert (!reeval ||
+ assert ((!pre_reeval && !reeval) ||
((!pkg.recursive_collection ||
!pkg.recollect_recursively (rpt_depts)) &&
!pkg.skeleton && !pkg.system));
- // If this package is not being re-evaluated, is not yet collected
+ // If this package is not being (pre-)re-evaluated, is not yet collected
// recursively, needs to be reconfigured, and is not yet postponed, then
// check if it is a dependency of any dependent with configuration clause
// and postpone the collection if that's the case.
@@ -1554,200 +1548,142 @@ namespace bpkg
// otherwise built (e.g., reconfigured) which means its externally-
// imposed configuration (user, dependents) is not being changed.
//
- if (!reeval &&
- !pkg.recursive_collection &&
- pkg.reconfigure () &&
- postponed_cfgs.find_dependency (pk) == nullptr)
+ if (!pre_reeval &&
+ !reeval &&
+ !pkg.recursive_collection &&
+ pkg.reconfigure () &&
+ postponed_cfgs.find_dependency (pk) == nullptr &&
+ postponed_edeps.find (pk) == postponed_edeps.end ())
{
- // If the dependent is being built, then check if it was re-evaluated to
- // the position greater than the dependency position. Return true if
- // that's the case, so this package is added to the resulting list and
- // we can handle this situation below.
- //
- // Note that we rely on "small function object" optimization here.
- //
- const function<verify_dependent_build_function> verify (
- [&postponed_cfgs]
- (const package_key& pk, pair<size_t, size_t> pos)
- {
- for (const postponed_configuration& cfg: postponed_cfgs)
- {
- if (cfg.negotiated)
- {
- if (const pair<size_t, size_t>* p =
- cfg.existing_dependent_position (pk))
- {
- if (p->first > pos.first)
- return true;
- }
- }
- }
-
- return false;
- });
-
// Note that there can be multiple existing dependents for a dependency.
- // Strictly speaking, we only need to add the first one with the
- // assumption that the remaining dependents will also be considered
- // comes the time for the negotiation. Let's, however, process all of
- // them to detect the potential "re-evaluation on the greater dependency
- // index" situation earlier. And, generally, have as much information as
- // possible up front.
//
vector<existing_dependent> eds (
query_existing_dependents (trace,
+ options,
pk.db,
pk.name,
- replaced_vers,
+ fdb,
rpt_depts,
- verify));
+ replaced_vers));
if (!eds.empty ())
{
+ bool postpone (false);
+
for (existing_dependent& ed: eds)
{
- package_key dpt (ed.db, ed.selected->name);
- package_key dep (pk);
-
- size_t& di (ed.dependency_position.first);
-
- const build_package* bp (&pkg);
-
- // Check if this dependent needs to be re-evaluated to an earlier
- // dependency position and, if that's the case, create the
- // configuration cluster with this dependency instead.
- //
- // Note that if the replace flag is false, we proceed normally with
- // the assumption that the dependency referred by the entry will be
- // collected later and its configuration cluster will be created
- // normally and will be negotiated earlier than the cluster being
- // created for the current dependency (see collect_build_postponed()
- // for details).
- //
+ if (ed.dependency) // Configuration clause is encountered.
{
- auto pi (postponed_poss.find (dpt));
+ const build_package* bp (&pkg);
- if (pi != postponed_poss.end () && pi->second.first < di)
+ package_key& dep (*ed.dependency);
+ package_key dpt (ed.db, ed.selected->name);
+
+ // If the earliest configuration clause applies to a different
+ // dependency, then collect it (non-recursively).
+ //
+ if (dep != pk)
+ bp = collect_existing_dependent_dependency (options,
+ ed,
+ replaced_vers,
+ postponed_cfgs);
+
+ // Indicate that the dependent with configuration clauses is
+ // present.
+ //
{
- // If requested, override the first encountered non-replace
- // position to replace. See collect_build_postponed () for
- // details.
- //
- if (!pi->second.replace && postponed_poss.replace)
- {
- pi->second.replace = true;
- postponed_poss.replace = false;
- }
+ auto i (postponed_deps.find (dep));
- if (pi->second.replace)
+ // Do not override postponements recorded during postponed
+ // collection phase with those recorded during initial
+ // phase.
+ //
+ if (i == postponed_deps.end ())
{
- // Overwrite the existing dependent dependency information and
- // fall through to proceed as for the normal case.
- //
- bp = replace_existing_dependent_dependency (
- trace,
- options,
- ed, // Note: modified.
- pi->second,
- fdb,
- rpt_depts,
- apc,
- initial_collection,
- replaced_vers,
- postponed_cfgs);
-
- dep = package_key (bp->db, bp->name ());
-
- // Note that here we side-step the bogus logic (by not setting
- // the skipped flag) because in this case (replace=true) our
- // choices are either (potentially) bogus or pathological
- // (where we have evaluated too far). In other words, the
- // postponed entry may cause the depends entry that triggered
- // it to disappear (and thus, strictly speaking, to become
- // bogus) but if we cancel it, we will be back to square one.
+ postponed_deps.emplace (dep,
+ postponed_dependency {
+ false /* without_config */,
+ true /* with_config */,
+ initial_collection});
}
+ else
+ i->second.with_config = true;
}
- }
- // Make sure that this existing dependent doesn't belong to any
- // (being) negotiated configuration cluster with a greater
- // dependency index. That would mean that this dependent has already
- // been re-evaluated to this index and so cannot participate in the
- // configuration negotiation of this earlier dependency.
- //
- for (const postponed_configuration& cfg: postponed_cfgs)
- {
- if (const pair<size_t, size_t>* p =
- cfg.existing_dependent_position (dpt))
+ // Prematurely collected before we saw any config clauses.
+ //
+ if (bp->recursive_collection)
{
- size_t ei (p->first);
-
- if (di < ei && cfg.negotiated)
- {
- // Feels like there cannot be an earlier position.
- //
- postponed_position pp (ed.dependency_position,
- false /* replace */);
+ l5 ([&]{trace << "cannot cfg-postpone dependency "
+ << bp->available_name_version_db ()
+ << " of existing dependent " << dpt
+ << " (collected prematurely), "
+ << "throwing postpone_dependency";});
- auto p (postponed_poss.emplace (move (dpt), pp));
- if (!p.second)
- {
- assert (p.first->second > pp);
- p.first->second = pp;
- }
-
- l5 ([&]{trace << "cannot cfg-postpone dependency "
- << bp->available_name_version_db ()
- << " of existing dependent " << *ed.selected
- << ed.db << " (index " << di
- << ") due to earlier dependency index " << ei
- << " in " << cfg << ", throwing "
- << "postpone_position";});
+ // Don't print the "while satisfying..." chain.
+ //
+ dep_chain.clear ();
- // Don't print the "while satisfying..." chain.
- //
- dep_chain.clear ();
+ throw postpone_dependency (move (dep));
+ }
- throw postpone_position ();
- }
+ l5 ([&]{trace << "cfg-postpone dependency "
+ << bp->available_name_version_db ()
+ << " of existing dependent " << *ed.selected
+ << ed.db << " due to dependency "
+ << pkg.available_name_version_db ();});
- if (di == ei)
- {
- // For the negotiated cluster all the dependency packages
- // should have been added. For non-negotiated cluster we
- // cannot add the missing dependencies at the moment and will
- // do it as a part of the dependent re-evaluation.
- //
- assert (!cfg.negotiated);
- }
- }
+ // Only add this dependent/dependency to the newly created cluster
+ // if this dependency doesn't belong to any cluster yet, which may
+ // not be the case if there are multiple existing dependents with
+ // configuration clause for this dependency.
+ //
+ // To put it another way, if there are multiple such existing
+ // dependents for this dependency, here we will create the
+ // configuration cluster only for the first one. The remaining
+ // dependents will be added to this dependency's cluster when the
+ // existing dependents of dependencies in this cluster are all
+ // discovered and reevaluated (see collect_build_postponed() for
+ // details).
+ //
+ if (postponed_cfgs.find_dependency (dep) == nullptr)
+ postponed_cfgs.add (move (dpt),
+ ed.dependency_position,
+ move (dep));
+ }
+ else // Existing dependent is deviated.
+ {
+ // Note that we could probably re-collect deviated dependents
+ // recursively right away but such a two-directional recursion
+ // would complicate implementation and troubleshooting. Thus,
+ // given that the deviated dependents are not very common, we just
+ // postpone their re-collection.
+ //
+ collect_deviated_dependent (options,
+ ed,
+ pk,
+ replaced_vers,
+ postponed_recs,
+ postponed_cfgs);
}
- l5 ([&]{trace << "cfg-postpone dependency "
- << bp->available_name_version_db ()
- << " of existing dependent " << *ed.selected
- << ed.db;});
-
- // Only add this dependent/dependency to the newly created cluster
- // if this dependency doesn't belong to any cluster yet, which may
- // not be the case if there are multiple existing dependents with
- // configuration clause for this dependency.
+ // Postpone the original dependency recursive collection if the
+ // existing dependent has deviated or the dependency belongs to the
+ // earliest depends clause with configuration clause or to some
+ // later depends clause. It is supposed that it will be collected
+ // during its existing dependent re-collection.
//
- // To put it another way, if there are multiple such an existing
- // dependents for this dependency, here we will create the
- // configuration cluster only for the first one. The remaining
- // dependents will be added to this dependency's cluster when the
- // existing dependents of dependencies in this cluster are all
- // discovered and reevaluated (see collect_build_postponed() for
- // details).
- //
- if (postponed_cfgs.find_dependency (dep) == nullptr)
- postponed_cfgs.add (move (dpt),
- ed.dependency_position,
- move (dep));
+ if (!ed.dependency || // Dependent has deviated.
+ !ed.orig_dependency_position || // Later depends clause.
+ *ed.orig_dependency_position == ed.dependency_position)
+ {
+ postpone = true;
+ postponed_edeps[pk].emplace_back (ed.db, ed.selected->name);
+ }
}
- return;
+ if (postpone)
+ return nullopt;
}
}
@@ -1756,7 +1692,7 @@ namespace bpkg
if (pkg.system)
{
l5 ([&]{trace << "skip system " << pkg.available_name_version_db ();});
- return;
+ return nullopt;
}
const shared_ptr<available_package>& ap (pkg.available);
@@ -1764,6 +1700,8 @@ namespace bpkg
const shared_ptr<selected_package>& sp (pkg.selected);
+ assert ((!pre_reeval && !reeval) || sp != nullptr);
+
// True if this is an up/down-grade.
//
bool ud (sp != nullptr && sp->version != pkg.available_version ());
@@ -1780,24 +1718,25 @@ namespace bpkg
sp->state == package_state::configured &&
sp->substate != package_substate::system);
- // The being re-evaluated dependent must be configured as a source package
- // and should not be collected recursively (due to upgrade, etc).
+ // The being (pre-)re-evaluated dependent must be configured as a source
+ // package and should not be collected recursively (due to upgrade, etc).
//
- assert (!reeval || (src_conf && !pkg.recollect_recursively (rpt_depts)));
+ assert ((!pre_reeval && !reeval) ||
+ (src_conf && !pkg.recollect_recursively (rpt_depts)));
if (src_conf)
{
- repointed_dependents::const_iterator i (rpt_depts.find (pk));
-
- if (i != rpt_depts.end ())
- rpt_prereq_flags = &i->second;
-
- if (!reeval && !pkg.recollect_recursively (rpt_depts))
+ if (!pre_reeval && !reeval && !pkg.recollect_recursively (rpt_depts))
{
l5 ([&]{trace << "skip configured "
<< pkg.available_name_version_db ();});
- return;
+ return nullopt;
}
+
+ repointed_dependents::const_iterator i (rpt_depts.find (pk));
+
+ if (i != rpt_depts.end ())
+ rpt_prereq_flags = &i->second;
}
// Iterate over dependencies, trying to unambiguously select a
@@ -1820,7 +1759,9 @@ namespace bpkg
//
if (!pkg.dependencies)
{
- l5 ([&]{trace << (reeval ? "reeval " : "begin ")
+ l5 ([&]{trace << (pre_reeval ? "pre-reeval " :
+ reeval ? "reeval " :
+ "begin " )
<< pkg.available_name_version_db ();});
pkg.dependencies = dependencies ();
@@ -1833,7 +1774,20 @@ namespace bpkg
}
if (!pkg.skeleton)
- pkg.init_skeleton (options);
+ {
+ // In the pre-reevaluation mode make sure that the user-specified
+ // configuration is loaded by the skeleton.
+ //
+ if (pre_reeval)
+ {
+ pkg.init_skeleton (options,
+ nullptr /* override */,
+ sp->effective_src_root (pdb.config),
+ sp->effective_out_root (pdb.config));
+ }
+ else
+ pkg.init_skeleton (options);
+ }
}
else
l5 ([&]{trace << "resume " << pkg.available_name_version_db ();});
@@ -1848,7 +1802,7 @@ namespace bpkg
if (sdeps.size () == deps.size ())
{
l5 ([&]{trace << "end " << pkg.available_name_version_db ();});
- return;
+ return nullopt;
}
// Show how we got here if things go wrong.
@@ -1872,28 +1826,59 @@ namespace bpkg
}
}));
- dep_chain.push_back (pkg);
+ if (!pre_reeval)
+ dep_chain.push_back (pkg);
assert (sdeps.size () < deps.size ());
package_skeleton& skel (*pkg.skeleton);
+ // We shouldn't be failing in the reevaluation mode, given that we only
+ // reevaluate a package if its pre-reevaluation succeeds.
+ //
auto fail_reeval = [&pkg] ()
{
fail << "unable to re-create dependency information of already "
<< "configured package " << pkg.available_name_version_db () <<
info << "likely cause is change in external environment" <<
- info << "consider resetting the build configuration";
+ info << "if not, please report in https://github.com/build2/build2/issues/302";
};
bool postponed (false);
bool reevaluated (false);
+ vector<postponed_configuration::dependency> r;
+
+ if (pre_reeval)
+ {
+ if (!sp->dependency_alternatives_section.loaded ())
+ pdb.load (*sp, sp->dependency_alternatives_section);
+
+ // It doesn't feel like the number of depends clauses may differ for the
+ // available and selected packages in the pre-reevaluation mode since
+ // they must refer to the same package version. If it still happens,
+ // maybe due to some manual tampering, let's assume this as a deviation
+ // case.
+ //
+ size_t nn (deps.size ());
+ size_t on (sp->dependency_alternatives.size ());
+
+ if (nn != on)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: number of depends clauses changed to "
+ << nn << " from " << on;});
+
+ throw reeval_deviated ();
+ }
+ }
+
for (size_t di (sdeps.size ()); di != deps.size (); ++di)
{
// Fail if we missed the re-evaluation target position for any reason.
//
- if (reeval && di == reeval_pos.first) // Note: reeval_pos is 1-based.
+ if (reeval && di == reeval_pos->first) // Note: reeval_pos is 1-based.
fail_reeval ();
const dependency_alternatives_ex& das (deps[di]);
@@ -1905,6 +1890,26 @@ namespace bpkg
if (toolchain_buildtime_dependency (options, das, &nm))
{
+ if (pre_reeval)
+ {
+ size_t oi (sp->dependency_alternatives[di]);
+
+ // It doesn't feel like it may happen in the pre-reevaluation
+ // mode. If it still happens, maybe due to some manual tampering,
+ // let's assume this as a deviation case.
+ //
+ if (oi != 0)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated at depends clause " << di + 1
+ << ": toolchain buildtime dependency replaced the "
+ << " regular one with selected alternative " << oi;});
+
+ throw reeval_deviated ();
+ }
+ }
+
sdeps.push_back (move (sdas));
salts.push_back (0); // Keep parallel to sdeps.
continue;
@@ -1935,6 +1940,22 @@ namespace bpkg
if (edas.empty ())
{
+ if (pre_reeval)
+ {
+ size_t oi (sp->dependency_alternatives[di]);
+
+ if (oi != 0)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated at depends clause " << di + 1
+ << ": dependency with previously selected "
+ << "alternative " << oi << " is now disabled";});
+
+ throw reeval_deviated ();
+ }
+ }
+
sdeps.push_back (move (sdas));
salts.push_back (0); // Keep parallel to sdeps.
continue;
@@ -2026,6 +2047,7 @@ namespace bpkg
&apc,
postponed_repo,
&dep_chain,
+ pre_reeval,
&trace,
this]
(const dependency_alternative& da,
@@ -2046,6 +2068,21 @@ namespace bpkg
if (buildtime && pdb.type == build2_config_type)
{
+ // It doesn't feel like it may happen in the pre-reevaluation
+ // mode. If it still happens, maybe due to some manual
+ // tampering, let's assume this as a deviation case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: build-time dependency " << dn
+ << " is now in build system module "
+ << "configuration";});
+
+ throw reeval_deviated ();
+ }
+
assert (dr == nullptr); // Should fail on the "silent" run.
// Note that the dependent is not necessarily a build system
@@ -2110,6 +2147,11 @@ namespace bpkg
if (!wildcard (*dep_constr) &&
!satisfies (*dep_constr, dp.constraint))
{
+ // We should end up throwing reeval_deviated exception
+ // before the diagnostics run in the pre-reevaluation mode.
+ //
+ assert (!pre_reeval || dr == nullptr);
+
if (dr != nullptr)
*dr << error << "unable to satisfy constraints on package "
<< dn <<
@@ -2199,6 +2241,21 @@ namespace bpkg
if (dsp->state == package_state::broken)
{
+ // If it happens in the pre-reevaluation mode, that may mean
+ // that the package has become broken since the time the
+ // dependent was built. Let's assume this as a deviation case
+ // and fail on the re-collection.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: package " << dn << *ddb
+ << " is broken";});
+
+ throw reeval_deviated ();
+ }
+
assert (dr == nullptr); // Should fail on the "silent" run.
fail << "unable to build broken package " << dn << *ddb <<
@@ -2316,6 +2373,24 @@ namespace bpkg
db = &ldb;
else
{
+ // If it happens in the pre-reevaluation mode, that may
+ // mean that some new configuration has been linked since
+ // the time the dependent was built. Let's assume this as
+ // a deviation case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: now multiple possible "
+ << type << " configurations for "
+ << "build-time dependency (" << dp << "): "
+ << db->config_orig << ", "
+ << ldb.config_orig;});
+
+ throw reeval_deviated ();
+ }
+
assert (dr == nullptr); // Should fail on the "silent" run.
fail << "multiple possible " << type << " configurations "
@@ -2334,6 +2409,22 @@ namespace bpkg
//
if (db == nullptr)
{
+ // If it happens in the pre-reevaluation mode, that may mean
+ // that some configuration has been unlinked since the time
+ // the dependent was built. Let's assume this as a deviation
+ // case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: now no suitable configuration "
+ << "is found for build-time dependency ("
+ << dp << ')';});
+
+ throw reeval_deviated ();
+ }
+
// The private config should be created on the "silent" run
// and so there always should be a suitable configuration on
// the diagnostics run.
@@ -2431,6 +2522,21 @@ namespace bpkg
build2_module (dn) &&
pdb == *ddb)
{
+ // It doesn't feel like it may happen in the pre-reevaluation
+ // mode. If it still happens, maybe due to some manual
+ // tampering, let's assume this as a deviation case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: now unable to build build system "
+ << "module " << dn << " in its dependent "
+ << "package configuration " << pdb.config_orig;});
+
+ throw reeval_deviated ();
+ }
+
assert (dr == nullptr); // Should fail on the "silent" run.
// Note that the dependent package information is printed by the
@@ -2454,6 +2560,19 @@ namespace bpkg
//
if (af == nullptr)
{
+ // If it happens in the pre-reevaluation mode, that may mean
+ // that the dependent has become an orphan since the time it
+ // was built. Let's assume this as a deviation case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: is now orphaned";});
+
+ throw reeval_deviated ();
+ }
+
assert (dr == nullptr); // Should fail on the "silent" run.
fail << "package " << pkg.available_name_version_db ()
@@ -2517,6 +2636,22 @@ namespace bpkg
if (dap == nullptr)
{
+ // If it happens in the pre-reevaluation mode, that may mean
+ // that the repositories has been refetched since the time the
+ // dependent was built and don't contain a satisfactory
+ // package anymore. Let's assume this as a deviation case.
+ //
+ if (pre_reeval)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated: unable to satisfy "
+ << (!dep_constr ? "" : "user-specified ")
+ << "dependency constraint (" << d << ')';});
+
+ throw reeval_deviated ();
+ }
+
if (dep_constr && !system && postponed_repo != nullptr)
{
// We shouldn't be called in the diag mode for the postponed
@@ -2613,6 +2748,11 @@ namespace bpkg
//
if (dap->system_version (*ddb) == nullptr)
{
+ // We should end up throwing reeval_deviated exception
+ // before the diagnostics run in the pre-reevaluation mode.
+ //
+ assert (!pre_reeval || dr == nullptr);
+
if (dr != nullptr)
*dr << error << "dependency " << d << " of package "
<< nm << " is not available in source" <<
@@ -2624,6 +2764,11 @@ namespace bpkg
if (!satisfies (*dap->system_version (*ddb), d.constraint))
{
+ // We should end up throwing reeval_deviated exception
+ // before the diagnostics run in the pre-reevaluation mode.
+ //
+ assert (!pre_reeval || dr == nullptr);
+
if (dr != nullptr)
*dr << error << "dependency " << d << " of package "
<< nm << " is not available in source" <<
@@ -2679,7 +2824,7 @@ namespace bpkg
{
const shared_ptr<available_package>& dap (b.available);
- assert (dap != nullptr); // Otherwise we would fail earlier.
+ assert (dap != nullptr); // Otherwise we would have failed earlier.
const dependency& d (b.dependency);
@@ -2709,6 +2854,12 @@ namespace bpkg
{
if (!satisfies (v1, c2.value))
{
+ // We should end up throwing reeval_deviated exception
+ // before the diagnostics run in the pre-reevaluation
+ // mode.
+ //
+ assert (!pre_reeval || dr == nullptr);
+
if (dr != nullptr)
{
const package_name& n (d.name);
@@ -2759,9 +2910,10 @@ namespace bpkg
&dep_chain,
postponed_repo,
postponed_alts,
+ &postponed_recs,
+ &postponed_edeps,
&postponed_deps,
&postponed_cfgs,
- &postponed_poss,
&unacceptable_alts,
&di,
reeval,
@@ -2782,39 +2934,39 @@ namespace bpkg
//
pair<size_t, size_t> dp (di + 1, dai + 1);
- if (reeval &&
- dp.first == reeval_pos.first &&
- dp.second != reeval_pos.second)
+ if (reeval &&
+ dp.first == reeval_pos->first &&
+ dp.second != reeval_pos->second)
fail_reeval ();
postponed_configuration::packages cfg_deps;
for (prebuild& b: bs)
{
- build_package bp {
+ build_package bpk {
build_package::build,
- b.db,
- b.selected,
- b.available,
- move (b.repository_fragment),
- nullopt, // Dependencies.
- nullopt, // Dependencies alternatives.
- nullopt, // Package skeleton.
- nullopt, // Postponed dependency alternatives.
- false, // Recursive collection.
- nullopt, // Hold package.
- nullopt, // Hold version.
- {}, // Constraints.
- b.system,
- false, // Keep output directory.
- false, // Disfigure (from-scratch reconf).
- false, // Configure-only.
- nullopt, // Checkout root.
- false, // Checkout purge.
- strings (), // Configuration variables.
- {pk}, // Required by (dependent).
- true, // Required by dependents.
- 0}; // State flags.
+ b.db,
+ b.selected,
+ b.available,
+ move (b.repository_fragment),
+ nullopt, // Dependencies.
+ nullopt, // Dependencies alternatives.
+ nullopt, // Package skeleton.
+ nullopt, // Postponed dependency alternatives.
+ false, // Recursive collection.
+ nullopt, // Hold package.
+ nullopt, // Hold version.
+ {}, // Constraints.
+ b.system,
+ false, // Keep output directory.
+ false, // Disfigure (from-scratch reconf).
+ false, // Configure-only.
+ nullopt, // Checkout root.
+ false, // Checkout purge.
+ strings (), // Configuration variables.
+ {pk}, // Required by (dependent).
+ true, // Required by dependents.
+ 0}; // State flags.
const optional<version_constraint>& constraint (
b.dependency.constraint);
@@ -2822,12 +2974,12 @@ namespace bpkg
// Add our constraint, if we have one.
//
// Note that we always add the constraint implied by the
- // dependent. The user-implied constraint, if present, will be
+ // dependent. The user-implied constraint, if present, will be
// added when merging from the pre-entered entry. So we will have
// both constraints for completeness.
//
if (constraint)
- bp.constraints.emplace_back (pdb, nm.string (), *constraint);
+ bpk.constraints.emplace_back (pdb, nm.string (), *constraint);
// Now collect this prerequisite. If it was actually collected
// (i.e., it wasn't already there) and we are forcing a downgrade
@@ -2933,18 +3085,19 @@ namespace bpkg
//
build_package* p (
collect_build (options,
- move (bp),
- fdb,
- rpt_depts,
- apc,
- initial_collection,
+ move (bpk),
replaced_vers,
postponed_cfgs,
nullptr /* dep_chain */,
+ false /* initial_collection */,
+ nullptr /* fdb */,
+ nullptr /* apc */,
+ nullptr /* rpt_depts */,
nullptr /* postponed_repo */,
nullptr /* postponed_alts */,
+ nullptr /* postponed_recs */,
+ nullptr /* postponed_edeps */,
nullptr /* postponed_deps */,
- nullptr /* postponed_poss */,
nullptr /* unacceptable_alts */,
verify));
@@ -2952,17 +3105,30 @@ namespace bpkg
// Do not collect prerequisites recursively for dependent
// re-evaluation. Instead, if the re-evaluation position is
- // reached, collect the dependency packages to add them to the
+ // reached, stash the dependency packages to add them to the
// existing dependent's cluster.
//
- if (reeval)
- {
- if (dp == reeval_pos)
- cfg_deps.push_back (move (dpk));
-
+ if (reeval && dp != *reeval_pos)
continue;
+
+ // Note that while collect_build() may prefer an existing entry in
+ // the map and return NULL, the recursive collection of this
+ // preferred entry may have been postponed due to the existing
+ // dependent (see collect_build_prerequisites() for details). Now,
+ // we can potentially be recursively collecting such a dependent
+ // after its re-evaluation to some earlier than this dependency
+ // position. If that's the case, it is the time to collect this
+ // dependency (unless it has a config clause which will be handled
+ // below).
+ //
+ if (p == nullptr)
+ {
+ p = entered_build (dpk);
+ assert (p != nullptr);
}
+ bool collect_prereqs (!p->recursive_collection);
+
// Do not recursively collect a dependency of a dependent with
// configuration clauses, which could be this or some other
// (indicated by the presence in postponed_deps) dependent. In the
@@ -2973,12 +3139,7 @@ namespace bpkg
// directly right after the configuration negotiation (rather than
// via the dependent).
//
- bool collect_prereqs (p != nullptr);
-
{
- build_package* bp (entered_build (dpk));
- assert (bp != nullptr);
-
if (da.prefer || da.require)
{
// Indicate that the dependent with configuration clauses is
@@ -2996,8 +3157,8 @@ namespace bpkg
postponed_deps.emplace (dpk,
postponed_dependency {
false /* without_config */,
- true /* with_config */,
- initial_collection});
+ true /* with_config */,
+ initial_collection});
}
else
i->second.with_config = true;
@@ -3005,15 +3166,27 @@ namespace bpkg
// Prematurely collected before we saw any config clauses.
//
- if (bp->recursive_collection &&
+ if (p->recursive_collection &&
postponed_cfgs.find_dependency (dpk) == nullptr)
{
- l5 ([&]{trace << "cannot cfg-postpone dependency "
- << bp->available_name_version_db ()
- << " of dependent "
- << pkg.available_name_version_db ()
- << " (collected prematurely), "
- << "throwing postpone_dependency";});
+ if (reeval)
+ {
+ l5 ([&]{trace << "cannot re-evaluate existing dependent "
+ << pkg.available_name_version_db ()
+ << " due to dependencys "
+ << p->available_name_version_db ()
+ << " (collected prematurely), "
+ << "throwing postpone_dependency";});
+ }
+ else
+ {
+ l5 ([&]{trace << "cannot cfg-postpone dependency "
+ << p->available_name_version_db ()
+ << " of dependent "
+ << pkg.available_name_version_db ()
+ << " (collected prematurely), "
+ << "throwing postpone_dependency";});
+ }
// Don't print the "while satisfying..." chain.
//
@@ -3022,12 +3195,15 @@ namespace bpkg
throw postpone_dependency (move (dpk));
}
- // Postpone until (re-)negotiation.
- //
- l5 ([&]{trace << "cfg-postpone dependency "
- << bp->available_name_version_db ()
- << " of dependent "
- << pkg.available_name_version_db ();});
+ if (!reeval)
+ {
+ // Postpone until (re-)negotiation.
+ //
+ l5 ([&]{trace << "cfg-postpone dependency "
+ << p->available_name_version_db ()
+ << " of dependent "
+ << pkg.available_name_version_db ();});
+ }
cfg_deps.push_back (move (dpk));
@@ -3042,7 +3218,7 @@ namespace bpkg
if (i != postponed_deps.end ())
{
l5 ([&]{trace << "dep-postpone dependency "
- << bp->available_name_version_db ()
+ << p->available_name_version_db ()
<< " of dependent "
<< pkg.available_name_version_db ();});
@@ -3053,7 +3229,7 @@ namespace bpkg
else
{
l5 ([&]{trace << "no cfg-clause for dependency "
- << bp->available_name_version_db ()
+ << p->available_name_version_db ()
<< " of dependent "
<< pkg.available_name_version_db ();});
}
@@ -3063,18 +3239,19 @@ namespace bpkg
if (collect_prereqs)
collect_build_prerequisites (options,
*p,
+ dep_chain,
+ initial_collection,
fdb,
- rpt_depts,
apc,
- initial_collection,
+ rpt_depts,
replaced_vers,
- dep_chain,
postponed_repo,
postponed_alts,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
}
@@ -3190,8 +3367,31 @@ namespace bpkg
{
reevaluated = true;
- // Note: the dependent may already exist in the cluster with a
- // subset of dependencies.
+ // As a first step add this dependent/dependencies to one of the
+ // new/existing postponed_configuration clusters, which could
+ // potentially cause some of them to be merged. Note that when
+ // we re-evaluate existing dependents of dependencies in a
+ // cluster, these dependents can potentially be added to
+ // different clusters (see collect_build_postponed() for
+ // details). Here are the possibilities and what we should do in
+ // each case.
+ //
+ // 1. Got added to a new cluster -- this dependent got postponed
+ // and we return false.
+ //
+ // 2. Got added to an existing non-yet-negotiated cluster (which
+ // could potentially involve merging a bunch of them) --
+ // ditto. Note this also covers adding into a cluster which
+ // contain dependencies whose existing dependents we are
+ // currently re-evaluating (the negotiated member is absent
+ // but the depth is non-zero).
+ //
+ // 3. Got added to an existing already-[being]-negotiated
+ // cluster (which could potentially involve merging a bunch
+ // of them, some negotiated, some being negotiated, and some
+ // not yet negotiated). Perhaps just making the resulting
+ // cluster shadow and rolling back, just like in the other
+ // case (non-existing dependent), will do.
//
postponed_configuration& cfg (
postponed_cfgs.add (pk,
@@ -3200,29 +3400,7 @@ namespace bpkg
cfg_deps,
has_alt).first);
- // Can we merge clusters as a result? Seems so.
- //
- // - Simple case is if the cluster(s) being merged are not
- // negotiated. Then perhaps we could handle this via the same
- // logic that handles the addition of extra dependencies.
- //
- // - For the complex case, perhaps just making the resulting
- // cluster shadow and rolling back, just like in the other
- // case (non-existing dependent).
- //
- // Note: this is a special case of the below more general logic.
- //
- // Also note that we can distinguish the simple case by the fact
- // that the resulting cluster is not negotiated. Note however,
- // that in this case it is guaranteed that all the involved
- // clusters will be merged into the cluster which the being
- // re-evaluated dependent belongs to since this cluster (while
- // not being negotiated) already has non-zero depth (see
- // collect_build_postponed() for details).
- //
- assert (cfg.depth != 0);
-
- if (cfg.negotiated)
+ if (cfg.negotiated) // Case (3).
{
l5 ([&]{trace << "re-evaluating dependent "
<< pkg.available_name_version_db ()
@@ -3515,18 +3693,19 @@ namespace bpkg
collect_build_prerequisites (options,
*b,
+ dep_chain,
+ initial_collection,
fdb,
- rpt_depts,
apc,
- initial_collection,
+ rpt_depts,
replaced_vers,
- dep_chain,
postponed_repo,
postponed_alts,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
// Unless the dependency is already being reconfigured,
@@ -3591,15 +3770,14 @@ namespace bpkg
// package to the postponements set (can potentially already be there)
// and saving the enabled alternatives.
//
- auto postpone = [&pkg, &edas, &postponed]
- (postponed_packages* postpones)
- {
- if (postpones != nullptr)
- postpones->insert (&pkg);
+ auto postpone = [&pkg, &edas, &postponed] (postponed_packages* postpones)
+ {
+ if (postpones != nullptr)
+ postpones->insert (&pkg);
- pkg.postponed_dependency_alternatives = move (edas);
- postponed = true;
- };
+ pkg.postponed_dependency_alternatives = move (edas);
+ postponed = true;
+ };
// Iterate over the enabled dependencies and try to select a
// satisfactory alternative.
@@ -3621,10 +3799,10 @@ namespace bpkg
? &sp->prerequisites
: nullptr);
- // During the dependent re-evaluation we always try to reproduce the
- // existing setup.
+ // During the dependent (pre-)re-evaluation we always try to reproduce
+ // the existing setup.
//
- assert (!reeval || prereqs != nullptr);
+ assert ((!reeval && !pre_reeval) || prereqs != nullptr);
for (bool unacceptable (false);;)
{
@@ -3657,6 +3835,18 @@ namespace bpkg
//
bool reused_only (false);
+ auto pre_reeval_append_result = [&r] (pair<size_t, size_t> pos,
+ prebuilds&& builds)
+ {
+ postponed_configuration::packages deps;
+ deps.reserve (builds.size ());
+
+ for (prebuild& b: builds)
+ deps.emplace_back (b.db, move (b.dependency.name));
+
+ r.emplace_back (pos, move (deps), nullopt /* has_alternative */);
+ };
+
for (size_t i (0); i != edas.size (); ++i)
{
// Skip the unacceptable alternatives.
@@ -3683,7 +3873,7 @@ namespace bpkg
const dependency_alternative& da (edas[i].first);
- precollect_result r (precollect (da, das.buildtime, prereqs));
+ precollect_result pcr (precollect (da, das.buildtime, prereqs));
// If we didn't come up with satisfactory dependency builds, then
// skip this alternative and try the next one, unless the collecting
@@ -3699,9 +3889,9 @@ namespace bpkg
//
// depends: libfoo >= 2.0.0 | {libfoo >= 1.0.0 libbar}
//
- if (!r.builds)
+ if (!pcr.builds)
{
- if (r.repo_postpone)
+ if (pcr.repo_postpone)
{
if (reeval)
fail_reeval ();
@@ -3713,7 +3903,7 @@ namespace bpkg
// If this alternative is reused but is not satisfactory, then
// switch to the reused-only mode.
//
- if (r.reused && r.unsatisfactory)
+ if (pcr.reused && pcr.unsatisfactory)
reused_only = true;
continue;
@@ -3730,7 +3920,7 @@ namespace bpkg
//
if (!first_alt)
{
- first_alt = make_pair (i, move (r));
+ first_alt = make_pair (i, move (pcr));
continue;
}
@@ -3741,11 +3931,16 @@ namespace bpkg
//
auto try_select = [postponed_alts, &max_alt_index,
&edas, &pkg,
+ di,
prereqs,
+ pre_reeval,
reeval,
&trace,
- &postpone, &collect, &select]
- (size_t index, precollect_result&& r)
+ &postpone,
+ &collect,
+ &select,
+ &pre_reeval_append_result]
+ (size_t index, precollect_result&& pcr)
{
const auto& eda (edas[index]);
const dependency_alternative& da (eda.first);
@@ -3773,14 +3968,39 @@ namespace bpkg
// Select this alternative if all its dependencies are reused and
// do nothing about it otherwise.
//
- if (r.reused)
+ if (pcr.reused)
{
// On the diagnostics run there shouldn't be any alternatives
// that we could potentially select.
//
assert (postponed_alts != nullptr);
- if (!collect (da, dai, move (*r.builds), prereqs))
+ if (pre_reeval)
+ {
+ size_t ni (dai + 1);
+ size_t oi (pkg.selected->dependency_alternatives[di]);
+
+ if (ni != oi)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated at depends clause " << di + 1
+ << ": selected alternative changed to " << ni
+ << " from " << oi;});
+
+ throw reeval_deviated ();
+ }
+
+ pre_reeval_append_result (make_pair (di + 1, ni),
+ move (*pcr.builds));
+
+ if (da.prefer || da.require)
+ {
+ postpone (nullptr);
+ return true;
+ }
+ }
+ else if (!collect (da, dai, move (*pcr.builds), prereqs))
{
postpone (nullptr); // Already inserted into postponed_cfgs.
return true;
@@ -3789,9 +4009,9 @@ namespace bpkg
select (da, dai);
// Make sure no more true alternatives are selected during this
- // function call unless we are re-evaluating a dependent.
+ // function call unless we are (pre-)reevaluating a dependent.
//
- if (!reeval)
+ if (!reeval && !pre_reeval)
max_alt_index = 0;
return true;
@@ -3813,7 +4033,7 @@ namespace bpkg
break;
}
- if (try_select (i, move (r)))
+ if (try_select (i, move (pcr)))
break;
// Not all of the alternative dependencies are reused, so go to
@@ -3832,22 +4052,47 @@ namespace bpkg
{
assert (first_alt);
- precollect_result& r (first_alt->second);
+ precollect_result& pcr (first_alt->second);
- assert (r.builds);
+ assert (pcr.builds);
- if (r.reused || !reused_only)
+ if (pcr.reused || !reused_only)
{
// If there are any unacceptable alternatives, then the remaining
// one should be reused.
//
- assert (!unacceptable || r.reused);
+ assert (!unacceptable || pcr.reused);
const auto& eda (edas[first_alt->first]);
const dependency_alternative& da (eda.first);
size_t dai (eda.second);
- if (!collect (da, dai, move (*r.builds), prereqs))
+ if (pre_reeval)
+ {
+ size_t ni (dai + 1);
+ size_t oi (sp->dependency_alternatives[di]);
+
+ if (ni != oi)
+ {
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated for depends clause " << di + 1
+ << ": selected alternative (single) changed to "
+ << ni << " from " << oi;});
+
+ throw reeval_deviated ();
+ }
+
+ pre_reeval_append_result (make_pair (di + 1, ni),
+ move (*pcr.builds));
+
+ if (da.prefer || da.require)
+ {
+ postpone (nullptr);
+ break;
+ }
+ }
+ else if (!collect (da, dai, move (*pcr.builds), prereqs))
{
postpone (nullptr); // Already inserted into postponed_cfgs.
break;
@@ -3870,6 +4115,19 @@ namespace bpkg
//
if (prereqs != nullptr)
{
+ if (pre_reeval)
+ {
+ size_t oi (sp->dependency_alternatives[di]);
+
+ l5 ([&]{trace << "re-evaluation of dependent "
+ << pkg.available_name_version_db ()
+ << " deviated for depends clause " << di + 1
+ << ": now can't select alternative, previously "
+ << oi << " was selected";});
+
+ throw reeval_deviated ();
+ }
+
if (reeval)
fail_reeval ();
@@ -3877,6 +4135,10 @@ namespace bpkg
continue;
}
+ // Otherwise we would have thrown/failed earlier.
+ //
+ assert (!pre_reeval && !reeval);
+
// We shouldn't end up with the "no alternative to select" case if any
// alternatives are unacceptable.
//
@@ -3973,10 +4235,7 @@ namespace bpkg
// Print the reason.
//
- precollect (da.first,
- das.buildtime,
- nullptr /* prereqs */,
- &dr);
+ precollect (da.first, das.buildtime, nullptr /* prereqs */, &dr);
}
}
}
@@ -3994,29 +4253,56 @@ namespace bpkg
assert (postponed);
}
- dep_chain.pop_back ();
+ if (pre_reeval)
+ {
+ l5 ([&]
+ {
+ diag_record dr (trace);
+ dr << "pre-reevaluated " << pkg.available_name_version_db ()
+ << ": ";
+
+ if (postponed)
+ {
+ assert (!r.empty ());
+
+ dr << r.back ().position.first << ','
+ << r.back ().position.second;
+ }
+ else
+ dr << "end reached";
+ });
+ }
+ else
+ {
+ dep_chain.pop_back ();
+
+ l5 ([&]{trace << (!postponed ? "end " :
+ reeval ? "re-evaluated " :
+ "postpone ")
+ << pkg.available_name_version_db ();});
+ }
- l5 ([&]{trace << (!postponed ? "end " :
- reeval ? "re-evaluated " :
- "postpone ")
- << pkg.available_name_version_db ();});
+ return pre_reeval && postponed
+ ? optional<vector<postponed_configuration::dependency>> (move (r))
+ : nullopt;
}
void build_packages::
collect_build_prerequisites (const pkg_build_options& o,
database& db,
const package_name& name,
+ bool initial_collection,
const function<find_database_function>& fdb,
- const repointed_dependents& rpt_depts,
const function<add_priv_cfg_function>& apc,
- bool initial_collection,
+ const repointed_dependents& rpt_depts,
replaced_versions& replaced_vers,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
size_t max_alt_index,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies& postponed_edeps,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
- postponed_positions& postponed_poss,
unacceptable_alternatives& unacceptable_alts)
{
auto mi (map_.find (db, name));
@@ -4026,33 +4312,36 @@ namespace bpkg
collect_build_prerequisites (o,
mi->second.package,
+ dep_chain,
+ initial_collection,
fdb,
- rpt_depts,
apc,
- initial_collection,
+ rpt_depts,
replaced_vers,
- dep_chain,
&postponed_repo,
&postponed_alts,
max_alt_index,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
}
void build_packages::
- collect_repointed_dependents (const pkg_build_options& o,
- const repointed_dependents& rpt_depts,
- replaced_versions& replaced_vers,
- postponed_packages& postponed_repo,
- postponed_packages& postponed_alts,
- postponed_dependencies& postponed_deps,
- postponed_configurations& postponed_cfgs,
- postponed_positions& postponed_poss,
- unacceptable_alternatives& unacceptable_alts,
- const function<find_database_function>& fdb,
- const function<add_priv_cfg_function>& apc)
+ collect_repointed_dependents (
+ const pkg_build_options& o,
+ const repointed_dependents& rpt_depts,
+ replaced_versions& replaced_vers,
+ postponed_packages& postponed_repo,
+ postponed_packages& postponed_alts,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies& postponed_edeps,
+ postponed_dependencies& postponed_deps,
+ postponed_configurations& postponed_cfgs,
+ unacceptable_alternatives& unacceptable_alts,
+ const function<find_database_function>& fdb,
+ const function<add_priv_cfg_function>& apc)
{
for (const auto& rd: rpt_depts)
{
@@ -4124,17 +4413,18 @@ namespace bpkg
//
collect_build (o,
move (p),
- fdb,
- rpt_depts,
- apc,
- true /* initial_collection */,
replaced_vers,
postponed_cfgs,
&dep_chain,
+ true /* initial_collection */,
+ fdb,
+ apc,
+ &rpt_depts,
&postponed_repo,
&postponed_alts,
+ &postponed_recs,
+ &postponed_edeps,
&postponed_deps,
- &postponed_poss,
&unacceptable_alts);
}
}
@@ -4305,10 +4595,11 @@ namespace bpkg
replaced_versions& replaced_vers,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies& postponed_edeps,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
strings& postponed_cfgs_history,
- postponed_positions& postponed_poss,
unacceptable_alternatives& unacceptable_alts,
const function<find_database_function>& fdb,
const repointed_dependents& rpt_depts,
@@ -4325,9 +4616,12 @@ namespace bpkg
snapshot (const build_packages& pkgs,
const postponed_packages& postponed_repo,
const postponed_packages& postponed_alts,
+ const postponed_packages& postponed_recs,
+ const postponed_existing_dependencies& postponed_edeps,
const postponed_dependencies& postponed_deps,
const postponed_configurations& postponed_cfgs)
: pkgs_ (pkgs),
+ postponed_edeps_ (postponed_edeps),
postponed_deps_ (postponed_deps),
postponed_cfgs_ (postponed_cfgs)
{
@@ -4341,18 +4635,22 @@ namespace bpkg
save (postponed_repo_, postponed_repo);
save (postponed_alts_, postponed_alts);
+ save (postponed_recs_, postponed_recs);
}
void
restore (build_packages& pkgs,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies& postponed_edeps,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs)
{
- pkgs = move (pkgs_);
- postponed_cfgs = move (postponed_cfgs_);
- postponed_deps = move (postponed_deps_);
+ pkgs = move (pkgs_);
+ postponed_cfgs = move (postponed_cfgs_);
+ postponed_deps = move (postponed_deps_);
+ postponed_edeps = move (postponed_edeps_);
auto restore = [&pkgs] (postponed_packages& d,
const vector<package_key>& s)
@@ -4369,6 +4667,7 @@ namespace bpkg
restore (postponed_repo, postponed_repo_);
restore (postponed_alts, postponed_alts_);
+ restore (postponed_recs, postponed_recs_);
}
private:
@@ -4376,31 +4675,13 @@ namespace bpkg
// memory. We could probably optimize this some more if necessary
// (there are still sets/maps inside).
//
- build_packages pkgs_;
- vector<package_key> postponed_repo_;
- vector<package_key> postponed_alts_;
- postponed_dependencies postponed_deps_;
- postponed_configurations postponed_cfgs_;
- };
-
- // This exception is thrown if negotiation of the current cluster needs to
- // be skipped until later. This is normally required if this cluster
- // contains some existing dependent which needs to be re-evaluated to a
- // dependency position greater than some other not yet negotiated cluster
- // will re-evaluate this dependent to. Sometimes this another cluster yet
- // needs to be created in which case the exception carries the information
- // required for that (see the postponed_position's replace flag for
- // details).
- //
- struct skip_configuration
- {
- optional<existing_dependent> dependent;
- pair<size_t, size_t> new_position;
-
- skip_configuration () = default;
-
- skip_configuration (existing_dependent&& d, pair<size_t, size_t> n)
- : dependent (move (d)), new_position (n) {}
+ build_packages pkgs_;
+ vector<package_key> postponed_repo_;
+ vector<package_key> postponed_alts_;
+ vector<package_key> postponed_recs_;
+ postponed_existing_dependencies postponed_edeps_;
+ postponed_dependencies postponed_deps_;
+ postponed_configurations postponed_cfgs_;
};
size_t depth (pcfg != nullptr ? pcfg->depth : 0);
@@ -4428,29 +4709,36 @@ namespace bpkg
assert (!pcfg->negotiated);
- // Re-evaluate existing dependents with configuration clause for
- // dependencies in this configuration cluster up to these
- // dependencies. Omit dependents which are already being built or
- // dropped. Note that these dependents, potentially with additional
- // dependencies, will be added to this cluster with the `existing` flag
- // as a part of the dependents' re-evaluation (see the collect lambda in
- // collect_build_prerequisites() for details).
+ // Re-evaluate existing dependents for dependencies in this
+ // configuration cluster. Omit dependents which are already being built
+ // or dropped.
+ //
+ // Note that the existing dependent can be re-evaluated to an earlier
+ // position than the position of the dependency which has introduced
+ // this existing dependent. Thus, re-evaluating such a dependent does
+ // not necessarily add this dependent together with the dependencies at
+ // the re-evaluation target position specifically to this cluster. We,
+ // however, re-evaluate all the discovered existing dependents. Also
+ // note that these dependents will be added to their respective clusters
+ // with the `existing` flag as a part of the dependents' re-evaluation
+ // (see the collect lambda in collect_build_prerequisites() for
+ // details).
//
// After being re-evaluated the existing dependents are recursively
- // collected in the same way as the new dependents.
+ // collected in the same way and at the same time as the new dependents
+ // of the clusters they belong to.
//
{
// Map existing dependents to the dependencies they apply a
// configuration to. Also, collect the information which is required
- // for a dependent re-evaluation and its subsequent recursive
- // collection (selected package, etc).
+ // for a dependent re-evaluation (selected package, etc).
//
- // As mentioned earlier, we may end up adding additional dependencies
- // to pcfg->dependencies which in turn may have additional existing
+ // Note that we may end up adding additional dependencies to
+ // pcfg->dependencies which in turn may have additional existing
// dependents which we need to process. Feels like doing this
// iteratively is the best option.
//
- // Note that we need to make sure we don't re-process the same
+ // Also note that we need to make sure we don't re-process the same
// existing dependents.
//
struct existing_dependent_ex: existing_dependent
@@ -4481,136 +4769,79 @@ namespace bpkg
//
const package_key& p (deps[i]);
- // If the dependent is being built, then check if it was
- // re-evaluated to the position greater than the dependency
- // position. Return true if that's the case, so this package is
- // added to the resulting list and we can handle this situation.
- //
- // Note that we rely on "small function object" optimization
- // here.
- //
- const function<verify_dependent_build_function> verify (
- [&postponed_cfgs, pcfg]
- (const package_key& pk, pair<size_t, size_t> pos)
- {
- for (const postponed_configuration& cfg: postponed_cfgs)
- {
- if (&cfg == pcfg || cfg.negotiated)
- {
- if (const pair<size_t, size_t>* p =
- cfg.existing_dependent_position (pk))
- {
- if (p->first > pos.first)
- return true;
- }
- }
- }
-
- return false;
- });
-
for (existing_dependent& ed:
query_existing_dependents (trace,
+ o,
p.db,
p.name,
- replaced_vers,
+ fdb,
rpt_depts,
- verify))
+ replaced_vers))
{
- package_key pk (ed.db, ed.selected->name);
-
- // If this dependent is present in postponed_deps, then it means
- // someone depends on it with configuration and it's no longer
- // considered an existing dependent (it will be reconfigured).
- // However, this fact may not be reflected yet. And it can
- // actually turn out bogus.
- //
- auto pi (postponed_deps.find (pk));
- if (pi != postponed_deps.end ())
+ if (ed.dependency)
{
- l5 ([&]{trace << "skip dep-postponed existing dependent "
- << pk << " of dependency " << p;});
+ package_key pk (ed.db, ed.selected->name);
- // Note that here we would re-evaluate the existing dependent
- // without specifying any configuration for it.
+ // If this dependent is present in postponed_deps, then it
+ // means someone depends on it with configuration and it's no
+ // longer considered an existing dependent (it will be
+ // reconfigured). However, this fact may not be reflected
+ // yet. And it can actually turn out bogus.
//
- pi->second.wout_config = true;
-
- continue;
- }
-
- auto i (dependents.find (pk));
- size_t di (ed.dependency_position.first);
+ auto pi (postponed_deps.find (pk));
+ if (pi != postponed_deps.end ())
+ {
+ l5 ([&]{trace << "skip dep-postponed existing dependent "
+ << pk << " of dependency " << p;});
- // Skip re-evaluated dependent if the dependency index is
- // greater than the one we have already re-evaluated to. If it
- // is earlier, then add the entry to postponed_poss and throw
- // postpone_position to recollect from scratch. Note that this
- // entry in postponed_poss is with replacement.
- //
- if (i != dependents.end () && i->second.reevaluated)
- {
- size_t ci (i->second.dependency_position.first);
+ // Note that here we would re-evaluate the existing
+ // dependent without specifying any configuration for it.
+ //
+ pi->second.wout_config = true;
- if (di > ci)
continue;
+ }
- // The newly-introduced dependency must belong to the depends
- // value other then the one we have re-evaluated to.
- //
- assert (di < ci);
-
- postponed_position pp (ed.dependency_position,
- true /* replace */);
-
- auto p (postponed_poss.emplace (pk, pp));
+ auto i (dependents.find (pk));
- if (!p.second)
+ // If the existing dependent is not in the map yet, then add
+ // it.
+ //
+ if (i == dependents.end ())
{
- assert (p.first->second > pp);
- p.first->second = pp;
+ if (*ed.dependency != p)
+ collect_existing_dependent_dependency (o,
+ ed,
+ replaced_vers,
+ postponed_cfgs);
+
+ i = dependents.emplace (
+ move (pk), existing_dependent_ex (move (ed))).first;
+ }
+ else
+ {
+ // We always re-evaluate to the earliest position.
+ //
+ assert (i->second.dependency_position ==
+ ed.dependency_position);
}
- l5 ([&]{trace << "cannot re-evaluate dependent "
- << pk << " to dependency index " << di
- << " since it is already re-evaluated to "
- << "greater index " << ci << " in " << *pcfg
- << ", throwing postpone_position";});
-
- throw postpone_position ();
- }
-
- // If the existing dependent is not in the map yet, then add
- // it. Otherwise, if the dependency position is greater than
- // that one in the existing map entry then skip it (this
- // position will be up-negotiated, if it's still present).
- // Otherwise, if the position is less then overwrite the
- // existing entry. Otherwise (the position is equal), just add
- // the dependency to the existing entry.
- //
- // Note that we want to re-evaluate the dependent up to the
- // earliest dependency position and continue with the regular
- // prerequisites collection (as we do for new dependents)
- // afterwards.
- //
- if (i == dependents.end ())
- {
- i = dependents.emplace (
- move (pk), existing_dependent_ex (move (ed))).first;
+ // Note that we add here the dependency which introduced this
+ // existing dependent, rather than the dependency which
+ // position we re-evaluate to, and which we want to be
+ // mentioned in the plan, if printed.
+ //
+ i->second.dependencies.push_back (p);
}
else
{
- size_t ci (i->second.dependency_position.first);
-
- if (ci < di)
- continue;
- else if (ci > di)
- i->second = existing_dependent_ex (move (ed));
- //else if (ci == di)
- // ;
+ collect_deviated_dependent (o,
+ ed,
+ p,
+ replaced_vers,
+ postponed_recs,
+ postponed_cfgs);
}
-
- i->second.dependencies.push_back (p);
}
}
@@ -4629,108 +4860,7 @@ namespace bpkg
if (ed.reevaluated)
continue;
- size_t di (ed.dependency_position.first);
const package_key& pk (d.first);
-
- // Check if there is an earlier dependency position for this
- // dependent that will be participating in a configuration
- // negotiation and skip this cluster if that's the case. There
- // are two places to check: postponed_poss and other clusters.
- //
- auto pi (postponed_poss.find (pk));
- if (pi != postponed_poss.end () && pi->second.first < di)
- {
- l5 ([&]{trace << "pos-postpone existing dependent "
- << pk << " re-evaluation to dependency "
- << "index " << di << " due to recorded index "
- << pi->second.first << ", skipping " << *pcfg;});
-
- pi->second.skipped = true;
-
- // If requested, override the first encountered non-replace
- // position to replace (see below for details).
- //
- if (!pi->second.replace && postponed_poss.replace)
- {
- pi->second.replace = true;
- postponed_poss.replace = false;
- }
-
- if (pi->second.replace)
- throw skip_configuration (move (ed), pi->second);
- else
- throw skip_configuration ();
- }
-
- // The other clusters check is a bit more complicated: if the
- // other cluster (with the earlier position) is not yet
- // negotiated, then we skip. Otherwise, we have to add an entry
- // to postponed_poss and backtrack.
- //
- bool skip (false);
- for (const postponed_configuration& cfg: postponed_cfgs)
- {
- // Skip the current cluster.
- //
- if (&cfg == pcfg)
- continue;
-
- if (const pair<size_t, size_t>* p =
- cfg.existing_dependent_position (pk))
- {
- size_t ei (p->first); // Other position.
-
- if (!cfg.negotiated)
- {
- if (ei < di)
- {
- l5 ([&]{trace << "cannot re-evaluate dependent "
- << pk << " to dependency index " << di
- << " due to earlier dependency index "
- << ei << " in " << cfg << ", skipping "
- << *pcfg;});
-
- skip = true;
- }
- }
- else
- {
- // If this were not the case, then this dependent wouldn't
- // have been considered as an existing by
- // query_existing_dependents() since as it is (being)
- // negotiated then it is already re-evaluated and so is
- // being built (see the verify lambda above).
- //
- assert (ei > di);
-
- // Feels like there cannot be an earlier position.
- //
- postponed_position pp (ed.dependency_position,
- false /* replace */);
-
- auto p (postponed_poss.emplace (pk, pp));
- if (!p.second)
- {
- assert (p.first->second > pp);
- p.first->second = pp;
- }
-
- l5 ([&]{trace << "cannot re-evaluate dependent "
- << pk << " to dependency index " << di
- << " due to greater dependency "
- << "index " << ei << " in " << cfg
- << ", throwing postpone_position";});
-
- throw postpone_position ();
- }
- }
- }
-
- if (skip)
- throw skip_configuration ();
-
- // Finally, re-evaluate the dependent.
- //
packages& ds (ed.dependencies);
pair<shared_ptr<available_package>,
@@ -4749,40 +4879,34 @@ namespace bpkg
//
build_package p {
build_package::build,
- pk.db,
- move (ed.selected),
- move (rp.first),
- move (rp.second),
- nullopt, // Dependencies.
- nullopt, // Dependencies alternatives.
- 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<package_key> ( // Required by (dependency).
- ds.begin (), ds.end ()),
- false, // Required by dependents.
- build_package::build_reevaluate};
+ pk.db,
+ move (ed.selected),
+ move (rp.first),
+ move (rp.second),
+ nullopt, // Dependencies.
+ nullopt, // Dependencies alternatives.
+ 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<package_key> ( // Required by (dependency).
+ make_move_iterator (ds.begin ()),
+ make_move_iterator (ds.end ())),
+ false, // Required by dependents.
+ build_package::build_reevaluate};
// Note: not recursive.
//
- collect_build (o,
- move (p),
- fdb,
- rpt_depts,
- apc,
- false /* initial_collection */,
- replaced_vers,
- postponed_cfgs);
+ collect_build (o, move (p), replaced_vers, postponed_cfgs);
build_package* b (entered_build (pk));
assert (b != nullptr);
@@ -4794,31 +4918,23 @@ namespace bpkg
build_package_refs dep_chain;
collect_build_prerequisites (o,
*b,
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
&postponed_repo,
&postponed_alts,
numeric_limits<size_t>::max (),
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts,
ed.dependency_position);
ed.reevaluated = true;
-
- if (pi != postponed_poss.end ())
- {
- // Otherwise we should have thrown skip_configuration above.
- //
- assert (di <= pi->second.first);
-
- pi->second.reevaluated = true;
- }
}
}
}
@@ -5018,18 +5134,19 @@ namespace bpkg
build_package_refs dep_chain;
collect_build_prerequisites (o,
*b,
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
&postponed_repo,
&postponed_alts,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
// Unless the dependency is already being reconfigured, reconfigure
@@ -5154,18 +5271,19 @@ namespace bpkg
collect_build_prerequisites (o,
*b,
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
&postponed_repo,
&postponed_alts,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
}
@@ -5183,16 +5301,70 @@ namespace bpkg
//
vector<build_package*> spas; // Reuse.
- for (bool prog (!postponed_repo.empty () ||
- !postponed_cfgs.negotiated () ||
- !postponed_alts.empty () ||
+ for (bool prog (find_if (postponed_recs.begin (), postponed_recs.end (),
+ [] (const build_package* p)
+ {
+ return !p->recursive_collection;
+ }) != postponed_recs.end () ||
+ !postponed_repo.empty () ||
+ !postponed_cfgs.negotiated () ||
+ !postponed_alts.empty () ||
postponed_deps.has_bogus ());
prog; )
{
+ // First, recursively recollect the not yet collected packages (deviated
+ // existing dependents, etc).
+ //
+ prog = false;
+
+ postponed_packages pcs;
+ for (build_package* p: postponed_recs)
+ {
+ if (!p->recursive_collection)
+ {
+ build_package_refs dep_chain;
+ collect_build_prerequisites (o,
+ *p,
+ dep_chain,
+ false /* initial_collection */,
+ fdb,
+ apc,
+ rpt_depts,
+ replaced_vers,
+ &postponed_repo,
+ &postponed_alts,
+ 0 /* max_alt_index */,
+ pcs,
+ postponed_edeps,
+ postponed_deps,
+ postponed_cfgs,
+ unacceptable_alts);
+
+ // Note that the existing dependent collection can be postponed
+ // due to it's own existing dependents.
+ //
+ if (p->recursive_collection)
+ prog = true;
+ }
+ }
+
+ // Scheduling new packages for re-collection is also a progress.
+ //
+ if (!prog)
+ prog = !pcs.empty ();
+
+ if (prog)
+ {
+ postponed_recs.insert (pcs.begin (), pcs.end ());
+ continue;
+ }
+
postponed_packages prs;
postponed_packages pas;
- // Try to collect the repository-related postponments first.
+ // Now, as there is no more progress made in recollecting of the not yet
+ // collected packages, try to collect the repository-related
+ // postponments.
//
for (build_package* p: postponed_repo)
{
@@ -5203,18 +5375,19 @@ namespace bpkg
collect_build_prerequisites (o,
*p,
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
&prs,
&pas,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
}
@@ -5265,6 +5438,8 @@ namespace bpkg
snapshot s (*this,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs);
@@ -5274,10 +5449,11 @@ namespace bpkg
replaced_vers,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
postponed_cfgs_history,
- postponed_poss,
unacceptable_alts,
fdb,
rpt_depts,
@@ -5296,72 +5472,6 @@ namespace bpkg
return;
}
- catch (skip_configuration& e)
- {
- // Restore the state from snapshot.
- //
- // Note: postponed_cfgs is re-assigned.
- //
- s.restore (*this,
- postponed_repo,
- postponed_alts,
- postponed_deps,
- postponed_cfgs);
-
- pc = &postponed_cfgs[ci];
-
- // Note that in this case we keep the accumulated configuration,
- // if any.
-
- pc->depth = 0; // Mark as non-negotiated.
-
- // If requested, "replace" the "later" dependent-dependency
- // cluster with an earlier.
- //
- if (e.dependent)
- {
- existing_dependent& ed (*e.dependent);
- pair<size_t, size_t> pos (e.new_position);
-
- const build_package* bp (
- replace_existing_dependent_dependency (
- trace,
- o,
- ed, // Note: modified.
- pos,
- fdb,
- rpt_depts,
- apc,
- false /* initial_collection */,
- replaced_vers,
- postponed_cfgs));
-
- // Can this dependency already belong to some configuration
- // cluster? It feels like potentially it can. However, if it
- // does then this cluster cannot be current (we would throw
- // postpone_position) nor (being) negotiated (the dependent
- // would have already been re-evaluated). Thus, if the
- // dependency already belongs to some cluster we assume that
- // this existing dependent will naturally be reevaluated up to
- // this dependency later when their cluster is negotiated.
- // Otherwise, we just create such a cluster.
- //
- package_key dep (bp->db, bp->selected->name);
-
- const postponed_configuration* cfg (
- postponed_cfgs.find_dependency (dep));
-
- if (cfg == nullptr)
- postponed_cfgs.add (
- package_key (ed.db, ed.selected->name), pos, move (dep));
- else
- assert (cfg != pc && !cfg->negotiated);
- }
-
- l5 ([&]{trace << "postpone cfg-negotiation of " << *pc;});
-
- break;
- }
catch (const retry_configuration& e)
{
// If this is not "our problem", then keep looking.
@@ -5379,6 +5489,8 @@ namespace bpkg
s.restore (*this,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs);
@@ -5425,6 +5537,8 @@ namespace bpkg
s.restore (*this,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs);
@@ -5568,18 +5682,19 @@ namespace bpkg
collect_build_prerequisites (o,
*p,
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
&prs,
&pas,
i,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
prog = (pas.find (p) == pas.end () ||
@@ -5600,7 +5715,7 @@ namespace bpkg
// but producing new repository-related postponements is progress
// nevertheless.
//
- // Note that we don't need to check for new configuration- related
+ // Note that we don't need to check for new configuration-related
// postponements here since if they are present, then this package
// wouldn't be in pas and so prog would be true (see above for
// details).
@@ -5619,40 +5734,6 @@ namespace bpkg
assert (!prog);
- // If we still have any non-negotiated clusters and non-replace
- // postponed positions, then it's possible one of them is the cross-
- // dependent pathological case where we will never hit it unless we
- // force the re-evaluation to earlier position (similar to the
- // single-dependent case, which we handle accurately). For example:
- //
- // tex: depends: libbar(c)
- // depends: libfoo(c)
- //
- // tix: depends: libbar(c)
- // depends: tex(c)
- //
- // Here tex and tix are existing dependent and we are upgrading tex.
- //
- // While it would be ideal to handle such cases accurately, it's not
- // trivial. So for now we resort to the following heuristics: when left
- // with no other option, we treat the first encountered non- replace
- // position as replace and see if that helps move things forward.
- //
- if (!postponed_cfgs.negotiated () &&
- find_if (postponed_poss.begin (), postponed_poss.end (),
- [] (const auto& v) {return !v.second.replace;}) !=
- postponed_poss.end () &&
- !postponed_poss.replace)
- {
- l5 ([&]{trace << "non-negotiated clusters left and non-replace "
- << "postponed positions are present, overriding first "
- << "encountered non-replace position to replace";});
-
- postponed_poss.replace = true;
- prog = true;
- continue; // Go back to negotiating skipped cluster.
- }
-
// Finally, erase the bogus postponements and re-collect from scratch,
// if any (see postponed_dependencies for details).
//
@@ -5805,18 +5886,19 @@ namespace bpkg
collect_build_prerequisites (o,
**postponed_repo.begin (),
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
nullptr,
nullptr,
0,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
assert (false); // Can't be here.
@@ -5828,18 +5910,19 @@ namespace bpkg
collect_build_prerequisites (o,
**postponed_alts.begin (),
+ dep_chain,
+ false /* initial_collection */,
fdb,
- rpt_depts,
apc,
- false /* initial_collection */,
+ rpt_depts,
replaced_vers,
- dep_chain,
nullptr,
nullptr,
0,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
assert (false); // Can't be here.
@@ -6193,16 +6276,15 @@ namespace bpkg
vector<build_packages::existing_dependent> build_packages::
query_existing_dependents (
tracer& trace,
+ const pkg_build_options& o,
database& db,
const package_name& name,
- const replaced_versions& replaced_vers,
+ const function<find_database_function>& fdb,
const repointed_dependents& rpt_depts,
- const function<verify_dependent_build_function>& vdb)
+ const replaced_versions& replaced_vers)
{
vector<existing_dependent> r;
- lazy_shared_ptr<selected_package> sp (db, name);
-
// Lazily search for the dependency build and detect if it is being
// up/downgraded. Note that we will only do that if the dependency has an
// existing dependent which imposes a version constraint on this
@@ -6215,106 +6297,214 @@ namespace bpkg
{
for (auto& pd: query_dependents (ddb, name, db))
{
- shared_ptr<selected_package> dsp (
- ddb.load<selected_package> (pd.name));
-
- auto i (dsp->prerequisites.find (sp));
- assert (i != dsp->prerequisites.end ());
+ package_key pk (ddb, pd.name);
- const auto& pos (i->second.config_position);
+ // Ignore repointed dependents.
+ //
+ if (rpt_depts.find (pk) != rpt_depts.end ())
+ {
+ l5 ([&]{trace << "skip repointed existing dependent " << pk
+ << " of dependency " << name << db;});
+ continue;
+ }
- if (pos.first != 0) // Has config clause?
+ // Ignore dependent which is expected to be built or dropped.
+ //
+ auto vi (replaced_vers.find (pk));
+ if (vi != replaced_vers.end () && !vi->second.replaced)
{
- package_key pk (ddb, pd.name);
+ bool build (vi->second.available != nullptr);
+
+ l5 ([&]{trace << "skip expected to be "
+ << (build ? "built" : "dropped")
+ << " existing dependent " << pk
+ << " of dependency " << name << db;});
+
+ continue;
+ }
+
+ // Ignore dependent which is already being built or dropped.
+ //
+ const build_package* p (entered_build (pk));
- if (rpt_depts.find (pk) != rpt_depts.end ())
+ if (p != nullptr && p->action)
+ {
+ bool build;
+ if (((build = *p->action == build_package::build) &&
+ (p->system || p->recollect_recursively (rpt_depts))) ||
+ *p->action == build_package::drop)
{
- l5 ([&]{trace << "skip repointed existing dependent " << pk
+ l5 ([&]{trace << "skip being "
+ << (build ? "built" : "dropped")
+ << " existing dependent " << pk
<< " of dependency " << name << db;});
continue;
}
+ }
- // Ignore dependent which is already being built or dropped.
+ // Ignore dependent if this dependency up/downgrade won't satisfy the
+ // dependent's constraint. The thinking here is that we will either
+ // fail for this reason later or the problem will be resolved
+ // naturally due to the execution plan refinement (see
+ // unsatisfied_dependents for details).
+ //
+ if (pd.constraint)
+ {
+ // Search for the dependency build and detect if it is being
+ // up/downgraded, if not done yet. In particular, the available
+ // package could be NULL meaning we are just adjusting.
//
- const build_package* p (entered_build (pk));
-
- if (p != nullptr && p->action)
+ if (dep == nullptr)
{
- bool build;
- if (((build = *p->action == build_package::build) &&
- (p->system || p->recollect_recursively (rpt_depts))) ||
- *p->action == build_package::drop)
+ dep = entered_build (db, name);
+
+ assert (dep != nullptr); // Expected to be being built.
+
+ if (dep->available != nullptr)
{
- if (!build || !vdb || !vdb (pk, pos))
- {
- l5 ([&]{trace << "skip being "
- << (build ? "built" : "dropped")
- << " existing dependent " << pk
- << " of dependency " << name << db;});
- continue;
- }
+ const shared_ptr<selected_package>& sp (dep->selected);
+
+ // Expected to be selected since it has an existing dependent.
+ //
+ assert (sp != nullptr);
+
+ ud = sp->version.compare (dep->available_version ());
}
}
- // Ignore dependent which is expected to be built or dropped.
- //
- auto vi (replaced_vers.find (pk));
- if (vi != replaced_vers.end () && !vi->second.replaced)
+ if (ud != 0 &&
+ !satisfies (dep->available_version (), *pd.constraint))
{
- bool build (vi->second.available != nullptr);
-
- l5 ([&]{trace << "skip expected to be "
- << (build ? "built" : "dropped")
- << " existing dependent " << pk
- << " of dependency " << name << db;});
+ l5 ([&]{trace << "skip unsatisfied existing dependent " << pk
+ << " of dependency "
+ << dep->available_name_version_db () << " due to "
+ << "constraint (" << name << ' ' << *pd.constraint
+ << ')';});
continue;
}
+ }
+
+ // Pre-reevaluate the dependent to calculate the position which the
+ // dependent should be re-evaluated to.
+ //
+ shared_ptr<selected_package> dsp (
+ ddb.load<selected_package> (pd.name));
+
+ pair<shared_ptr<available_package>,
+ lazy_shared_ptr<repository_fragment>> rp (
+ find_available_fragment (o, ddb, dsp));
+
+ try
+ {
+ build_package p {
+ build_package::build,
+ ddb,
+ dsp, // Don't move from since will be used later.
+ move (rp.first),
+ move (rp.second),
+ nullopt, // Dependencies.
+ nullopt, // Dependencies alternatives.
+ 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.
+ {}, // Required by (dependency).
+ false, // Required by dependents.
+ 0}; // State flags.
- // Ignore dependent if this dependency up/downgrade won't satisfy
- // the dependent's constraint. The thinking here is that we will
- // either fail for this reason later or the problem will be resolved
- // naturally due to the execution plan refinement (see
- // unsatisfied_dependents for details).
+ build_package_refs dep_chain;
+ postponed_packages postponed_repo;
+ postponed_packages postponed_alts;
+ postponed_packages postponed_recs;
+ postponed_existing_dependencies postponed_edeps;
+ postponed_dependencies postponed_deps;
+ postponed_configurations postponed_cfgs;
+ unacceptable_alternatives unacceptable_alts;
+ replaced_versions replaced_vers;
+
+ // Note: the initial_collection value is meaningless since we don't
+ // perform the actual prerequisites collection in the
+ // pre-reevaluation mode.
//
- if (pd.constraint)
- {
- // Search for the dependency build and detect if it is being
- // up/downgraded, if not done yet. In particular, the available
- // package could be NULL meaning we are just adjusting.
- //
- if (dep == nullptr)
- {
- dep = entered_build (db, name);
+ optional<vector<postponed_configuration::dependency>> deps (
+ collect_build_prerequisites (o,
+ p,
+ dep_chain,
+ false /* initial_collection */,
+ fdb,
+ nullptr /* add_priv_cfg_function */,
+ rpt_depts,
+ replaced_vers,
+ &postponed_repo,
+ &postponed_alts,
+ numeric_limits<size_t>::max (),
+ postponed_recs,
+ postponed_edeps,
+ postponed_deps,
+ postponed_cfgs,
+ unacceptable_alts,
+ pair<size_t, size_t> (0, 0)));
- assert (dep != nullptr); // Expected to be being built.
+ // Must be read-only.
+ //
+ assert (postponed_repo.empty () &&
+ postponed_alts.empty () &&
+ postponed_recs.empty () &&
+ postponed_edeps.empty () &&
+ postponed_deps.empty () &&
+ postponed_cfgs.empty () &&
+ unacceptable_alts.empty () &&
+ replaced_vers.empty ());
+
+ if (deps)
+ {
+ package_key pk {db, name};
- if (dep->available != nullptr)
- {
- const shared_ptr<selected_package>& sp (dep->selected);
+ assert (!deps->empty ());
- // Expected to be selected since it has an existing dependent.
- //
- assert (sp != nullptr);
+ // Try to retrieve the original dependency position. If we fail,
+ // then this dependency belongs to the depends clause which comes
+ // after the re-evaluation target position.
+ //
+ optional<pair<size_t, size_t>> odp;
- ud = sp->version.compare (dep->available_version ());
+ for (const postponed_configuration::dependency& d: *deps)
+ {
+ if (find (d.begin (), d.end (), pk) != d.end ())
+ {
+ odp = d.position;
+ break;
}
}
- if (ud != 0 &&
- !satisfies (dep->available_version (), *pd.constraint))
- {
- l5 ([&]{trace << "skip unsatisfied existing dependent " << pk
- << " of dependency "
- << dep->available_name_version_db () << " due to "
- << "constraint (" << name << ' ' << *pd.constraint
- << ')';});
+ // Try to preserve the name of the original dependency as the one
+ // which brings the existing dependent to the config cluster.
+ // Failed that, use the first dependency in the alternative which
+ // we will be re-evaluating to.
+ //
+ postponed_configuration::dependency& d (deps->back ());
- continue;
- }
- }
+ if (find (d.begin (), d.end (), pk) == d.end ())
+ pk = move (d.front ());
- r.push_back (existing_dependent {ddb, move (dsp), pos});
+ r.push_back (
+ existing_dependent {ddb, move (dsp), move (pk), d.position, odp});
+ }
+ }
+ catch (const reeval_deviated&)
+ {
+ r.push_back (
+ existing_dependent {ddb, move (dsp), nullopt, {}, nullopt});
}
}
}
@@ -6323,73 +6513,32 @@ namespace bpkg
}
const build_package* build_packages::
- replace_existing_dependent_dependency (
- tracer& trace,
+ collect_existing_dependent_dependency (
const pkg_build_options& o,
- existing_dependent& ed,
- pair<size_t, size_t> pos,
- const function<find_database_function>& fdb,
- const repointed_dependents& rpt_depts,
- const function<add_priv_cfg_function>& apc,
- bool initial_collection,
+ const existing_dependent& ed,
replaced_versions& replaced_vers,
postponed_configurations& postponed_cfgs)
{
- // The repointed dependent cannot be returned by
- // query_existing_dependents(). Note that the repointed dependent
- // references both old and new prerequisites.
- //
- assert (rpt_depts.find (package_key (ed.db, ed.selected->name)) ==
- rpt_depts.end ());
-
- shared_ptr<selected_package> dsp;
- database* pdb (nullptr);
- const version_constraint* vc (nullptr);
-
- // Find the dependency for this earlier dependency position. We know it
- // must be there since it's with configuration.
- //
- for (const auto& p: ed.selected->prerequisites)
- {
- if (p.second.config_position == pos)
- {
- pdb = &p.first.database ();
-
- dsp = p.first.load ();
-
- l5 ([&]{trace << "replace dependency at index "
- << ed.dependency_position.first
- << " of existing dependent " << *ed.selected
- << ed.db << " with dependency " << *dsp
- << *pdb << " at index " << pos.first;});
+ assert (ed.dependency); // Shouldn't be called for deviated dependents.
- if (p.second.constraint)
- vc = &*p.second.constraint;
- }
- }
+ const shared_ptr<selected_package>& dsp (ed.selected);
- assert (dsp != nullptr);
+ package_key dpt (ed.db, dsp->name);
+ const package_key& dep (*ed.dependency);
- package_key pk (*pdb, dsp->name);
+ lazy_shared_ptr<selected_package> lsp (dep.db.get (), dep.name);
+ shared_ptr<selected_package> sp (lsp.load ());
- // Adjust the existing dependent entry.
- //
- ed.dependency_position = pos;
-
- // Collect the package build for this dependency.
- //
pair<shared_ptr<available_package>,
lazy_shared_ptr<repository_fragment>> rp (
- find_available_fragment (o, pk.db, dsp));
+ find_available_fragment (o, dep.db, sp));
- bool system (dsp->system ());
-
- package_key dpk (ed.db, ed.selected->name);
+ bool system (sp->system ());
build_package p {
build_package::build,
- pk.db,
- move (dsp),
+ dep.db,
+ move (sp),
move (rp.first),
move (rp.second),
nullopt, // Dependencies.
@@ -6407,25 +6556,71 @@ namespace bpkg
nullopt, // Checkout root.
false, // Checkout purge.
strings (), // Configuration variables.
- {dpk}, // Required by (dependent).
+ {dpt}, // Required by (dependent).
true, // Required by dependents.
- build_package::adjust_reconfigure};
+ 0};
+
+ // Add constraints, if present.
+ //
+ {
+ auto i (dsp->prerequisites.find (lsp));
+ assert (i != dsp->prerequisites.end ());
+
+ if (i->second.constraint)
+ p.constraints.emplace_back (dpt.db,
+ dpt.name.string (),
+ *i->second.constraint);
+ }
+
+ // Note: not recursive.
+ //
+ collect_build (o, move (p), replaced_vers, postponed_cfgs);
- if (vc != nullptr)
- p.constraints.emplace_back (dpk.db, dpk.name.string (), *vc);
+ return entered_build (dep);
+ }
+
+ void build_packages::
+ collect_deviated_dependent (const pkg_build_options& o,
+ const existing_dependent& ed,
+ package_key orig_dep,
+ replaced_versions& replaced_vers,
+ postponed_packages& postponed_recs,
+ postponed_configurations& postponed_cfgs)
+ {
+ pair<shared_ptr<available_package>,
+ lazy_shared_ptr<repository_fragment>> rp (
+ find_available_fragment (o, ed.db, ed.selected));
+
+ build_package p {
+ build_package::build,
+ ed.db,
+ ed.selected,
+ move (rp.first),
+ move (rp.second),
+ nullopt, // Dependencies.
+ nullopt, // Dependencies alternatives.
+ 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.
+ {move (orig_dep)}, // Required by (dependency).
+ false, // Required by dependents.
+ build_package::build_recollect};
// Note: not recursive.
//
- collect_build (o,
- move (p),
- fdb,
- rpt_depts,
- apc,
- initial_collection,
- replaced_vers,
- postponed_cfgs);
-
- return entered_build (pk);
+ collect_build (o, move (p), replaced_vers, postponed_cfgs);
+
+ postponed_recs.insert (entered_build (ed.db, ed.selected->name));
}
build_packages::iterator build_packages::
diff --git a/bpkg/pkg-build-collect.hxx b/bpkg/pkg-build-collect.hxx
index 1764b3a..a91d2df 100644
--- a/bpkg/pkg-build-collect.hxx
+++ b/bpkg/pkg-build-collect.hxx
@@ -297,7 +297,9 @@ namespace bpkg
// This is required if it is being built as a source package and needs to
// be up/down-graded and/or reconfigured and has some buildfile clauses,
// it is a repointed dependent, or it is already in the process of being
- // collected.
+ // collected. Also configured dependents can be scheduled for recollection
+ // explicitly (see postponed_packages and build_recollect flag for
+ // details).
//
bool
recollect_recursively (const repointed_dependents&) const;
@@ -345,6 +347,11 @@ namespace bpkg
//
static const uint16_t build_reevaluate = 0x0008;
+ // Set if this build action is for recursive re-collecting of a deviated
+ // existing dependent.
+ //
+ static const uint16_t build_recollect = 0x0010;
+
// Set if this build action is for replacing of an existing package due to
// deorphaning or rebuilding as an archive or directory.
//
@@ -352,7 +359,7 @@ namespace bpkg
// repository fragment, archive, or directory (even if its version doesn't
// change).
//
- static const uint16_t build_replace = 0x0010;
+ static const uint16_t build_replace = 0x0020;
bool
replace () const
@@ -404,7 +411,9 @@ namespace bpkg
//
package_skeleton&
init_skeleton (const common_options&,
- const shared_ptr<available_package>& override = nullptr);
+ const shared_ptr<available_package>& override = nullptr,
+ optional<dir_path> src_root = nullopt,
+ optional<dir_path> out_root = nullopt);
};
using build_package_list = std::list<reference_wrapper<build_package>>;
@@ -415,11 +424,11 @@ namespace bpkg
// Packages with postponed prerequisites collection, for one of the
// following reasons:
//
- // - Postponed due to the inability to find a version satisfying the pre-
- // entered constraint from repositories available to this package. The
- // idea is that this constraint could still be satisfied from a repository
- // fragment of some other package (that we haven't processed yet) that
- // also depends on this prerequisite.
+ // - Postponed due to the inability to find a dependency version satisfying
+ // the pre-entered constraint from repositories available to this
+ // package. The idea is that this constraint could still be satisfied from
+ // a repository fragment of some other package (that we haven't processed
+ // yet) that also depends on this prerequisite.
//
// - Postponed due to the inability to choose between two dependency
// alternatives, both having dependency packages which are not yet
@@ -427,6 +436,11 @@ namespace bpkg
// ambiguity could still be resolved after some of those dependency
// packages get built via some other dependents.
//
+ // - Postponed recollection of configured dependents whose dependencies
+ // up/downgrade causes selection of different dependency alternatives.
+ // This, in particular, may end up in resolving different dependency
+ // packages and affect the dependent and dependency configurations.
+ //
using postponed_packages = std::set<build_package*>;
// Base for exception types that indicate an inability to collect a package
@@ -529,101 +543,13 @@ namespace bpkg
}
};
- // Map of existing dependents which may not be re-evaluated to a position
- // with the dependency index greater than the specified one.
- //
- // This mechanism applies when we re-evaluate an existing dependent to a
- // certain position but later realize we've gone too far. In this case we
- // note the earlier position information and re-collect from scratch. On the
- // re-collection any re-evaluation of the dependent to a greater position
- // will be either skipped or performed but to this earlier position (see the
- // replace member for details).
+ // Map of the dependencies whose recursive collection is postponed until
+ // their existing dependents re-collection/re-evaluation to the lists of the
+ // respective existing dependents (see collect_build_prerequisites() for
+ // details).
//
- // We consider the postponement bogus if some dependent re-evaluation was
- // skipped due to its presence but no re-evaluation to this (or earlier)
- // dependency index was performed. Thus, if after the collection of packages
- // some bogus entries are present in the map, then it means that we have
- // skipped the respective re-evaluations erroneously and so need to erase
- // these entries and re-collect.
- //
- // Note that if no re-evaluation is skipped due to a postponement then it
- // is harmless and we don't consider it bogus.
- //
- struct postponed_position: pair<size_t, size_t>
- {
- // True if the "later" position should be replaced rather than merely
- // skipped. The replacement deals with the case where the "earlier"
- // position is encountered while processing the same cluster as what
- // contains the later position. In this case, if we merely skip, then we
- // will never naturally encounter the earlier position. So we have to
- // force the issue (even if things change enough for us to never see the
- // later position again).
- //
- bool replace;
-
- // Re-evaluation was skipped due to this postponement.
- //
- bool skipped = false;
-
- // The dependent was re-evaluated. Note that it can be only re-evaluated
- // to this or earlier dependency index.
- //
- bool reevaluated = false;
-
- postponed_position (pair<size_t, size_t> p, bool r)
- : pair<size_t, size_t> (p), replace (r) {}
- };
-
- class postponed_positions: public std::map<package_key, postponed_position>
- {
- public:
- // If true, override the first encountered non-replace position to replace
- // and clear this flag. See collect_build_postponed() for details.
- //
- bool replace = false;
-
- // Erase the bogus postponements and throw cancel_postponement, if any.
- //
- struct cancel_postponement: scratch_collection
- {
- cancel_postponement ()
- : scratch_collection ("bogus existing dependent re-evaluation "
- "postponement cancellation") {}
- };
-
- void
- cancel_bogus (tracer& trace)
- {
- bool bogus (false);
- for (auto i (begin ()); i != end (); )
- {
- const postponed_position& p (i->second);
-
- if (p.skipped && !p.reevaluated)
- {
- bogus = true;
-
- l5 ([&]{trace << "erase bogus existing dependent " << i->first
- << " re-evaluation postponement with dependency index "
- << i->second.first;});
-
- // It seems that the replacement may never be bogus.
- //
- assert (!p.replace);
-
- i = erase (i);
- }
- else
- ++i;
- }
-
- if (bogus)
- {
- l5 ([&]{trace << "bogus re-evaluation postponement erased, throwing";});
- throw cancel_postponement ();
- }
- }
- };
+ using postponed_existing_dependencies = std::map<package_key,
+ vector<package_key>>;
// Set of dependency alternatives which were found unacceptable by the
// configuration negotiation machinery and need to be ignored on re-
@@ -922,6 +848,10 @@ namespace bpkg
// The depth of the negotiating recursion (see collect_build_postponed()
// for details).
//
+ // Note that non-zero depth for an absent negotiated member indicates that
+ // the cluster is in the existing dependents re-evaluation or
+ // configuration refinment phases.
+ //
size_t depth = 0;
// Add dependencies of a new dependent.
@@ -990,12 +920,6 @@ namespace bpkg
bool
contains_dependency (const postponed_configuration&) const;
- // If the configuration contains the specified existing dependent, then
- // return the earliest dependency position. Otherwise return NULL.
- //
- const pair<size_t, size_t>*
- existing_dependent_position (const package_key&) const;
-
// Notes:
//
// - Adds dependencies of the being merged from configuration to the end
@@ -1206,21 +1130,23 @@ namespace bpkg
build_package*
collect_build (const pkg_build_options&,
build_package,
- const function<find_database_function>&,
- const repointed_dependents&,
- const function<add_priv_cfg_function>&,
- bool initial_collection,
replaced_versions&,
postponed_configurations&,
build_package_refs* dep_chain = nullptr,
+ bool initial_collection = false,
+ const function<find_database_function>& = nullptr,
+ const function<add_priv_cfg_function>& = nullptr,
+ const repointed_dependents* = nullptr,
postponed_packages* postponed_repo = nullptr,
postponed_packages* postponed_alts = nullptr,
+ postponed_packages* postponed_recs = nullptr,
+ postponed_existing_dependencies* = nullptr,
postponed_dependencies* = nullptr,
- postponed_positions* = nullptr,
unacceptable_alternatives* = nullptr,
const function<verify_package_build_function>& = nullptr);
- // Collect prerequisites of the package being built recursively.
+ // Collect prerequisites of the package being built recursively. Return
+ // nullopt, unless in the pre-reevaluation mode (see below).
//
// But first "prune" this process if the package we build is a system one
// or is already configured, since that would mean all its prerequisites
@@ -1244,7 +1170,16 @@ namespace bpkg
// recursively.
//
// - For an existing dependent being re-evaluated to the specific
- // dependency position.
+ // dependency position (reeval_pos argument is specified and is not
+ // {0,0}).
+ //
+ // - For an existing dependent being pre-reevaluated (reeval_pos argument
+ // is {0,0}).
+ //
+ // - For an existing dependent being re-collected due to the selected
+ // dependency alternatives deviation, which may be caused by its
+ // dependency up/downgrade (see postponed prerequisites collection for
+ // details).
//
// Note that for these cases, as it was said above, we can potentially
// fail if the dependent is an orphan, but this is exactly what we need to
@@ -1279,16 +1214,44 @@ namespace bpkg
// be performed. See the collect lambda implementation for details on the
// configuration refinement machinery.
//
- // If the package is a dependency of a configured dependent with
- // configuration clause and needs to be reconfigured (being upgraded, has
- // configuration specified, etc), then postpone its recursive collection
- // by recording it in postponed_cfgs as a single-dependency cluster with
- // an existing dependent (see postponed_configurations for details). If
- // this dependent already belongs to some (being) negotiated configuration
- // cluster with a greater dependency position then record this dependency
- // position in postponed_poss and throw postpone_position. This exception
- // is handled by re-collecting packages from scratch, but now with the
- // knowledge about position this dependent needs to be re-evaluated to.
+ // If {0,0} is specified as the reeval_pos argument, then perform the
+ // pre-reevaluation. In this read-only mode perform the regular dependency
+ // alternative selection but not the actual dependency collection and stop
+ // when all the depends clauses are processed or an alternative with the
+ // configuration clause is encountered. In the latter case return the list
+ // of the selected alternative dependencies/positions, where the last
+ // entry corresponds to the alternative with the encountered configuration
+ // clause. Return nullopt otherwise. Also lock for any deviation in the
+ // dependency alternatives selection and throw reeval_deviated exception
+ // if such a deviation is detected.
+ //
+ // If the package is a dependency of configured dependents and needs to be
+ // reconfigured (being upgraded, has configuration specified, etc), then
+ // do the following for each such dependent prior to collecting its own
+ // prerequisites:
+ //
+ // - If the dependent is not already being built/dropped, expected to be
+ // built/dropped, and doesn't apply constraints which the dependency
+ // doesn't satisfy anymore, then pre-reevaluate the dependent.
+ //
+ // - If the dependency alternative with configuration clause has been
+ // encountered during the pre-reevaluation, then record it in
+ // postponed_cfgs as a single-dependency cluster with an existing
+ // dependent (see postponed_configurations for details). If the index of
+ // the encountered depends clause is equal/less than the index of the
+ // depends clause the dependency belongs to, then postpone the recursive
+ // collection of this dependency assuming that it will be collected
+ // later, during/after its existing dependent re-evaluation.
+ //
+ // - If the dependency alternatives selection has deviated, then record
+ // the dependent in postponed_recs (so that it can be re-collected
+ // later) and postpone recursive collection of this dependency assuming
+ // that it will be collected later, during its existing dependent
+ // re-collection. Also record this dependency in the postponed existing
+ // dependencies map (postponed_existing_dependencies argument). This way
+ // the caller can track if the postponed dependencies have never been
+ // collected recursively (deviations are too large, etc) and handle this
+ // situation (currently just fail).
//
// If a dependency alternative configuration cannot be negotiated between
// all the dependents, then unaccept_alternative can be thrown (see
@@ -1307,12 +1270,6 @@ namespace bpkg
}
};
- struct postpone_position: scratch_collection
- {
- postpone_position ()
- : scratch_collection ("earlier dependency position") {}
- };
-
struct retry_configuration
{
size_t depth;
@@ -1324,40 +1281,43 @@ namespace bpkg
size_t depth;
};
- void
+ struct reeval_deviated {};
+
+ optional<vector<postponed_configuration::dependency>>
collect_build_prerequisites (const pkg_build_options&,
build_package&,
+ build_package_refs& dep_chain,
+ bool initial_collection,
const function<find_database_function>&,
- const repointed_dependents&,
const function<add_priv_cfg_function>&,
- bool initial_collection,
+ const repointed_dependents&,
replaced_versions&,
- build_package_refs& dep_chain,
postponed_packages* postponed_repo,
postponed_packages* postponed_alts,
size_t max_alt_index,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies&,
postponed_dependencies&,
postponed_configurations&,
- postponed_positions&,
unacceptable_alternatives&,
- pair<size_t, size_t> reeval_pos =
- make_pair(0, 0));
+ optional<pair<size_t, size_t>> reeval_pos = nullopt);
void
collect_build_prerequisites (const pkg_build_options&,
database&,
const package_name&,
+ bool initial_collection,
const function<find_database_function>&,
- const repointed_dependents&,
const function<add_priv_cfg_function>&,
- bool initial_collection,
+ const repointed_dependents&,
replaced_versions&,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
size_t max_alt_index,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies&,
postponed_dependencies&,
postponed_configurations&,
- postponed_positions&,
unacceptable_alternatives&);
// Collect the repointed dependents and their replaced prerequisites,
@@ -1374,9 +1334,10 @@ namespace bpkg
replaced_versions&,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies&,
postponed_dependencies&,
postponed_configurations&,
- postponed_positions&,
unacceptable_alternatives&,
const function<find_database_function>&,
const function<add_priv_cfg_function>&);
@@ -1403,10 +1364,11 @@ namespace bpkg
replaced_versions&,
postponed_packages& postponed_repo,
postponed_packages& postponed_alts,
+ postponed_packages& postponed_recs,
+ postponed_existing_dependencies&,
postponed_dependencies&,
postponed_configurations&,
strings& postponed_cfgs_history,
- postponed_positions&,
unacceptable_alternatives&,
const function<find_database_function>&,
const repointed_dependents&,
@@ -1469,54 +1431,64 @@ namespace bpkg
private:
// Return the list of existing dependents that has a configuration clause
- // for the specified dependency. Skip dependents which are being built and
- // require recursive recollection or dropped (present in the map) or
- // expected to be built or dropped (present in rpt_depts or
+ // for any of the selected alternatives together with the dependencies for
+ // the earliest such an alternative and the original dependency (for which
+ // the function is called for) position. Return absent dependency for
+ // those dependents which dependency alternatives selection has deviated
+ // (normally due to the dependency up/downgrade). Skip dependents which
+ // are being built and require recursive recollection or dropped (present
+ // in the map) or expected to be built or dropped (present in rpt_depts or
// replaced_vers). Also skip dependents which impose the version
// constraint on this dependency and the dependency doesn't satisfy this
// constraint.
//
- // Optionally, specify the function which can verify the dependent build
- // and decide whether to override the default behavior and still add the
- // dependent package to the resulting list, returning true in this case.
- //
struct existing_dependent
{
- reference_wrapper<database> db;
- shared_ptr<selected_package> selected;
- pair<size_t, size_t> dependency_position;
- };
+ // Dependent.
+ //
+ reference_wrapper<database> db;
+ shared_ptr<selected_package> selected;
- using verify_dependent_build_function = bool (const package_key&,
- pair<size_t, size_t>);
+ // Dependency.
+ //
+ optional<package_key> dependency;
+ pair<size_t, size_t> dependency_position;
+ optional<pair<size_t, size_t>> orig_dependency_position;
+ };
vector<existing_dependent>
query_existing_dependents (
tracer&,
+ const pkg_build_options&,
database&,
const package_name&,
- const replaced_versions&,
+ const function<find_database_function>&,
const repointed_dependents&,
- const function<verify_dependent_build_function>& = nullptr);
+ const replaced_versions&);
- // Update the existing dependent object (previously obtained with the
- // query_existing_dependents() call) with the new dependency position and
- // collect the dependency referred by this position. Return the pointer to
- // the collected build package object.
+ // Non-recursively collect the dependency of an existing dependent
+ // previously returned by the query_existing_dependents() function call
+ // with the build_package::build_reevaluate flag.
//
const build_package*
- replace_existing_dependent_dependency (
- tracer&,
+ collect_existing_dependent_dependency (
const pkg_build_options&,
- existing_dependent&,
- pair<size_t, size_t>,
- const function<find_database_function>&,
- const repointed_dependents&,
- const function<add_priv_cfg_function>&,
- bool initial_collection,
+ const existing_dependent&,
replaced_versions&,
postponed_configurations&);
+ // Non-recursively collect the deviated existing dependent previously
+ // returned by the query_existing_dependents() function call and add it to
+ // the postponed package recollections list.
+ //
+ void
+ collect_deviated_dependent (const pkg_build_options&,
+ const existing_dependent&,
+ package_key orig_dependency,
+ replaced_versions&,
+ postponed_packages& postponed_recs,
+ postponed_configurations&);
+
struct package_ref
{
database& db;
@@ -1536,7 +1508,7 @@ namespace bpkg
bool reorder);
// Skip the dependents collection/ordering for the specified dependency if
- // that has already be done.
+ // that has already been done.
//
// Note that if this function has already been called for this dependency,
// then all its dependents are already in the map and the dependency
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 243d713..fa3d762 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -1697,7 +1697,7 @@ namespace bpkg
// will modify the cached instance, which means our list will always "see"
// their updated state.
//
- // Also note that rep_fetch() must be called in session.
+ // Also note that rep_fetch() and pkg_fetch() must be called in session.
//
session ses;
@@ -3891,7 +3891,6 @@ namespace bpkg
replaced_versions replaced_vers;
postponed_dependencies postponed_deps;
- postponed_positions postponed_poss;
unacceptable_alternatives unacceptable_alts;
// Map the repointed dependents to the replacement flags (see
@@ -3959,12 +3958,12 @@ namespace bpkg
// during the package collection) because we want to enter them before
// collect_build_postponed() and they could be the dependents that have
// the config clauses. In a sense, change to replaced_vers,
- // postponed_deps, or postponed_poss maps should not affect the deps
+ // postponed_deps, or unacceptable_alts maps should not affect the deps
// list. But not the other way around: a dependency erased from the deps
// list could have caused an entry in the replaced_vers, postponed_deps,
- // and/or postponed_poss maps. And so we clean replaced_vers,
- // postponed_deps, and postponed_poss on scratch_exe (scratch during the
- // plan execution).
+ // and/or unacceptable_alts maps. And so we clean replaced_vers,
+ // postponed_deps, and unacceptable_alts on scratch_exe (scratch during
+ // the plan execution).
//
for (bool refine (true), scratch_exe (true), scratch_col (false);
refine; )
@@ -4172,11 +4171,13 @@ namespace bpkg
}
});
- postponed_packages postponed_repo;
- postponed_packages postponed_alts;
- postponed_configurations postponed_cfgs;
- strings postponed_cfgs_history;
- unsatisfied_dependents unsatisfied_depts;
+ postponed_packages postponed_repo;
+ postponed_packages postponed_alts;
+ postponed_packages postponed_recs;
+ postponed_existing_dependencies postponed_edeps;
+ postponed_configurations postponed_cfgs;
+ strings postponed_cfgs_history;
+ unsatisfied_dependents unsatisfied_depts;
try
{
@@ -4188,7 +4189,6 @@ namespace bpkg
{
replaced_vers.clear ();
postponed_deps.clear ();
- postponed_poss.clear ();
unacceptable_alts.clear ();
scratch_exe = false;
@@ -4206,12 +4206,6 @@ namespace bpkg
pd.second.with_config = false;
}
- for (auto& pd: postponed_poss)
- {
- pd.second.skipped = false;
- pd.second.reevaluated = false;
- }
-
scratch_col = false;
}
@@ -4244,14 +4238,7 @@ namespace bpkg
// specify packages on the command line does not matter).
//
for (const build_package& p: hold_pkgs)
- pkgs.collect_build (o,
- p,
- find_prereq_database,
- rpt_depts,
- add_priv_cfg,
- true /* initial_collection */,
- replaced_vers,
- postponed_cfgs);
+ pkgs.collect_build (o, p, replaced_vers, postponed_cfgs);
// Collect all the prerequisites of the user selection.
//
@@ -4270,17 +4257,18 @@ namespace bpkg
o,
p.db,
p.name (),
+ true /* initial_collection */,
find_prereq_database,
- rpt_depts,
add_priv_cfg,
- true /* initial_collection */,
+ rpt_depts,
replaced_vers,
postponed_repo,
postponed_alts,
0 /* max_alt_index */,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts);
}
else
@@ -4332,9 +4320,10 @@ namespace bpkg
replaced_vers,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
- postponed_poss,
unacceptable_alts,
find_prereq_database,
add_priv_cfg);
@@ -4361,6 +4350,11 @@ namespace bpkg
}
else
{
+ // Wouldn't be here otherwise.
+ //
+ assert (postponed_deps.find (package_key {ddb, d.name}) ==
+ postponed_deps.end ());
+
shared_ptr<selected_package> sp (
ddb.find<selected_package> (d.name));
@@ -4408,17 +4402,18 @@ namespace bpkg
//
pkgs.collect_build (o,
move (p),
- find_prereq_database,
- rpt_depts,
- add_priv_cfg,
- true /* initial_collection */,
replaced_vers,
postponed_cfgs,
&dep_chain,
+ true /* initial_collection */,
+ find_prereq_database,
+ add_priv_cfg,
+ &rpt_depts,
&postponed_repo,
&postponed_alts,
+ &postponed_recs,
+ &postponed_edeps,
&postponed_deps,
- &postponed_poss,
&unacceptable_alts);
}
}
@@ -4446,18 +4441,24 @@ namespace bpkg
// Handle the (combined) postponed collection.
//
- if (!postponed_repo.empty () ||
- !postponed_alts.empty () ||
- postponed_deps.has_bogus () ||
+ if (find_if (postponed_recs.begin (), postponed_recs.end (),
+ [] (const build_package* p)
+ {
+ return !p->recursive_collection;
+ }) != postponed_recs.end () ||
+ !postponed_repo.empty () ||
+ !postponed_alts.empty () ||
+ postponed_deps.has_bogus () ||
!postponed_cfgs.empty ())
pkgs.collect_build_postponed (o,
replaced_vers,
postponed_repo,
postponed_alts,
+ postponed_recs,
+ postponed_edeps,
postponed_deps,
postponed_cfgs,
postponed_cfgs_history,
- postponed_poss,
unacceptable_alts,
find_prereq_database,
rpt_depts,
@@ -4467,12 +4468,6 @@ namespace bpkg
// (see replaced_versions for details).
//
replaced_vers.cancel_bogus (trace, true /* scratch */);
-
- // Erase the bogus existing dependent re-evaluation postponements
- // and re-collect from scratch, if any (see postponed_positions for
- // details).
- //
- postponed_poss.cancel_bogus (trace);
}
catch (const scratch_collection& e)
{
@@ -4552,6 +4547,16 @@ namespace bpkg
}
}
+ for (build_package* p: postponed_recs)
+ {
+ assert (p->recursive_collection);
+
+ pkgs.order (p->db,
+ p->name (),
+ nullopt /* buildtime */,
+ find_prereq_database);
+ }
+
// Collect and order all the dependents that we will need to
// reconfigure because of the up/down-grades of packages that are now
// on the list.
@@ -4589,6 +4594,32 @@ namespace bpkg
}
}
+ // Make sure all the postponed dependencies of existing dependents
+ // have been collected and fail if that's not the case.
+ //
+ for (const auto& pd: postponed_edeps)
+ {
+ const build_package* p (pkgs.entered_build (pd.first));
+ assert (p != nullptr && p->available != nullptr);
+
+ if (!p->recursive_collection)
+ {
+ // Feels like this shouldn't happen but who knows.
+ //
+ diag_record dr (fail);
+ dr << "package " << p->available_name_version_db () << " is not "
+ << "built due to its configured dependents deviation in "
+ << "dependency resolution" <<
+ info << "deviated dependents:";
+
+ for (const package_key& d: pd.second)
+ dr << ' ' << d;
+
+ dr << info << "please report in "
+ << "https://github.com/build2/build2/issues/302";
+ }
+ }
+
#ifndef NDEBUG
pkgs.verify_ordering ();
#endif
@@ -4959,10 +4990,10 @@ namespace bpkg
// that the build-time dependency configuration type (host or
// build2) differs from the dependent configuration type (target
// is a common case) and doesn't work well, for example, for the
- // self-hosted configurations. For them it can fail
- // erroneously. We can potentially fix that by additionally
- // storing the build-time flag for a prerequisite. However, let's
- // first see if it ever becomes a problem.
+ // self-hosted configurations. For them it can fail erroneously.
+ // We can potentially fix that by additionally storing the
+ // build-time flag for a prerequisite. However, let's first see if
+ // it ever becomes a problem.
//
prerequisites r;
const package_prerequisites& prereqs (sp->prerequisites);
@@ -5630,8 +5661,8 @@ namespace bpkg
// 1. sys-install not installed system/distribution
// 2. disfigure up/down-graded, reconfigured [left to right]
// 3. purge up/down-graded [right to left]
- // 4.a fetch/unpack new, up/down-graded
- // 4.b checkout new, up/down-graded
+ // 4.a fetch/unpack new, up/down-graded, replaced
+ // 4.b checkout new, up/down-graded, replaced
// 5. configure all
// 6. unhold unheld
// 7. build user selection [right to left]
@@ -5699,13 +5730,14 @@ namespace bpkg
database& db (p.db);
- // Note: don't update the re-evaluated dependent unless it is
- // reconfigured.
+ // Note: don't update the re-evaluated and re-collected dependents
+ // unless they are reconfigured.
//
if ((*p.action == build_package::adjust && p.reconfigure ()) ||
(*p.action == build_package::build &&
- ((p.flags & build_package::build_repoint) != 0 ||
- ((p.flags & build_package::build_reevaluate) != 0 &&
+ ((p.flags & build_package::build_repoint) != 0 ||
+ ((p.flags & (build_package::build_reevaluate |
+ build_package::build_recollect)) != 0 &&
p.reconfigure ()))))
upkgs.push_back (pkg_command_vars {db.config_orig,
!multi_config () && db.main (),
diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx
index 57ac5ac..53c104e 100644
--- a/bpkg/pkg-configure.cxx
+++ b/bpkg/pkg-configure.cxx
@@ -58,6 +58,7 @@ namespace bpkg
tracer_guard tg (db, trace);
package_prerequisites prereqs;
+ vector<size_t> dep_alts;
strings vars;
// Notes on the buildfile clauses evaluation:
@@ -88,46 +89,9 @@ namespace bpkg
// on some previous pkg-build run when this package and its dependencies
// have been configured. But because of this we may not evaluate the
// enable and reflect clauses which refer to dependency configuration
- // variables. Thus, for now we fail if such an enable or reflect clause
- // is encountered and evaluate all the enable and reflect clauses
- // otherwise. In the future it feels like such cases should somehow
- // be handled at the pkg-build level (e.g., detect such situations and
- // cause the dependent re-evaluation instead of re-configuration). Note
- // that if/when this is implemented, the current logic could still be
- // used as an optimization (reflection of dependency configuration is
- // not very common).
- //
- // @@ It seems there is a hole in the reconfiguration mode:
- //
- // foo -> libfoo {prefer {config.libfoo.proto=1} accept(true)
- // reflect {config.foo.reflect=1}} |
- // libfoo {prefer {config.libfoo.proto=2} accept(true)
- // reflect {config.foo.reflect=2}}
- // -> libbar {prefer {config.libbar.proto=$config.libfoo.proto}
- // accept (config.libbar.proto=2)}
- // -> libbaz
- //
- // foo is configured with config.foo.reflect=2 initially.
- //
- // If afterwords libbaz is upgraded, the foo is reconfigured with
- // config.foo.reflect=1 just because we erroneously pick the first
- // libfoo alternative (which has been banned by libbar accept clause
- // on the previous pkg-build run during negotiation).
- //
- // It feels more and more that the proper solution here is to go
- // "nuclear" and to always "upgrade" re-configuration for a package
- // with any prefer/require into a complete re-evaluation. The most
- // likely drawback of this approach would be unnecessary
- // re-evaluations if we use the "any prefer/require in any
- // alternative" condition. So we may need to exclude some common
- // simple cases where such an upgrade is not needed. For example:
- //
- // foo -> libfoo require {config.libfoo.proto=1}
- // foo -> libbar require {config.libbar.proto=1}
- // foo -> libbaz
- //
- // Feels like the condition will have to be based on the presence
- // of clauses plus their textual analysis.
+ // variables. If such clauses are present, then this is considered an
+ // implementation error since such packages should be handled in the
+ // above pre-selected alternatives mode.
//
bool manual (alts == nullptr && prev_prereqs == nullptr);
@@ -152,7 +116,8 @@ namespace bpkg
{
fail << "unable to reconfigure dependent " << ps.package.name
<< " with " << what << " clause that refers to dependency "
- << "configuration variables";
+ << "configuration variables" <<
+ info << "please report in https://github.com/build2/build2/issues/302";
}
}
};
@@ -162,6 +127,8 @@ namespace bpkg
//
assert (alts == nullptr || alts->size () == deps.size ());
+ dep_alts.reserve (deps.size ());
+
for (size_t di (0); di != deps.size (); ++di)
{
// Skip the toolchain build-time dependencies and dependencies without
@@ -170,7 +137,10 @@ namespace bpkg
const dependency_alternatives_ex& das (deps[di]);
if (das.empty ())
+ {
+ dep_alts.push_back (0);
continue;
+ }
small_vector<pair<reference_wrapper<const dependency_alternative>,
size_t>,
@@ -179,7 +149,10 @@ namespace bpkg
if (alts == nullptr)
{
if (toolchain_buildtime_dependency (o, das, &ps.package.name))
+ {
+ dep_alts.push_back (0);
continue;
+ }
for (size_t i (0); i != das.size (); ++i)
{
@@ -205,7 +178,10 @@ namespace bpkg
}
if (edas.empty ())
+ {
+ dep_alts.push_back (0);
continue;
+ }
}
else
{
@@ -226,6 +202,8 @@ namespace bpkg
// the "make dependency decisions" mode and select the alternative
// regardless of the former prerequisites.
//
+ assert (!edas.empty ());
+
for (const vector<package_name>* pps (prev_prereqs);;)
{
const pair<reference_wrapper<const dependency_alternative>,
@@ -234,7 +212,6 @@ namespace bpkg
for (const auto& eda: edas)
{
const dependency_alternative& da (eda.first);
- size_t dai (eda.second);
// Cache the selected packages which correspond to the alternative
// dependencies, pairing them with the respective constraints. If
@@ -297,13 +274,9 @@ namespace bpkg
// See the package_prerequisites definition for details on
// creating the map keys with the database passed.
//
- bool conf (da.prefer || da.require);
-
prerequisites.emplace_back (
lazy_shared_ptr<selected_package> (pdb, dp),
- prerequisite_info {*dc,
- make_pair (conf ? di + 1 : 0,
- conf ? dai + 1 : 0)});
+ prerequisite_info {*dc});
}
// Try the next alternative if there are unresolved dependencies for
@@ -342,15 +315,6 @@ namespace bpkg
if (s2 && !s1)
c1 = c2;
-
- // Keep position of the first dependency alternative with a
- // configuration clause.
- //
- pair<size_t, size_t>& p1 (p.first->second.config_position);
- pair<size_t, size_t> p2 (pi.config_position);
-
- if (p1.first == 0 && p2.first != 0)
- p1 = p2;
}
// If the prerequisite is configured in the linked configuration,
@@ -480,6 +444,8 @@ namespace bpkg
make_pair (di, selected_alt->second));
}
+ dep_alts.push_back (selected_alt->second + 1);
+
// The dependency alternative is selected and its dependencies are
// resolved to the selected packages. So proceed to the next depends
// value.
@@ -488,6 +454,10 @@ namespace bpkg
}
}
+ // Make sure we didn't miss any selected dependency alternative.
+ //
+ assert (dep_alts.size () == deps.size ());
+
// Add the rest of the configuration variables (user overrides, reflects,
// etc) as well as their sources.
//
@@ -518,6 +488,7 @@ namespace bpkg
}
return configure_prerequisites_result {move (prereqs),
+ move (dep_alts),
move (vars),
move (srcs),
move (checksum)};
@@ -633,8 +604,14 @@ namespace bpkg
l4 ([&]{trace << "src_root: " << src_root << ", "
<< "out_root: " << out_root;});
- assert (p->prerequisites.empty ());
+ assert (p->prerequisites.empty () && p->dependency_alternatives.empty ());
+
p->prerequisites = move (cpr.prerequisites);
+ p->dependency_alternatives = move (cpr.dependency_alternatives);
+
+ // Mark the section as loaded, so dependency alternatives are updated.
+ //
+ p->dependency_alternatives_section.load ();
// Configure.
//
diff --git a/bpkg/pkg-configure.hxx b/bpkg/pkg-configure.hxx
index 876d11a..cd74786 100644
--- a/bpkg/pkg-configure.hxx
+++ b/bpkg/pkg-configure.hxx
@@ -43,12 +43,13 @@ namespace bpkg
bool buildtime);
// Given dependencies of a package, return its prerequisite packages,
- // configuration variables that resulted from selection of these
- // prerequisites (import, reflection, etc), and sources of the configuration
- // variables resulted from evaluating the reflect clauses. Fail if for some
- // of the dependency alternative lists there is no satisfactory alternative
- // (all its dependencies are configured, satisfy the respective constraints,
- // etc).
+ // 1-based indexes of the selected dependency alternatives (0 for toolchain
+ // build-time dependencies, etc), configuration variables that resulted from
+ // selection of these prerequisites (import, reflection, etc), and sources
+ // of the configuration variables resulted from evaluating the reflect
+ // clauses. Fail if for some of the dependency alternative lists there is no
+ // satisfactory alternative (all its dependencies are configured, satisfy
+ // the respective constraints, etc).
//
// The package dependency constraints are expected to be complete.
//
@@ -101,8 +102,9 @@ namespace bpkg
//
struct configure_prerequisites_result
{
- package_prerequisites prerequisites;
- strings config_variables; // Note: name and value.
+ package_prerequisites prerequisites;
+ vector<size_t> dependency_alternatives;
+ strings config_variables; // Note: name and value.
// Only contains sources of configuration variables collected using the
// package skeleton, excluding those user-specified variables which are
diff --git a/bpkg/pkg-disfigure.cxx b/bpkg/pkg-disfigure.cxx
index af2c4f1..2239314 100644
--- a/bpkg/pkg-disfigure.cxx
+++ b/bpkg/pkg-disfigure.cxx
@@ -72,6 +72,11 @@ namespace bpkg
// Since we are no longer configured, clear the prerequisites list.
//
p->prerequisites.clear ();
+ p->dependency_alternatives.clear ();
+
+ // Mark the section as loaded, so dependency alternatives are updated.
+ //
+ p->dependency_alternatives_section.load ();
assert (p->src_root); // Must be set since unpacked.
assert (p->out_root); // Must be set since configured.
diff --git a/tests/common/dependency-alternatives/t11a/biz-0.1.0.tar.gz b/tests/common/dependency-alternatives/t11a/biz-0.1.0.tar.gz
new file mode 100644
index 0000000..b42dff0
--- /dev/null
+++ b/tests/common/dependency-alternatives/t11a/biz-0.1.0.tar.gz
Binary files differ
diff --git a/tests/common/dependency-alternatives/t11a/bus-0.1.0.tar.gz b/tests/common/dependency-alternatives/t11a/bus-0.1.0.tar.gz
new file mode 100644
index 0000000..e486d37
--- /dev/null
+++ b/tests/common/dependency-alternatives/t11a/bus-0.1.0.tar.gz
Binary files differ
diff --git a/tests/common/dependency-alternatives/t11a/libbiz-0.1.0.tar.gz b/tests/common/dependency-alternatives/t11a/libbiz-0.1.0.tar.gz
new file mode 100644
index 0000000..429dc0d
--- /dev/null
+++ b/tests/common/dependency-alternatives/t11a/libbiz-0.1.0.tar.gz
Binary files differ
diff --git a/tests/common/dependency-alternatives/t11a/libbiz-1.0.0.tar.gz b/tests/common/dependency-alternatives/t11a/libbiz-1.0.0.tar.gz
new file mode 100644
index 0000000..250f110
--- /dev/null
+++ b/tests/common/dependency-alternatives/t11a/libbiz-1.0.0.tar.gz
Binary files differ
diff --git a/tests/common/dependency-alternatives/t8a/tpx-1.0.0.tar.gz b/tests/common/dependency-alternatives/t8a/tpx-1.0.0.tar.gz
new file mode 100644
index 0000000..aa8db1d
--- /dev/null
+++ b/tests/common/dependency-alternatives/t8a/tpx-1.0.0.tar.gz
Binary files differ
diff --git a/tests/common/dependency-alternatives/t8a/twx-1.0.0.tar.gz b/tests/common/dependency-alternatives/t8a/twx-1.0.0.tar.gz
new file mode 100644
index 0000000..03e8fbb
--- /dev/null
+++ b/tests/common/dependency-alternatives/t8a/twx-1.0.0.tar.gz
Binary files differ
diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript
index be5a9f8..ee4ea99 100644
--- a/tests/pkg-build.testscript
+++ b/tests/pkg-build.testscript
@@ -148,9 +148,9 @@
# | |-- libbox-1.0.0.tar.gz
# | |-- libfoo-1.0.0.tar.gz
# | |-- libfoo-2.0.0.tar.gz
-# | |-- bar -> libbar
-# | |-- baz -> libbaz
-# | |-- box -> libbiz ^1.0.0 config.box.backend=libbiz |
+# | |-- bar-1.0.0.tar.gz -> libbar
+# | |-- baz-1.0.0.tar.gz -> libbaz
+# | |-- box-1.0.0.tar.gz -> libbiz ^1.0.0 config.box.backend=libbiz |
# | | libbox >= 0.1.1 config.box.backend=libbox,
# | | libbaz
# | |-- fax-1.0.0.tar.gz -> libbar ^1.0.0 ? ($cxx.target.class == 'windows') config.fax.backend=libbar |
@@ -160,13 +160,19 @@
# | |-- fix-1.0.0.tar.gz -> libbaz ^1.0.0 | libbar ^1.0.0
# | |-- foo-1.0.0.tar.gz -> {libbar libbaz} ^1.0.0
# | |-- fox-1.0.0.tar.gz -> libbar ^1.0.0 | libbaz ^1.0.0
-# | |-- fux -> libbiz ? (!$config.fux.libbiz_old) | libbiz ^0.1.0 ? ($config.fux.libbiz_old)
-# | |-- tax -> libfoo == 1.0.0 | libfoo == 2.0.0
-# | |-- tex -> libfoo {prefer{} accept(false) reflect {...}}
-# | |-- tix -> libfoo >= 2.0.0 reflect {...} | libfoo >= 1.0.0 reflect {...}
-# | |-- tox -> libfoo >= 2.0.0 {prefer{} accept(false) reflect {...}} | libfoo >= 1.0.0 reflect {...}
-# | |-- tux -> libfoo {prefer{config.libfoo.protocol = "1"} accept(false)
-# | | -> libbox ? (config.libfoo.protocol == "1")
+# | |-- fux-1.0.0.tar.gz -> libbiz ? (!$config.fux.libbiz_old) | libbiz ^0.1.0 ? ($config.fux.libbiz_old)
+# | |-- tax-1.0.0.tar.gz -> libfoo == 1.0.0 | libfoo == 2.0.0
+# | |-- tex-1.0.0.tar.gz -> libfoo prefer{} accept(true) reflect {...}
+# | |-- tix-1.0.0.tar.gz -> libfoo >= 2.0.0 reflect {...} | libfoo >= 1.0.0 reflect {...}
+# | |-- tox-1.0.0.tar.gz -> libfoo >= 2.0.0 prefer{} accept(true) reflect {...} | libfoo >= 1.0.0 reflect {...}
+# | |-- tpx-1.0.0.tar.gz -> libfoo >= 2.0.0 prefer{...} accept(true) reflect {...} | libfoo >= 1.0.0 prefer{...} accept(true) reflect {...}
+# | |-- tux-1.0.0.tar.gz -> libfoo prefer{config.libfoo.protocol = "1"} accept(true),
+# | | libbox ? (config.libfoo.protocol == "1")
+# | |-- twx-1.0.0.tar.gz -> libbiz,
+# | | libfoo prefer{config.libfoo.protocol = "1"} accept(true),
+# | | libbox ? (config.libfoo.protocol == "1")
+# | |-- tvx-1.0.0.tar.gz -> libfoo >= 2.0.0 reflect {...} | libfoo >= 1.0.0 reflect {...},
+# | | libfox prefer{config.libfox.level = $config.tvx.reflect} accept(true)
# | `-- repositories.manifest
# |
# |-- t9
@@ -191,6 +197,8 @@
# | |-- libbaz-1.0.0.tar.gz
# | |-- libbox-0.1.0.tar.gz
# | |-- libbox-1.0.0.tar.gz
+# | |-- libbiz-0.1.0.tar.gz
+# | |-- libbiz-1.0.0.tar.gz -> libbar
# | |-- foo-0.1.0.tar.gz -> libfoo {require {config.libfoo.extras=true}}
# | |-- foo-0.2.0.tar.gz -> libfoo {require {config.libfoo.extras=true}} | libbar
# | |-- foo-1.0.0.tar.gz -> libfoo {require {config.libfoo.extras=true}}
@@ -201,6 +209,7 @@
# | | libbar {require {config.libbar.extras=true}}
# | |-- fox-1.0.0.tar.gz -> libfoo {require {config.libfoo.extras=true}}
# | |-- fux-1.0.0.tar.gz -> libfoo
+# | |-- fix-0.1.0.tar.gz -> foo == 0.1.0
# | |-- fix-1.0.0.tar.gz -> foo {require {config.foo.extras=true}}
# | |-- fex-1.0.0.tar.gz -> foo, libfoo {require {config.libfoo.extras=true}}
# | |-- bar-0.1.0.tar.gz -> libbar == 0.1.0 {require {config.libbar.extras=true}}
@@ -213,6 +222,7 @@
# | |-- bat-1.0.0.tar.gz -> libbaz {require {config.libbaz.extras=true}}
# | |-- bas-1.0.0.tar.gz -> libbar {require {config.libbar.extras=true}},
# | | bus {require {config.bus.extras=true}}
+# | |-- bus-0.1.0.tar.gz -> foo {require {config.foo.extras=true}}
# | |-- bus-1.0.0.tar.gz -> libaz {require {config.libbox.extras=true}},
# | | foo {require {config.foo.extras=true}}
# | |-- box-0.1.0.tar.gz -> libbox {require {config.libbox.extras=true}}
@@ -225,6 +235,7 @@
# | | bux
# | |-- bex-1.0.0.tar.gz -> libbar
# | |-- boo-1.0.0.tar.gz -> libbar | libfoo {require {config.libfoo.extras=true}} | libbox
+# | |-- biz-0.1.0.tar.gz -> libbiz == 0.1.0
# | |-- biz-1.0.0.tar.gz -> boo {require {config.boo.extras=true}}
# | |-- buz-1.0.0.tar.gz -> bux {require {config.bux.extras=true}}
# | |-- buc-1.0.0.tar.gz -> libfoo {require {config.libfoo.extras=true}},
@@ -5191,7 +5202,7 @@ test.arguments += --sys-no-query
$pkg_drop tix
}
- : fail-select-alt-with-reflect
+ : select-alt-with-reflect
:
{
$clone_cfg;
@@ -5209,103 +5220,217 @@ test.arguments += --sys-no-query
%.*
EOO
- # @@ Note that the current behavior should actually be considered as a
- # bug which we will fix eventually. The proper behaviour would be
- # to re-evaluate this dependent rather than just to re-configure.
- #
- $* ?libfoo 2>>~%EOE% != 0;
- error: unable to reconfigure dependent tox with reflect clause that refers to dependency configuration variables
- info: while configuring tox
+ $* ?libfoo 2>>~%EOE%;
+ disfigured tox/1.0.0
+ disfigured libfoo/1.0.0
+ fetched libfoo/2.0.0
+ unpacked libfoo/2.0.0
+ configured libfoo/2.0.0
+ configured tox/1.0.0
+ %info: .+tox-1.0.0.+ is up to date%
+ updated tox/1.0.0
EOE
$pkg_status -r >>EOO;
!tox configured 1.0.0
- libfoo configured !1.0.0 available 2.0.0
+ libfoo configured 2.0.0
EOO
cat cfg/tox-1.0.0/build/config.build >>~%EOO%;
%.*
- config.tox.libfoo_protocol = '1 or 2'
+ config.tox.libfoo_protocol = 2
%.*
EOO
$pkg_drop tox
}
- : fail-enable-banned-var
+ : re-evaluate-from
:
{
- $clone_cfg;
+ +$clone_cfg
- $* tux ?libbox/0.1.0 2>!;
+ : earlier-depends
+ :
+ {
+ $clone_cfg;
- $pkg_status -r >>EOO;
- !tux configured 1.0.0
- libbox configured !0.1.0 available 1.0.0 0.1.1
- libfoo configured 2.0.0
- EOO
+ $* tux ?libbox/0.1.0 2>!;
- $* ?libbox 2>>EOE != 0;
- error: unable to reconfigure dependent tux with enable clause that refers to dependency configuration variables
- info: while configuring tux
- EOE
+ $pkg_status -r >>EOO;
+ !tux configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0 0.1.1
+ libfoo configured 2.0.0
+ EOO
- $pkg_status -r >>EOO;
- !tux configured 1.0.0
- libbox configured !0.1.0 available 1.0.0 0.1.1
- libfoo configured 2.0.0
- EOO
+ cat cfg/libfoo-2.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfoo.protocol = 1
+ %.*
+ EOO
+
+ $* ?libbox 2>>~%EOE%;
+ disfigured tux/1.0.0
+ disfigured libbox/0.1.0
+ fetched libbox/1.0.0
+ unpacked libbox/1.0.0
+ configured libbox/1.0.0
+ configured tux/1.0.0
+ %info: .+tux-1.0.0.+ is up to date%
+ updated tux/1.0.0
+ EOE
+
+ $pkg_status -r >>EOO;
+ !tux configured 1.0.0
+ libbox configured 1.0.0
+ libfoo configured 2.0.0
+ EOO
+
+ cat cfg/libfoo-2.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfoo.protocol = 1
+ %.*
+ EOO
+
+ $pkg_drop tux
+ }
+
+ : later-depends
+ :
+ {
+ $clone_cfg;
+
+ $* twx ?libbiz/0.1.0 2>!;
+
+ $pkg_status -r >>EOO;
+ !twx configured 1.0.0
+ libbiz configured !0.1.0 available 1.0.0
+ libbox configured 1.0.0
+ libfoo configured 2.0.0
+ EOO
+
+ cat cfg/libfoo-2.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfoo.protocol = 1
+ %.*
+ EOO
+
+ $* ?libbiz 2>>~%EOE%;
+ disfigured twx/1.0.0
+ disfigured libbiz/0.1.0
+ fetched libbiz/1.0.0
+ unpacked libbiz/1.0.0
+ configured libbiz/1.0.0
+ configured twx/1.0.0
+ %info: .+twx-1.0.0.+ is up to date%
+ updated twx/1.0.0
+ EOE
+
+ $pkg_status -r >>EOO;
+ !twx configured 1.0.0
+ libbiz configured 1.0.0
+ libbox configured 1.0.0
+ libfoo configured 2.0.0
+ EOO
+
+ cat cfg/libfoo-2.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfoo.protocol = 1
+ %.*
+ EOO
+
+ $pkg_drop twx
+ }
+
+ : same-depends
+ :
+ {
+ $clone_cfg;
+
+ $* tvx ?libfoo/1.0.0 2>!;
+
+ $pkg_status -r >>EOO;
+ !tvx configured 1.0.0
+ libfoo configured !1.0.0 available 2.0.0
+ libfox configured 1.0.0
+ EOO
+
+ cat cfg/libfox-1.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfox.level = 1
+ %.*
+ EOO
+
+ $* ?libfoo 2>>~%EOE%;
+ disfigured tvx/1.0.0
+ disfigured libfoo/1.0.0
+ disfigured libfox/1.0.0
+ fetched libfoo/2.0.0
+ unpacked libfoo/2.0.0
+ configured libfox/1.0.0
+ configured libfoo/2.0.0
+ configured tvx/1.0.0
+ %info: .+tvx-1.0.0.+ is up to date%
+ updated tvx/1.0.0
+ EOE
- $pkg_drop tux
+ $pkg_status -r >>EOO;
+ !tvx configured 1.0.0
+ libfoo configured 2.0.0
+ libfox configured 1.0.0
+ EOO
+
+ cat cfg/libfox-1.0.0/build/config.build >>~%EOO%;
+ %.*
+ config.libfox.level = 2
+ %.*
+ EOO
+
+ $pkg_drop tvx
+ }
}
- : dont-re-evaluate-dependent
+ : change-alternative
:
{
$clone_cfg;
- $* tvx ?libfoo/1.0.0 2>!;
+ $* tpx ?libfoo/1.0.0 2>!;
$pkg_status -r >>EOO;
- !tvx configured 1.0.0
+ !tpx configured 1.0.0
libfoo configured !1.0.0 available 2.0.0
- libfox configured 1.0.0
EOO
- cat cfg/libfox-1.0.0/build/config.build >>~%EOO%;
+ cat cfg/tpx-1.0.0/build/config.build >>~%EOO%;
%.*
- config.libfox.level = 1
+ config.tpx.libfoo_protocol = 1
%.*
EOO
- # @@ Note that the current behavior should actually be considered as a
- # bug which we will fix eventually. The proper behaviour would be
- # to re-evaluate this dependent rather than just to re-configure.
- #
$* ?libfoo 2>>~%EOE%;
- disfigured tvx/1.0.0
+ disfigured tpx/1.0.0
disfigured libfoo/1.0.0
fetched libfoo/2.0.0
unpacked libfoo/2.0.0
configured libfoo/2.0.0
- configured tvx/1.0.0
- %info: .+tvx-1.0.0.+ is up to date%
- updated tvx/1.0.0
+ configured tpx/1.0.0
+ %info: .+tpx-1.0.0.+ is up to date%
+ updated tpx/1.0.0
EOE
$pkg_status -r >>EOO;
- !tvx configured 1.0.0
+ !tpx configured 1.0.0
libfoo configured 2.0.0
- libfox configured 1.0.0
EOO
- cat cfg/libfox-1.0.0/build/config.build >>~%EOO%;
+ cat cfg/tpx-1.0.0/build/config.build >>~%EOO%;
%.*
- config.libfox.level = 1
+ config.tpx.libfoo_protocol = 2
%.*
EOO
- $pkg_drop tvx
+ $pkg_drop tpx
}
}
}
@@ -6109,6 +6234,10 @@ test.arguments += --sys-no-query
{
$clone_cfg;
+ # Dependencies:
+ #
+ # foo/1.0.0: depends: libfoo(c)
+ #
$* foo 2>>~%EOE%;
%.*
trace: pkg_build: refine package collection/plan execution from scratch
@@ -6151,11 +6280,17 @@ test.arguments += --sys-no-query
%.*
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: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent foo/1.0.0 due to dependency libfoo/0.1.0
trace: postponed_configurations::add: create {foo^ | libfoo->{foo/1,1}}
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {foo^ | libfoo->{foo/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
trace: collect_build: add foo/1.0.0
trace: collect_build_prerequisites: reeval foo/1.0.0
@@ -6213,13 +6348,18 @@ test.arguments += --sys-no-query
%.*
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: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent foo/1.0.0 due to dependency libfoo/0.1.0
trace: postponed_configurations::add: create {foo^ | libfoo->{foo/1,1}}
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {foo^ | libfoo->{foo/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
%.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
trace: collect_build: add foo/1.0.0
trace: collect_build_prerequisites: reeval foo/1.0.0
%.*
@@ -6273,11 +6413,17 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add libfoo/1.0.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent foo/1.0.0
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent foo/1.0.0 due to dependency libfoo/1.0.0
trace: postponed_configurations::add: create {foo^ | libfoo->{foo/1,1}}
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {foo^ | libfoo->{foo/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
trace: collect_build_prerequisites: reeval foo/1.0.0
%.*
@@ -6310,6 +6456,16 @@ test.arguments += --sys-no-query
trace: pkg_build: refine package collection/plan execution from scratch
%.*
trace: collect_build: add libfoo/1.0.0
+ trace: pkg_build: dep-postpone user-specified libfoo
+ trace: collect_drop: overwrite foo
+ trace: collect_build_postponed (0): begin
+ trace: collect_build_postponed (0): erase bogus postponement libfoo
+ trace: collect_build_postponed (0): bogus postponements erased, throwing
+ trace: pkg_build: collection failed due to bogus dependency collection postponement cancellation, retry from scratch
+ %.*
+ trace: pkg_build: refine package collection/plan execution from scratch
+ %.*
+ trace: collect_build: add libfoo/1.0.0
%.*
trace: collect_build_prerequisites: skip expected to be dropped existing dependent foo of dependency libfoo
trace: collect_build_prerequisites: begin libfoo/1.0.0
@@ -6350,6 +6506,11 @@ test.arguments += --sys-no-query
{
$clone_cfg;
+ # Dependencies:
+ #
+ # foo/1.0.0: depends: libfoo(c)
+ # fox/1.0.0: depends: libfoo(c)
+ #
$* libfoo/0.1.0 foo/1.0.0 fox/1.0.0 2>!;
$pkg_status -r >>EOO;
@@ -6366,14 +6527,26 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add libfoo/1.0.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent foo/1.0.0
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ %.*
+ trace: collect_build_prerequisites: pre-reeval fox/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated fox/1.0.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent foo/1.0.0 due to dependency libfoo/1.0.0
trace: postponed_configurations::add: create {foo^ | libfoo->{foo/1,1}}
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent fox/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent fox/1.0.0 due to dependency libfoo/1.0.0
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {foo^ | libfoo->{foo/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_prerequisites: pre-reeval fox/1.0.0
%.*
+ trace: collect_build_prerequisites: pre-reevaluated fox/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {foo^ | libfoo->{foo/1,1}}
trace: collect_build: add foo/1.0.0
trace: collect_build_prerequisites: reeval foo/1.0.0
%.*
@@ -6381,7 +6554,6 @@ test.arguments += --sys-no-query
trace: postponed_configurations::add: add {foo^ 1,1: libfoo} to {foo^ | libfoo->{foo/1,1}}
trace: collect_build_prerequisites: re-evaluating dependent foo/1.0.0 results in {foo^ | libfoo->{foo/1,1}}
trace: collect_build_prerequisites: re-evaluated foo/1.0.0
- %.*
trace: collect_build: add fox/1.0.0
trace: collect_build_prerequisites: reeval fox/1.0.0
%.*
@@ -6446,56 +6618,214 @@ test.arguments += --sys-no-query
$pkg_drop libfoo foo fox
}
- : postpone-existing
+ : postpone-existing-dependency
:
{
$clone_cfg;
# Dependencies:
#
- # fix/1.0.0: depends: foo(c)
- # foo/1.0.0: depends: libfoo(c)
+ # bus: depends: foo(c)
#
- # fix/0.1.0: depends: foo == 0.1.0
- # foo/0.1.0: depends: libfoo(c)
+ # fix: depends: foo == 0.1.0
#
- $* fix 2>!;
+ # libbiz/1.0.0: depends: libbar
+ # libbiz/0.1.0:
+ #
+ # foo: depends: libfoo(c)
+ #
+ $* bus/0.1.0 2>!;
- $* libfoo/0.1.0 fix/0.1.0 2>>~%EOE%;
+ $pkg_status -r >>EOO;
+ !bus configured !0.1.0 available 1.0.0
+ foo configured 1.0.0
+ libfoo configured 1.0.0
+ EOO
+
+ $* fix/0.1.0 libbiz biz/0.1.0 2>>~%EOE%;
%.*
trace: pkg_build: refine package collection/plan execution from scratch
%.*
- trace: collect_build: add libfoo/0.1.0
trace: collect_build: add fix/0.1.0
+ trace: collect_build: add libbiz/1.0.0
+ trace: collect_build: add biz/0.1.0
+ trace: collect_build_prerequisites: begin fix/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 {foo^ | libfoo->{foo/1,1}}
+ trace: collect_build: add foo/0.1.0
+ info: package fix dependency on (foo == 0.1.0) is forcing downgrade of foo/1.0.0 to 0.1.0
+ trace: collect_build_prerequisites: no cfg-clause for dependency foo/0.1.0 of dependent fix/0.1.0
%.*
- trace: collect_build_prerequisites: begin fix/0.1.0
+ trace: collect_build_prerequisites: pre-reeval bus/0.1.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bus/0.1.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency foo/0.1.0 of existing dependent bus/0.1.0 due to dependency foo/0.1.0
+ trace: postponed_configurations::add: create {bus^ | foo->{bus/1,1}}
+ trace: collect_build_prerequisites: end fix/0.1.0
+ trace: collect_build_prerequisites: begin libbiz/1.0.0
+ %.*
+ trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: no cfg-clause for dependency libbar/1.0.0 of dependent libbiz/1.0.0
+ trace: collect_build_prerequisites: begin libbar/1.0.0
+ trace: collect_build_prerequisites: end libbar/1.0.0
+ trace: collect_build_prerequisites: end libbiz/1.0.0
+ trace: collect_build_prerequisites: begin biz/0.1.0
+ %.*
+ trace: collect_build: pick libbiz/0.1.0 over libbiz/1.0.0
+ trace: collect_build: libbiz/1.0.0 package version needs to be replaced with libbiz/0.1.0
+ trace: pkg_build: collection failed due to package version replacement, retry from scratch
%.*
trace: pkg_build: refine package collection/plan execution from scratch
%.*
- trace: collect_build: add libfoo/0.1.0
trace: collect_build: add fix/0.1.0
+ trace: collect_build: apply version replacement for libbiz/1.0.0
+ trace: collect_build: replacement: libbiz/0.1.0
+ trace: collect_build: add libbiz/0.1.0
+ trace: collect_build: add biz/0.1.0
+ trace: collect_build_prerequisites: begin fix/0.1.0
%.*
- trace: collect_build_prerequisites: skip expected to be built existing dependent foo of dependency libfoo
- trace: collect_build_prerequisites: begin libfoo/0.1.0
- trace: collect_build_prerequisites: end libfoo/0.1.0
+ trace: collect_build: add foo/0.1.0
+ info: package fix dependency on (foo == 0.1.0) is forcing downgrade of foo/1.0.0 to 0.1.0
+ trace: collect_build_prerequisites: dep-postpone dependency foo/0.1.0 of dependent fix/0.1.0
+ trace: collect_build_prerequisites: end fix/0.1.0
+ trace: collect_build_prerequisites: begin libbiz/0.1.0
+ trace: collect_build_prerequisites: end libbiz/0.1.0
+ trace: collect_build_prerequisites: begin biz/0.1.0
+ %.*
+ trace: collect_build_prerequisites: no cfg-clause for dependency libbiz/0.1.0 of dependent biz/0.1.0
+ trace: collect_build_prerequisites: end biz/0.1.0
+ trace: pkg_build: erase bogus postponement foo
+ trace: pkg_build: bogus postponements erased, throwing
+ trace: pkg_build: collection failed due to bogus dependency collection postponement cancellation, retry from scratch
%.*
+ trace: pkg_build: refine package collection/plan execution from scratch
+ %.*
+ trace: collect_build: add fix/0.1.0
+ trace: collect_build: apply version replacement for libbiz/1.0.0
+ trace: collect_build: replacement: libbiz/0.1.0
+ trace: collect_build: add libbiz/0.1.0
+ trace: collect_build: add biz/0.1.0
trace: collect_build_prerequisites: begin fix/0.1.0
%.*
- trace: collect_build: apply version replacement for foo/0.1.0
- trace: collect_build: replacement: foo/0.1.0
trace: collect_build: add foo/0.1.0
info: package fix dependency on (foo == 0.1.0) is forcing downgrade of foo/1.0.0 to 0.1.0
trace: collect_build_prerequisites: no cfg-clause for dependency foo/0.1.0 of dependent fix/0.1.0
%.*
- trace: collect_build_prerequisites: skip being built existing dependent fix of dependency foo
+ trace: collect_build_prerequisites: pre-reeval bus/0.1.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bus/0.1.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency foo/0.1.0 of existing dependent bus/0.1.0 due to dependency foo/0.1.0
+ trace: postponed_configurations::add: create {bus^ | foo->{bus/1,1}}
+ trace: collect_build_prerequisites: end fix/0.1.0
+ trace: collect_build_prerequisites: begin libbiz/0.1.0
+ trace: collect_build_prerequisites: end libbiz/0.1.0
+ trace: collect_build_prerequisites: begin biz/0.1.0
+ %.*
+ trace: collect_build_prerequisites: no cfg-clause for dependency libbiz/0.1.0 of dependent biz/0.1.0
+ trace: collect_build_prerequisites: end biz/0.1.0
+ trace: collect_build_postponed (0): begin
+ trace: collect_build_postponed (1): begin {bus^ | foo->{bus/1,1}}
+ %.*
+ trace: collect_build_prerequisites: pre-reeval bus/0.1.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bus/0.1.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {bus^ | foo->{bus/1,1}}
+ trace: collect_build: add bus/0.1.0
+ trace: collect_build_prerequisites: reeval bus/0.1.0
+ %.*
+ trace: collect_build: pick foo/0.1.0 over foo/1.0.0
+ trace: postponed_configurations::add: add {bus^ 1,1: foo} to {bus^ | foo->{bus/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent bus/0.1.0 results in {bus^ | foo->{bus/1,1}}
+ trace: collect_build_prerequisites: re-evaluated bus/0.1.0
+ trace: collect_build_postponed (1): cfg-negotiate begin {bus^ | foo->{bus/1,1}}
+ %.*
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin foo/0.1.0
%.*
- trace: collect_build: pick libfoo/0.1.0 over libfoo/1.0.0
- trace: collect_build_prerequisites: cannot cfg-postpone dependency libfoo/0.1.0 of dependent foo/0.1.0 (collected prematurely), throwing postpone_dependency
- trace: pkg_build: collection failed due to prematurely collected dependency (libfoo), retry from scratch
+ trace: collect_build: add libfoo/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent foo/0.1.0
+ trace: postponed_configurations::add: create {foo | libfoo->{foo/1,1}}
+ trace: collect_build_prerequisites: postpone foo/0.1.0
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent bus/0.1.0
+ trace: collect_build_prerequisites: resume bus/0.1.0
+ trace: collect_build_prerequisites: end bus/0.1.0
+ trace: collect_build_postponed (1): cfg-negotiate end {bus^ | foo->{bus/1,1}}!
+ trace: collect_build_postponed (2): begin {foo | libfoo->{foo/1,1}}
+ %.*
+ trace: collect_build_postponed (2): skip being built existing dependent foo of dependency libfoo
+ trace: collect_build_postponed (2): cfg-negotiate begin {foo | libfoo->{foo/1,1}}
+ %.*
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
+ trace: collect_build_prerequisites: skip configured libfoo/1.0.0
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent foo/0.1.0
+ trace: collect_build_prerequisites: resume foo/0.1.0
+ trace: collect_build_prerequisites: end foo/0.1.0
+ trace: collect_build_postponed (2): cfg-negotiate end {foo | libfoo->{foo/1,1}}!
+ trace: collect_build_postponed (2): end {foo | libfoo->{foo/1,1}}
+ trace: collect_build_postponed (1): end {bus^ | foo->{bus/1,1}}
+ trace: collect_build_postponed (0): end
+ %.*
+ trace: execute_plan: simulate: yes
+ %.*
+ build plan:
+ downgrade foo/0.1.0 (required by bus, fix)
+ config.foo.extras=true (set by bus)
+ reconfigure bus/0.1.0 (dependent of foo)
+ new fix/0.1.0
+ new libbiz/0.1.0
+ new biz/0.1.0
+ trace: execute_plan: simulate: no
+ %.*
+ EOE
+
+ $pkg_status -r >>EOO;
+ !bus configured !0.1.0 available 1.0.0
+ foo configured 0.1.0 available 1.0.0 0.2.0
+ libfoo configured 1.0.0
+ !fix configured !0.1.0 available 1.0.0
+ foo configured 0.1.0 available 1.0.0 0.2.0
+ libfoo configured 1.0.0
+ !libbiz configured 0.1.0 available 1.0.0
+ !biz configured !0.1.0 available 1.0.0
+ !libbiz configured 0.1.0 available 1.0.0
+ EOO
+
+ $pkg_drop bus fix libbiz biz
+ }
+
+ : postpone-existing
+ :
+ {
+ $clone_cfg;
+
+ # Dependencies:
+ #
+ # fix/1.0.0: depends: foo(c)
+ # foo/1.0.0: depends: libfoo(c)
+ #
+ # fix/0.1.0: depends: foo == 0.1.0
+ # foo/0.1.0: depends: libfoo(c)
+ #
+ $* fix 2>!;
+
+ $* libfoo/0.1.0 fix/0.1.0 2>>~%EOE%;
+ %.*
+ trace: pkg_build: refine package collection/plan execution from scratch
+ %.*
+ trace: collect_build: add libfoo/0.1.0
+ trace: collect_build: add fix/0.1.0
+ %.*
+ trace: collect_build_prerequisites: pre-reeval foo/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated foo/1.0.0: 1,1
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent foo/1.0.0 due to dependency libfoo/0.1.0
+ trace: postponed_configurations::add: create {foo^ | libfoo->{foo/1,1}}
+ %.*
+ trace: collect_build_prerequisites: begin fix/0.1.0
+ %.*
+ trace: collect_build: existing dependent foo/1.0.0 needs to be replaced with foo/0.1.0
+ trace: pkg_build: collection failed due to package version replacement, retry from scratch
%.*
trace: pkg_build: refine package collection/plan execution from scratch
%.*
@@ -6538,6 +6868,13 @@ test.arguments += --sys-no-query
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade libfoo/0.1.0
+ config.libfoo.extras=true (set by foo)
+ downgrade foo/0.1.0 (required by fix)
+ downgrade fix/0.1.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_status -r >>EOO;
@@ -6575,21 +6912,20 @@ test.arguments += --sys-no-query
trace: collect_build: add libfoo/0.1.0
trace: collect_build: add libbar/0.1.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent tex/1.0.0
- trace: postponed_configurations::add: create {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_prerequisites: pre-reeval tex/1.0.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libbar/0.1.0 of existing dependent tex/1.0.0
+ trace: collect_build_prerequisites: pre-reevaluated tex/1.0.0: 1,1
+ trace: collect_build: pick libbar/0.1.0 over libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/0.1.0 of existing dependent tex/1.0.0 due to dependency libfoo/0.1.0
trace: postponed_configurations::add: create {tex^ | libbar->{tex/1,1}}
+ trace: pkg_build: dep-postpone user-specified libbar
trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tex^ | libfoo->{tex/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (1): cannot re-evaluate dependent tex to dependency index 2 due to earlier dependency index 1 in {tex^ | libbar->{tex/1,1}}, skipping {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (0): postpone cfg-negotiation of {tex^ | libfoo->{tex/2,1}}
trace: collect_build_postponed (1): begin {tex^ | libbar->{tex/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tex^ | libbar->{tex/1,1}}
+ trace: collect_build_prerequisites: pre-reeval tex/1.0.0
%.*
+ trace: collect_build_prerequisites: pre-reevaluated tex/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {tex^ | libbar->{tex/1,1}}
trace: collect_build: add tex/1.0.0
trace: collect_build_prerequisites: reeval tex/1.0.0
%.*
@@ -6608,13 +6944,13 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: pick libfoo/0.1.0 over libfoo/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of dependent tex/1.0.0
- trace: postponed_configurations::add: add {tex 2,1: libfoo} to {tex^ | libfoo->{tex/2,1}}
+ trace: postponed_configurations::add: create {tex | libfoo->{tex/2,1}}
trace: collect_build_prerequisites: postpone tex/1.0.0
trace: collect_build_postponed (1): cfg-negotiate end {tex^ | libbar->{tex/1,1}}!
- trace: collect_build_postponed (2): begin {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): begin {tex | libfoo->{tex/2,1}}
%.*
trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libfoo
- trace: collect_build_postponed (2): cfg-negotiate begin {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/2,1}}
%.*
trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin libfoo/0.1.0
@@ -6623,8 +6959,8 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tex/1.0.0
trace: collect_build_prerequisites: resume 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,1}}!
- trace: collect_build_postponed (2): end {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/2,1}}!
+ trace: collect_build_postponed (2): end {tex | libfoo->{tex/2,1}}
trace: collect_build_postponed (1): end {tex^ | libbar->{tex/1,1}}
trace: collect_build_postponed (0): end
%.*
@@ -6636,32 +6972,7 @@ test.arguments += --sys-no-query
downgrade libbar/0.1.0
config.libbar.extras=true (set by tex)
reconfigure tex/1.0.0 (dependent of libbar)
- %.*
- disfigured tex/1.0.0
- %.*
- disfigured libbar/1.0.0
- %.*
- disfigured libfoo/1.0.0
- %.*
- fetched libfoo/0.1.0
- %.*
- unpacked libfoo/0.1.0
- %.*
- fetched libbar/0.1.0
- %.*
- unpacked libbar/0.1.0
- %.*
- configured libfoo/0.1.0
- %.*
- configured libbar/0.1.0
- %.*
- configured tex/1.0.0
- %.*
- updated libfoo/0.1.0
- %.*
- updated libbar/0.1.0
- %.*
- updated tex/1.0.0
+ trace: execute_plan: simulate: no
%.*
EOE
@@ -6697,73 +7008,32 @@ test.arguments += --sys-no-query
trace: collect_build: add libfoo/0.1.0
trace: collect_build: add bar/0.1.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent tex/1.0.0
- trace: postponed_configurations::add: create {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_prerequisites: begin bar/0.1.0
+ trace: collect_build_prerequisites: pre-reeval tex/1.0.0
%.*
- trace: collect_build: add libbar/0.1.0
- info: package bar dependency on (libbar == 0.1.0) is forcing downgrade of libbar/1.0.0 to 0.1.0
- trace: collect_build_prerequisites: cfg-postpone dependency libbar/0.1.0 of dependent bar/0.1.0
- trace: postponed_configurations::add: create {bar | libbar->{bar/1,1}}
- trace: collect_build_prerequisites: postpone bar/0.1.0
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tex^ | libfoo->{tex/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tex^ | libfoo->{tex/2,1}}
- %.*
- trace: collect_build: add tex/1.0.0
- trace: collect_build_prerequisites: reeval tex/1.0.0
- %.*
- trace: collect_build: pick libbar/0.1.0 over libbar/1.0.0
- %.*
- trace: collect_build: pick libfoo/0.1.0 over libfoo/1.0.0
- trace: postponed_configurations::add: add {tex^ 2,1: libfoo} to {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent tex/1.0.0 results in {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_prerequisites: re-evaluated tex/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate begin {tex^ | libfoo->{tex/2,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): select cfg-negotiated dependency alternative for dependent tex/1.0.0
- trace: collect_build_prerequisites: resume tex/1.0.0
- trace: collect_build_prerequisites: end tex/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate end {tex^ | libfoo->{tex/2,1}}!
- trace: collect_build_postponed (2): begin {bar | libbar->{bar/1,1}}
- %.*
- trace: collect_build_postponed (2): re-evaluate existing dependents for {bar | libbar->{bar/1,1}}
- trace: collect_build_postponed (2): cannot re-evaluate dependent tex to dependency index 1 due to greater dependency index 2 in {tex^ | libfoo->{tex/2,1}}!, throwing postpone_position
- trace: pkg_build: collection failed due to earlier dependency position, retry from scratch
- %.*
- trace: pkg_build: refine package collection/plan execution from scratch
- %.*
- trace: collect_build: add libfoo/0.1.0
- trace: collect_build: add bar/0.1.0
- %.*
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of existing dependent tex/1.0.0
- trace: postponed_configurations::add: create {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_prerequisites: pre-reevaluated tex/1.0.0: 1,1
+ trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of existing dependent tex/1.0.0 due to dependency libfoo/0.1.0
+ trace: postponed_configurations::add: create {tex^ | libbar->{tex/1,1}}
trace: collect_build_prerequisites: begin bar/0.1.0
%.*
- trace: collect_build: add libbar/0.1.0
+ trace: collect_build: pick libbar/0.1.0 over libbar/1.0.0
+ trace: collect_build: libbar/1.0.0 package version needs to be replaced in-place with libbar/0.1.0
info: package bar dependency on (libbar == 0.1.0) is forcing downgrade of libbar/1.0.0 to 0.1.0
trace: collect_build_prerequisites: cfg-postpone dependency libbar/0.1.0 of dependent bar/0.1.0
- trace: postponed_configurations::add: create {bar | libbar->{bar/1,1}}
+ trace: postponed_configurations::add: add {bar 1,1: libbar} to {tex^ | libbar->{tex/1,1}}
trace: collect_build_prerequisites: postpone bar/0.1.0
trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (1): begin {bar tex^ | libbar->{bar/1,1 tex/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (1): pos-postpone existing dependent tex re-evaluation to dependency index 2 due to recorded index 1, skipping {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (0): postpone cfg-negotiation of {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (1): begin {bar | libbar->{bar/1,1}}
+ trace: collect_build_prerequisites: pre-reeval tex/1.0.0
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bar | libbar->{bar/1,1}}
+ trace: collect_build_prerequisites: pre-reevaluated tex/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {bar tex^ | libbar->{bar/1,1 tex/1,1}}
trace: collect_build: add tex/1.0.0
trace: collect_build_prerequisites: reeval tex/1.0.0
%.*
trace: collect_build: pick libbar/0.1.0 over libbar/1.0.0
- trace: postponed_configurations::add: add {tex^ 1,1: libbar} to {bar | libbar->{bar/1,1}}
+ trace: postponed_configurations::add: add {tex^ 1,1: libbar} to {bar tex^ | libbar->{bar/1,1 tex/1,1}}
trace: collect_build_prerequisites: re-evaluating dependent tex/1.0.0 results in {bar tex^ | libbar->{bar/1,1 tex/1,1}}
trace: collect_build_prerequisites: re-evaluated tex/1.0.0
trace: collect_build_postponed (1): cfg-negotiate begin {bar tex^ | libbar->{bar/1,1 tex/1,1}}
@@ -6780,13 +7050,13 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: pick libfoo/0.1.0 over libfoo/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libfoo/0.1.0 of dependent tex/1.0.0
- trace: postponed_configurations::add: add {tex 2,1: libfoo} to {tex^ | libfoo->{tex/2,1}}
+ trace: postponed_configurations::add: create {tex | libfoo->{tex/2,1}}
trace: collect_build_prerequisites: postpone tex/1.0.0
trace: collect_build_postponed (1): cfg-negotiate end {bar tex^ | libbar->{bar/1,1 tex/1,1}}!
- trace: collect_build_postponed (2): begin {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): begin {tex | libfoo->{tex/2,1}}
%.*
trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libfoo
- trace: collect_build_postponed (2): cfg-negotiate begin {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/2,1}}
%.*
trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin libfoo/0.1.0
@@ -6795,13 +7065,22 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tex/1.0.0
trace: collect_build_prerequisites: resume 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,1}}!
- trace: collect_build_postponed (2): end {tex^ | libfoo->{tex/2,1}}
- trace: collect_build_postponed (1): end {bar | libbar->{bar/1,1}}
+ trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/2,1}}!
+ trace: collect_build_postponed (2): end {tex | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (1): end {bar tex^ | libbar->{bar/1,1 tex/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade libfoo/0.1.0
+ config.libfoo.extras=true (set by tex)
+ downgrade libbar/0.1.0 (required by bar, tex)
+ config.libbar.extras=true (set by bar)
+ reconfigure tex/1.0.0 (dependent of libbar)
+ new bar/0.1.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_status -r >>EOO;
@@ -6922,49 +7201,22 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add libbox/0.1.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libbox/0.1.0 of existing dependent bax/1.0.0
- trace: postponed_configurations::add: create {bax^ | libbox->{bax/2,1}}
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {bax^ | libbox->{bax/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libbox->{bax/2,1}}
- %.*
- trace: collect_build: add bax/1.0.0
- trace: collect_build_prerequisites: reeval bax/1.0.0
- %.*
- trace: collect_build: add libfoo/1.0.0
- %.*
- trace: collect_build: pick libbox/0.1.0 over libbox/1.0.0
- trace: collect_build: add libbar/1.0.0
- trace: postponed_configurations::add: add {bax^ 2,1: libbox libbar} to {bax^ | libbox->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluated bax/1.0.0
- %.*
- trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- %.*
- trace: collect_build: add baz/1.0.0
- trace: collect_build_prerequisites: reeval baz/1.0.0
- %.*
- trace: postponed_configurations::add: add {baz^ 1,1: libbar libfoo} to {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ | libbox->{bax/2,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}
- trace: collect_build_prerequisites: re-evaluated baz/1.0.0
- %.*
- trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libfoo
- trace: collect_build_postponed (1): cannot re-evaluate dependent bax to dependency index 1 since it is already re-evaluated to greater index 2 in {bax^ baz^ | libbox->{bax/2,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}, throwing postpone_position
- trace: pkg_build: collection failed due to earlier dependency position, retry from scratch
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
%.*
- trace: pkg_build: refine package collection/plan execution from scratch
- %.*
- trace: collect_build: add libbox/0.1.0
- %.*
- trace: collect_build_prerequisites: replace dependency at index 2 of existing dependent bax/1.0.0 with dependency libfoo/1.0.0 at index 1
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
trace: collect_build: add libfoo/1.0.0
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0 due to dependency libbox/0.1.0
trace: postponed_configurations::add: create {bax^ | libfoo->{bax/1,1}}
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ %.*
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
@@ -7000,6 +7252,12 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (0): cfg-negotiation of {bax^ | libfoo->{bax/1,1}} failed due to dependent bax, refining configuration
trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
@@ -7018,7 +7276,6 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libbar
trace: collect_build_postponed (1): cfg-negotiate begin {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
- %.*
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_prerequisites: skip configured libbar/1.0.0
@@ -7045,6 +7302,12 @@ test.arguments += --sys-no-query
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade libbox/0.1.0
+ config.libbox.extras=true (set by bax)
+ reconfigure bax/1.0.0 (dependent of libfoo)
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_status -r >>EOO;
@@ -7092,61 +7355,35 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {box | libbox->{box/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {box | libbox->{box/1,1}}
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
%.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ trace: collect_build: add libfoo/1.0.0
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {box | libbox->{box/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
%.*
- trace: collect_build: add libfoo/1.0.0
- %.*
- trace: collect_build: pick libbox/0.1.0 over libbox/1.0.0
- trace: collect_build: add libbar/1.0.0
- trace: postponed_configurations::add: add {bax^ 2,1: libbox libbar} to {box | libbox->{box/1,1}}
- trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1}}
+ trace: postponed_configurations::add: create {bax^ | libfoo->{bax/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ | libfoo->{bax/1,1}}
trace: collect_build_prerequisites: re-evaluated bax/1.0.0
+ trace: collect_build_postponed (1): cfg-negotiate begin {box | libbox->{box/1,1}}
%.*
- trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1}}
- %.*
- trace: collect_build: add baz/1.0.0
- trace: collect_build_prerequisites: reeval baz/1.0.0
- %.*
- trace: postponed_configurations::add: add {baz^ 1,1: libbar libfoo} to {bax^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}
- trace: collect_build_prerequisites: re-evaluated baz/1.0.0
- %.*
- trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libfoo
- trace: collect_build_postponed (1): cannot re-evaluate dependent bax to dependency index 1 since it is already re-evaluated to greater index 2 in {bax^ baz^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}, throwing postpone_position
- trace: pkg_build: collection failed due to earlier dependency position, retry from scratch
- %.*
- trace: pkg_build: refine package collection/plan execution from scratch
- %.*
- trace: collect_build: add box/0.1.0
- trace: collect_build_prerequisites: begin box/0.1.0
- %.*
- trace: collect_build: add libbox/0.1.0
- info: package box dependency on (libbox == 0.1.0) is forcing downgrade of libbox/1.0.0 to 0.1.0
- trace: collect_build_prerequisites: cfg-postpone dependency libbox/0.1.0 of dependent box/0.1.0
- trace: postponed_configurations::add: create {box | libbox->{box/1,1}}
- trace: collect_build_prerequisites: postpone box/0.1.0
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {box | libbox->{box/1,1}}
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
+ trace: collect_build_prerequisites: begin libbox/0.1.0
+ trace: collect_build_prerequisites: end libbox/0.1.0
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent box/0.1.0
+ trace: collect_build_prerequisites: resume box/0.1.0
+ trace: collect_build_prerequisites: end box/0.1.0
+ trace: collect_build_postponed (1): cfg-negotiate end {box | libbox->{box/1,1}}!
+ trace: collect_build_postponed (2): begin {bax^ | libfoo->{bax/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {box | libbox->{box/1,1}}
- trace: collect_build_postponed (1): pos-postpone existing dependent bax re-evaluation to dependency index 2 due to recorded index 1, skipping {box | libbox->{box/1,1}}
- trace: collect_build_postponed (0): replace dependency at index 2 of existing dependent bax/1.0.0 with dependency libfoo/1.0.0 at index 1
- trace: collect_build: add libfoo/1.0.0
- trace: postponed_configurations::add: create {bax^ | libfoo->{bax/1,1}}
- trace: collect_build_postponed (0): postpone cfg-negotiation of {box | libbox->{box/1,1}}
- trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
+ trace: collect_build_postponed (2): skip being built existing dependent bax of dependency libfoo
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
- trace: collect_build: add bax/1.0.0
- trace: collect_build_prerequisites: reeval bax/1.0.0
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
%.*
- trace: postponed_configurations::add: add {bax^ 1,1: libfoo} to {bax^ | libfoo->{bax/1,1}}
- trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ | libfoo->{bax/1,1}}
- trace: collect_build_prerequisites: re-evaluated bax/1.0.0
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
+ trace: collect_build_postponed (2): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add baz/1.0.0
trace: collect_build_prerequisites: reeval baz/1.0.0
%.*
@@ -7155,50 +7392,58 @@ test.arguments += --sys-no-query
trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
trace: collect_build_prerequisites: re-evaluated baz/1.0.0
%.*
- trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
- trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libbar
- trace: collect_build_postponed (1): cfg-negotiate begin {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
+ trace: collect_build_postponed (2): skip being built existing dependent bax of dependency libbar
+ trace: collect_build_postponed (2): skip being built existing dependent baz of dependency libbar
+ trace: collect_build_postponed (2): cfg-negotiate begin {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
%.*
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_prerequisites: skip configured libbar/1.0.0
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent bax/1.0.0
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent bax/1.0.0
trace: collect_build_prerequisites: resume bax/1.0.0
%.*
trace: collect_build: pick libbox/0.1.0 over libbox/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libbox/0.1.0 of dependent bax/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent bax/1.0.0
- trace: postponed_configurations::add: add {bax 2,1: libbox libbar} to {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}?
- trace: postponed_configurations::add: merge {box | libbox->{box/1,1}} into {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{bax/2,1 baz/1,1} libbox->{bax/2,1}}?
- trace: collect_build_prerequisites: cfg-postponing dependent bax/1.0.0 merges non-negotiated and/or being negotiated configurations in and results in {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbar->{bax/2,1 baz/1,1} libbox->{bax/2,1 box/1,1}}?, throwing merge_configuration
- trace: collect_build_postponed (0): cfg-negotiation of {bax^ | libfoo->{bax/1,1}} failed due to non-negotiated clusters, force-merging based on shadow cluster {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbar->{bax/2,1 baz/1,1} libbox->{bax/2,1 box/1,1}}?
- trace: collect_build_postponed (0): force-merge {box | libbox->{box/1,1}} into {bax^ | libfoo->{bax/1,1}}
- trace: collect_build_postponed (1): begin {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}}
+ trace: postponed_configurations::add: add {bax 2,1: libbox libbar} to {box | libbox->{box/1,1}}!
+ trace: postponed_configurations::add: merge {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}? into {bax box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1}}!
+ trace: collect_build_prerequisites: cfg-postponing dependent bax/1.0.0 merges non-negotiated and/or being negotiated configurations in and results in {bax baz^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1 baz/1,1} libfoo->{bax/1,1 baz/1,1}}!, throwing merge_configuration
+ trace: collect_build_postponed (0): cfg-negotiation of {box | libbox->{box/1,1}} failed due to non-negotiated clusters, force-merging based on shadow cluster {bax baz^ box | libbox->{bax/2,1 box/1,1} libbar->{bax/2,1 baz/1,1} libfoo->{bax/1,1 baz/1,1}}!
+ trace: collect_build_postponed (1): begin {box | libbox->{box/1,1}}
+ %.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}}
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ trace: collect_build: add libfoo/1.0.0
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {box | libbox->{box/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
%.*
- trace: postponed_configurations::add: add {bax^ 1,1: libfoo} to {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}} (shadow cluster-based)
- trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}}
+ trace: postponed_configurations::add: add {bax^ 1,1: libfoo} to {box | libbox->{box/1,1}} (shadow cluster-based)
+ trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ box | libbox->{box/1,1} libfoo->{bax/1,1}}
trace: collect_build_prerequisites: re-evaluated bax/1.0.0
+ %.*
+ trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libfoo
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ box | libbox->{box/1,1} libfoo->{bax/1,1}}
trace: collect_build: add baz/1.0.0
trace: collect_build_prerequisites: reeval baz/1.0.0
%.*
trace: collect_build: add libbar/1.0.0
- trace: postponed_configurations::add: add {baz^ 1,1: libbar libfoo} to {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}} (shadow cluster-based)
- trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbox->{box/1,1} libbar->{baz/1,1}}
+ trace: postponed_configurations::add: add {baz^ 1,1: libbar libfoo} to {bax^ box | libbox->{box/1,1} libfoo->{bax/1,1}} (shadow cluster-based)
+ trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ box | libbox->{box/1,1} libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
trace: collect_build_prerequisites: re-evaluated baz/1.0.0
%.*
trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libbar
- trace: collect_build_postponed (1): cfg-negotiate begin {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbox->{box/1,1} libbar->{baz/1,1}}
- %.*
+ trace: collect_build_postponed (1): cfg-negotiate begin {bax^ baz^ box | libbox->{box/1,1} libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
- trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_prerequisites: begin libbox/0.1.0
trace: collect_build_prerequisites: end libbox/0.1.0
+ trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_prerequisites: skip configured libbar/1.0.0
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent bax/1.0.0
@@ -7207,7 +7452,7 @@ test.arguments += --sys-no-query
trace: collect_build: pick libbox/0.1.0 over libbox/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libbox/0.1.0 of dependent bax/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent bax/1.0.0
- trace: postponed_configurations::add: add {bax 2,1: libbox libbar} to {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbox->{box/1,1} libbar->{baz/1,1}}? (shadow cluster-based)
+ trace: postponed_configurations::add: add {bax 2,1: libbox libbar} to {bax^ baz^ box | libbox->{box/1,1} libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}? (shadow cluster-based)
trace: collect_build_prerequisites: configuration for cfg-postponed dependencies of dependent bax/1.0.0 is shadow-negotiated
trace: collect_build_prerequisites: dependency libbox/0.1.0 of dependent bax/1.0.0 is already (being) recursively collected, skipping
trace: collect_build_prerequisites: dependency libbar/1.0.0 of dependent bax/1.0.0 is already (being) recursively collected, skipping
@@ -7218,12 +7463,19 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent box/0.1.0
trace: collect_build_prerequisites: resume box/0.1.0
trace: collect_build_prerequisites: end box/0.1.0
- trace: collect_build_postponed (1): cfg-negotiate end {bax^ baz^ box | libfoo->{bax/1,1 baz/1,1} libbox->{bax/2,1 box/1,1} libbar->{bax/2,1 baz/1,1}}!
- trace: collect_build_postponed (1): end {bax^ box | libfoo->{bax/1,1} libbox->{box/1,1}}
+ trace: collect_build_postponed (1): cfg-negotiate end {bax^ baz^ box | libbox->{bax/2,1 box/1,1} libfoo->{bax/1,1 baz/1,1} libbar->{bax/2,1 baz/1,1}}!
+ trace: collect_build_postponed (1): end {box | libbox->{box/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade libbox/0.1.0 (required by bax, box)
+ config.libbox.extras=true (set by box)
+ reconfigure bax/1.0.0 (dependent of libbox)
+ new box/0.1.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_status -r >>EOO;
@@ -7261,47 +7513,21 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add libbox/0.1.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency libbox/0.1.0 of existing dependent bax/1.0.0
- trace: postponed_configurations::add: create {bax^ | libbox->{bax/2,1}}
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {bax^ | libbox->{bax/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libbox->{bax/2,1}}
- %.*
- trace: collect_build: add bax/1.0.0
- trace: collect_build_prerequisites: reeval bax/1.0.0
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
%.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
trace: collect_build: add libfoo/1.0.0
- %.*
- trace: collect_build: pick libbox/0.1.0 over libbox/1.0.0
- trace: collect_build: add libbar/1.0.0
- trace: postponed_configurations::add: add {bax^ 2,1: libbox libbar} to {bax^ | libbox->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluated bax/1.0.0
- %.*
- trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
- trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: reeval baz/1.0.0
- %.*
- trace: postponed_configurations::add: add {baz^ 1,1: libbar libfoo} to {bax^ | libbox->{bax/2,1} libbar->{bax/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent baz/1.0.0 results in {bax^ baz^ | libbox->{bax/2,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}
- trace: collect_build_prerequisites: re-evaluated baz/1.0.0
- %.*
- trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libfoo
- trace: collect_build_postponed (1): cannot re-evaluate dependent bax to dependency index 1 since it is already re-evaluated to greater index 2 in {bax^ baz^ | libbox->{bax/2,1} libbar->{bax/2,1 baz/1,1} libfoo->{baz/1,1}}, throwing postpone_position
- trace: pkg_build: collection failed due to earlier dependency position, retry from scratch
- %.*
- trace: pkg_build: refine package collection/plan execution from scratch
- %.*
- trace: collect_build: add libbox/0.1.0
- %.*
- trace: collect_build_prerequisites: replace dependency at index 2 of existing dependent bax/1.0.0 with dependency libfoo/1.0.0 at index 1
- trace: collect_build: add libfoo/1.0.0
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0 due to dependency libbox/0.1.0
trace: postponed_configurations::add: create {bax^ | libfoo->{bax/1,1}}
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
@@ -7336,6 +7562,12 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (0): cfg-negotiation of {bax^ | libfoo->{bax/1,1}} failed due to dependent bax, refining configuration
trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
+ trace: collect_build_prerequisites: pre-reeval baz/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated baz/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add bax/1.0.0
trace: collect_build_prerequisites: reeval bax/1.0.0
@@ -7353,7 +7585,6 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (1): skip being built existing dependent bax of dependency libbar
trace: collect_build_postponed (1): skip being built existing dependent baz of dependency libbar
trace: collect_build_postponed (1): cfg-negotiate begin {bax^ baz^ | libfoo->{bax/1,1 baz/1,1} libbar->{baz/1,1}}
- %.*
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_prerequisites: skip configured libbar/1.0.0
@@ -7401,14 +7632,19 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add libbox/0.1.0
%.*
- trace: collect_build_prerequisites: replace dependency at index 2 of existing dependent bax/1.0.0 with dependency libfoo/1.0.0 at index 1
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
trace: collect_build: add libfoo/1.0.0
- trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of existing dependent bax/1.0.0 due to dependency libbox/0.1.0
trace: postponed_configurations::add: create {bax^ | libfoo->{bax/1,1}}
trace: collect_drop: overwrite baz
trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {bax^ | libfoo->{bax/1,1}}
%.*
+ trace: collect_build_prerequisites: pre-reeval bax/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated bax/1.0.0: 1,1
trace: collect_build_postponed (1): skip being dropped existing dependent baz of dependency libfoo
trace: collect_build_postponed (1): re-evaluate existing dependents for {bax^ | libfoo->{bax/1,1}}
trace: collect_build: add bax/1.0.0
@@ -7418,7 +7654,6 @@ test.arguments += --sys-no-query
trace: collect_build_prerequisites: re-evaluating dependent bax/1.0.0 results in {bax^ | libfoo->{bax/1,1}}
trace: collect_build_prerequisites: re-evaluated bax/1.0.0
trace: collect_build_postponed (1): cfg-negotiate begin {bax^ | libfoo->{bax/1,1}}
- %.*
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
@@ -7439,7 +7674,6 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (2): skip being built existing dependent bax of dependency libbar
trace: collect_build_postponed (2): skip being dropped existing dependent baz of dependency libbar
trace: collect_build_postponed (2): cfg-negotiate begin {bax | libbox->{bax/2,1} libbar->{bax/2,1}}
- %.*
trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin libbox/0.1.0
trace: collect_build_prerequisites: end libbox/0.1.0
@@ -7455,6 +7689,13 @@ test.arguments += --sys-no-query
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade libbox/0.1.0
+ config.libbox.extras=true (set by bax)
+ reconfigure bax/1.0.0 (dependent of libfoo)
+ drop baz/1.0.0 (unused)
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_status -r >>EOO;
@@ -9792,66 +10033,19 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: add tex/0.3.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency tex/0.3.0 of existing dependent tix/1.0.0
- trace: postponed_configurations::add: create {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- %.*
- trace: collect_build: add tix/1.0.0
- trace: collect_build_prerequisites: reeval tix/1.0.0
- %.*
- trace: collect_build: add libbar/1.0.0
- %.*
- trace: collect_build: pick tex/0.3.0 over tex/1.0.0
- trace: postponed_configurations::add: add {tix^ 2,1: tex} to {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: re-evaluated tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | tex->{tix/2,1}}
- %.*
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
- trace: collect_build_prerequisites: begin tex/0.3.0
- %.*
- trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tex/0.3.0
- trace: postponed_configurations::add: create {tex | libbar->{tex/1,1}}
- trace: collect_build_prerequisites: postpone tex/0.3.0
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
- trace: collect_build_prerequisites: resume tix/1.0.0
- trace: collect_build_prerequisites: end tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate end {tix^ | tex->{tix/2,1}}!
- trace: collect_build_postponed (2): begin {tex | libbar->{tex/1,1}}
- %.*
- trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libbar
- trace: collect_build_postponed (2): re-evaluate existing dependents for {tex | libbar->{tex/1,1}}
- trace: collect_build_postponed (2): cannot re-evaluate dependent tix to dependency index 1 due to greater dependency index 2 in {tix^ | tex->{tix/2,1}}!, throwing postpone_position
- trace: pkg_build: collection failed due to earlier dependency position, retry from scratch
- %.*
- trace: pkg_build: refine package collection/plan execution from scratch
- %.*
- trace: collect_build: add tex/0.3.0
- %.*
- trace: collect_build_prerequisites: cfg-postpone dependency tex/0.3.0 of existing dependent tix/1.0.0
- trace: postponed_configurations::add: create {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
- %.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (1): pos-postpone existing dependent tix re-evaluation to dependency index 2 due to recorded index 1, skipping {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (0): postpone cfg-negotiation of {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (0): non-negotiated clusters left and non-replace postponed positions are present, overriding first encountered non-replace position to replace
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (1): pos-postpone existing dependent tix re-evaluation to dependency index 2 due to recorded index 1, skipping {tix^ | tex->{tix/2,1}}
- trace: collect_build_postponed (0): replace dependency at index 2 of existing dependent tix/1.0.0 with dependency libbar/1.0.0 at index 1
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of existing dependent tix/1.0.0 due to dependency tex/0.3.0
trace: postponed_configurations::add: create {tix^ | libbar->{tix/1,1}}
- trace: collect_build_postponed (0): postpone cfg-negotiation of {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (0): begin
trace: collect_build_postponed (1): begin {tix^ | libbar->{tix/1,1}}
%.*
trace: collect_build_postponed (1): skip being built existing dependent tex of dependency libbar
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | libbar->{tix/1,1}}
trace: collect_build: add tix/1.0.0
trace: collect_build_prerequisites: reeval tix/1.0.0
@@ -9869,13 +10063,13 @@ test.arguments += --sys-no-query
%.*
trace: collect_build: pick tex/0.3.0 over tex/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency tex/0.3.0 of dependent tix/1.0.0
- trace: postponed_configurations::add: add {tix 2,1: tex} to {tix^ | tex->{tix/2,1}}
+ trace: postponed_configurations::add: create {tix | tex->{tix/2,1}}
trace: collect_build_prerequisites: postpone tix/1.0.0
trace: collect_build_postponed (1): cfg-negotiate end {tix^ | libbar->{tix/1,1}}!
- trace: collect_build_postponed (2): begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (2): begin {tix | tex->{tix/2,1}}
%.*
trace: collect_build_postponed (2): skip being built existing dependent tix of dependency tex
- trace: collect_build_postponed (2): cfg-negotiate begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2,1}}
%.*
trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin tex/0.3.0
@@ -9893,7 +10087,7 @@ test.arguments += --sys-no-query
trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tix/1.0.0
trace: collect_build_prerequisites: resume tix/1.0.0
trace: collect_build_prerequisites: end tix/1.0.0
- trace: collect_build_postponed (2): cfg-negotiate end {tix^ | tex->{tix/2,1}}!
+ trace: collect_build_postponed (2): cfg-negotiate end {tix | tex->{tix/2,1}}!
trace: collect_build_postponed (3): begin {tex | libfoo->{tex/2,1}}
%.*
trace: collect_build_postponed (3): skip being built existing dependent tex of dependency libfoo
@@ -9907,12 +10101,18 @@ test.arguments += --sys-no-query
trace: collect_build_prerequisites: end tex/0.3.0
trace: collect_build_postponed (3): cfg-negotiate end {tex | libfoo->{tex/2,1}}!
trace: collect_build_postponed (3): end {tex | libfoo->{tex/2,1}}
- trace: collect_build_postponed (2): end {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (2): end {tix | tex->{tix/2,1}}
trace: collect_build_postponed (1): end {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade tex/0.3.0
+ config.tex.extras=true (set by tix)
+ reconfigure tix/1.0.0 (dependent of libbar)
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_drop tex tix
@@ -9946,52 +10146,80 @@ test.arguments += --sys-no-query
trace: collect_build: add tex/0.1.0
trace: collect_build_prerequisites: skip configured tix/1.0.0
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency tex/0.1.0 of existing dependent tix/1.0.0
- trace: postponed_configurations::add: create {tix^ | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of existing dependent tix/1.0.0 due to dependency tex/0.1.0
+ trace: postponed_configurations::add: create {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): begin {tix^ | libbar->{tix/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: reeval tix/1.0.0
+ trace: collect_build_postponed (1): skip being built existing dependent tex of dependency libbar
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
%.*
- trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: reeval tix/1.0.0
%.*
- trace: collect_build: pick tex/0.1.0 over tex/1.0.0
- trace: postponed_configurations::add: add {tix^ 2,1: tex} to {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | tex->{tix/2,1}}
+ trace: postponed_configurations::add: add {tix^ 1,1: libbar} to {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | libbar->{tix/1,1}}
trace: collect_build_prerequisites: re-evaluated tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | libbar->{tix/1,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_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_prerequisites: resume tix/1.0.0
+ %.*
+ trace: collect_build: pick tex/0.1.0 over tex/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency tex/0.1.0 of dependent tix/1.0.0
+ trace: postponed_configurations::add: create {tix | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: postpone tix/1.0.0
+ trace: collect_build_postponed (1): cfg-negotiate end {tix^ | libbar->{tix/1,1}}!
+ trace: collect_build_postponed (2): begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): skip being built existing dependent tix of dependency tex
+ trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin tex/0.1.0
%.*
trace: collect_build: add libfoo/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent tex/0.1.0
trace: postponed_configurations::add: create {tex | libfoo->{tex/1,1}}
trace: collect_build_prerequisites: postpone tex/0.1.0
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tix/1.0.0
trace: collect_build_prerequisites: resume tix/1.0.0
trace: collect_build_prerequisites: end tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate end {tix^ | tex->{tix/2,1}}!
- trace: collect_build_postponed (2): begin {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (2): cfg-negotiate end {tix | tex->{tix/2,1}}!
+ trace: collect_build_postponed (3): begin {tex | libfoo->{tex/1,1}}
%.*
- trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libfoo
- trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (3): skip being built existing dependent tex of dependency libfoo
+ trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/1,1}}
%.*
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tex/0.1.0
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (3): select cfg-negotiated dependency alternative for dependent tex/0.1.0
trace: collect_build_prerequisites: resume tex/0.1.0
trace: collect_build_prerequisites: end tex/0.1.0
- trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/1,1}}!
- trace: collect_build_postponed (2): end {tex | libfoo->{tex/1,1}}
- trace: collect_build_postponed (1): end {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (3): cfg-negotiate end {tex | libfoo->{tex/1,1}}!
+ trace: collect_build_postponed (3): end {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (2): end {tix | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): end {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade tex/0.1.0
+ config.tex.extras=true (set by tix)
+ reconfigure/update tix/1.0.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_drop tex tix
@@ -10026,52 +10254,80 @@ test.arguments += --sys-no-query
%.*
trace: pkg_build: refine package collection/plan execution
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency tex/0.1.0 of existing dependent tix/1.0.0
- trace: postponed_configurations::add: create {tix^ | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of existing dependent tix/1.0.0 due to dependency tex/0.1.0
+ trace: postponed_configurations::add: create {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): begin {tix^ | libbar->{tix/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: reeval tix/1.0.0
+ trace: collect_build_postponed (1): skip being built existing dependent tex of dependency libbar
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
%.*
- trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: reeval tix/1.0.0
%.*
- trace: collect_build: pick tex/0.1.0 over tex/1.0.0
- trace: postponed_configurations::add: add {tix^ 2,1: tex} to {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | tex->{tix/2,1}}
+ trace: postponed_configurations::add: add {tix^ 1,1: libbar} to {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | libbar->{tix/1,1}}
trace: collect_build_prerequisites: re-evaluated tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | libbar->{tix/1,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_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_prerequisites: resume tix/1.0.0
+ %.*
+ trace: collect_build: pick tex/0.1.0 over tex/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency tex/0.1.0 of dependent tix/1.0.0
+ trace: postponed_configurations::add: create {tix | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: postpone tix/1.0.0
+ trace: collect_build_postponed (1): cfg-negotiate end {tix^ | libbar->{tix/1,1}}!
+ trace: collect_build_postponed (2): begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): skip being built existing dependent tix of dependency tex
+ trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin tex/0.1.0
%.*
trace: collect_build: add libfoo/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent tex/0.1.0
trace: postponed_configurations::add: create {tex | libfoo->{tex/1,1}}
trace: collect_build_prerequisites: postpone tex/0.1.0
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tix/1.0.0
trace: collect_build_prerequisites: resume tix/1.0.0
trace: collect_build_prerequisites: end tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate end {tix^ | tex->{tix/2,1}}!
- trace: collect_build_postponed (2): begin {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (2): cfg-negotiate end {tix | tex->{tix/2,1}}!
+ trace: collect_build_postponed (3): begin {tex | libfoo->{tex/1,1}}
%.*
- trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libfoo
- trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (3): skip being built existing dependent tex of dependency libfoo
+ trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/1,1}}
%.*
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tex/0.1.0
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (3): select cfg-negotiated dependency alternative for dependent tex/0.1.0
trace: collect_build_prerequisites: resume tex/0.1.0
trace: collect_build_prerequisites: end tex/0.1.0
- trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/1,1}}!
- trace: collect_build_postponed (2): end {tex | libfoo->{tex/1,1}}
- trace: collect_build_postponed (1): end {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (3): cfg-negotiate end {tex | libfoo->{tex/1,1}}!
+ trace: collect_build_postponed (3): end {tex | libfoo->{tex/1,1}}
+ trace: collect_build_postponed (2): end {tix | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): end {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade/unhold tex/0.1.0
+ config.tex.extras=true (set by tix)
+ reconfigure/update tix/1.0.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_drop tix
@@ -10079,7 +10335,7 @@ test.arguments += --sys-no-query
: dependency-downgrade-unhold-premature
:
- : As above but the dependency (tex) depends on libbar without
+ : As above but the dependency (tex/0.2.0) depends on libbar without
: configuration clause.
:
{
@@ -10107,54 +10363,82 @@ test.arguments += --sys-no-query
%.*
trace: pkg_build: refine package collection/plan execution
%.*
- trace: collect_build_prerequisites: cfg-postpone dependency tex/0.2.0 of existing dependent tix/1.0.0
- trace: postponed_configurations::add: create {tix^ | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
+ %.*
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of existing dependent tix/1.0.0 due to dependency tex/0.2.0
+ trace: postponed_configurations::add: create {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): begin
- trace: collect_build_postponed (1): begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): begin {tix^ | libbar->{tix/1,1}}
%.*
- trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: reeval tix/1.0.0
+ trace: collect_build_postponed (1): skip being built existing dependent tex of dependency libbar
+ trace: collect_build_prerequisites: pre-reeval tix/1.0.0
%.*
- trace: collect_build: add libbar/1.0.0
+ trace: collect_build_prerequisites: pre-reevaluated tix/1.0.0: 1,1
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: reeval tix/1.0.0
%.*
- trace: collect_build: pick tex/0.2.0 over tex/1.0.0
- trace: postponed_configurations::add: add {tix^ 2,1: tex} to {tix^ | tex->{tix/2,1}}
- trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | tex->{tix/2,1}}
+ trace: postponed_configurations::add: add {tix^ 1,1: libbar} to {tix^ | libbar->{tix/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent tix/1.0.0 results in {tix^ | libbar->{tix/1,1}}
trace: collect_build_prerequisites: re-evaluated tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): cfg-negotiate begin {tix^ | libbar->{tix/1,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_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_prerequisites: resume tix/1.0.0
+ %.*
+ trace: collect_build: pick tex/0.2.0 over tex/1.0.0
+ trace: collect_build_prerequisites: cfg-postpone dependency tex/0.2.0 of dependent tix/1.0.0
+ trace: postponed_configurations::add: create {tix | tex->{tix/2,1}}
+ trace: collect_build_prerequisites: postpone tix/1.0.0
+ trace: collect_build_postponed (1): cfg-negotiate end {tix^ | libbar->{tix/1,1}}!
+ trace: collect_build_postponed (2): begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): skip being built existing dependent tix of dependency tex
+ trace: collect_build_postponed (2): cfg-negotiate begin {tix | tex->{tix/2,1}}
+ %.*
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: begin tex/0.2.0
%.*
- trace: collect_build_prerequisites: no cfg-clause for dependency libbar/1.0.0 of dependent tex/0.2.0
+ trace: collect_build_prerequisites: dep-postpone dependency libbar/1.0.0 of dependent tex/0.2.0
%.*
trace: collect_build: add libfoo/1.0.0
trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent tex/0.2.0
trace: postponed_configurations::add: create {tex | libfoo->{tex/2,1}}
trace: collect_build_prerequisites: postpone tex/0.2.0
- trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (1): select cfg-negotiated dependency alternative for dependent tix/1.0.0
+ trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tix/1.0.0
trace: collect_build_prerequisites: resume tix/1.0.0
trace: collect_build_prerequisites: end tix/1.0.0
- trace: collect_build_postponed (1): cfg-negotiate end {tix^ | tex->{tix/2,1}}!
- trace: collect_build_postponed (2): begin {tex | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): cfg-negotiate end {tix | tex->{tix/2,1}}!
+ trace: collect_build_postponed (3): begin {tex | libfoo->{tex/2,1}}
%.*
- trace: collect_build_postponed (2): skip being built existing dependent tex of dependency libfoo
- trace: collect_build_postponed (2): cfg-negotiate begin {tex | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (3): skip being built existing dependent tex of dependency libfoo
+ trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/2,1}}
%.*
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependencies
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies
trace: collect_build_prerequisites: skip configured libfoo/1.0.0
- trace: collect_build_postponed (2): recursively collect cfg-negotiated dependents
- trace: collect_build_postponed (2): select cfg-negotiated dependency alternative for dependent tex/0.2.0
+ trace: collect_build_postponed (3): recursively collect cfg-negotiated dependents
+ trace: collect_build_postponed (3): select cfg-negotiated dependency alternative for dependent tex/0.2.0
trace: collect_build_prerequisites: resume tex/0.2.0
trace: collect_build_prerequisites: end tex/0.2.0
- trace: collect_build_postponed (2): cfg-negotiate end {tex | libfoo->{tex/2,1}}!
- trace: collect_build_postponed (2): end {tex | libfoo->{tex/2,1}}
- trace: collect_build_postponed (1): end {tix^ | tex->{tix/2,1}}
+ trace: collect_build_postponed (3): cfg-negotiate end {tex | libfoo->{tex/2,1}}!
+ trace: collect_build_postponed (3): end {tex | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (2): end {tix | tex->{tix/2,1}}
+ trace: collect_build_postponed (1): end {tix^ | libbar->{tix/1,1}}
trace: collect_build_postponed (0): end
%.*
trace: execute_plan: simulate: yes
%.*
+ build plan:
+ downgrade/unhold tex/0.2.0
+ config.tex.extras=true (set by tix)
+ reconfigure/update tix/1.0.0
+ trace: execute_plan: simulate: no
+ %.*
EOE
$pkg_drop tix
@@ -12260,130 +12544,136 @@ test.arguments += --sys-no-query
: or hang and ends up with an expected packages setup.
:
{
- $clone_cfg;
+ +$clone_cfg
- $* libfoo libbar ?libbaz/0.1.0 ?libbox/0.1.0 \
- foo fox fux fix fex bar baz bac bat bas bus \
- box bax bux bix bex boo biz buz buc tax tex \
- tix tiz toz tez tux dex dix diz dox 2>!;
+ : all-new
+ :
+ {
+ $clone_cfg;
- $pkg_status -r >>EOO;
- !libfoo configured 1.0.0
- !libbar configured 1.0.0
- !bat configured 1.0.0
- libbaz configured !0.1.0 available 1.0.0
- !tix configured 0.1.0 available 1.0.0
- !toz configured 0.1.0 available 1.0.0 0.2.0
- !tux configured 1.0.0
- libbox configured !0.1.0 available 1.0.0
- !tix configured 0.1.0 available 1.0.0
- !bar configured 1.0.0
- !libbar configured 1.0.0
- !bux configured 1.0.0
- !libbar configured 1.0.0
- !bex configured 1.0.0
- !libbar configured 1.0.0
- !boo configured 1.0.0
- !libbar configured 1.0.0
- !biz configured 1.0.0
- !boo configured 1.0.0
- !libbar configured 1.0.0
- !buz configured 1.0.0
- !bux configured 1.0.0
- !libbar configured 1.0.0
- !tez configured 1.0.0
+ $* libfoo libbar ?libbaz/0.1.0 ?libbox/0.1.0 \
+ foo fox fux fix fex bar baz bac bat bas bus \
+ box bax bux bix bex boo biz buz buc tax tex \
+ tix tiz toz tez tux dex dix diz dox 2>!;
+
+ $pkg_status -r >>EOO;
+ !libfoo configured 1.0.0
!libbar configured 1.0.0
- libbox configured !0.1.0 available 1.0.0
+ !bat configured 1.0.0
+ libbaz configured !0.1.0 available 1.0.0
+ !tix configured 0.1.0 available 1.0.0
!toz configured 0.1.0 available 1.0.0 0.2.0
- !bix configured 1.0.0
+ !tux configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0
+ !tix configured 0.1.0 available 1.0.0
!bar configured 1.0.0
!libbar configured 1.0.0
!bux configured 1.0.0
!libbar configured 1.0.0
- !libbar configured 1.0.0
- !foo configured 1.0.0
- !libfoo configured 1.0.0
- !fox configured 1.0.0
- !libfoo configured 1.0.0
- !fux configured 1.0.0
- !libfoo configured 1.0.0
- !baz configured 1.0.0
- !libbar configured 1.0.0
- !libfoo configured 1.0.0
- !bac configured 1.0.0
- !libbar configured 1.0.0
- libbaz configured !0.1.0 available 1.0.0
- !libfoo configured 1.0.0
- !fix configured 1.0.0
+ !bex configured 1.0.0
+ !libbar configured 1.0.0
+ !boo configured 1.0.0
+ !libbar configured 1.0.0
+ !biz configured 1.0.0
+ !boo configured 1.0.0
+ !libbar configured 1.0.0
+ !buz configured 1.0.0
+ !bux configured 1.0.0
+ !libbar configured 1.0.0
+ !tez configured 1.0.0
+ !libbar configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0
+ !toz configured 0.1.0 available 1.0.0 0.2.0
+ !bix configured 1.0.0
+ !bar configured 1.0.0
+ !libbar configured 1.0.0
+ !bux configured 1.0.0
+ !libbar configured 1.0.0
+ !libbar configured 1.0.0
!foo configured 1.0.0
!libfoo configured 1.0.0
- !fex configured 1.0.0
- !foo configured 1.0.0
+ !fox configured 1.0.0
!libfoo configured 1.0.0
- !libfoo configured 1.0.0
- !bus configured 1.0.0
- !foo configured 1.0.0
+ !fux configured 1.0.0
+ !libfoo configured 1.0.0
+ !baz configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
+ !bac configured 1.0.0
+ !libbar configured 1.0.0
+ libbaz configured !0.1.0 available 1.0.0
+ !libfoo configured 1.0.0
+ !fix configured 1.0.0
+ !foo configured 1.0.0
+ !libfoo configured 1.0.0
+ !fex configured 1.0.0
+ !foo configured 1.0.0
+ !libfoo configured 1.0.0
!libfoo configured 1.0.0
- libbaz configured !0.1.0 available 1.0.0
- !bas configured 1.0.0
!bus configured 1.0.0
!foo configured 1.0.0
!libfoo configured 1.0.0
libbaz configured !0.1.0 available 1.0.0
- !libbar configured 1.0.0
- !box configured 1.0.0
- !libbar configured 1.0.0
- !libfoo configured 1.0.0
- !bax configured 1.0.0
- !libbar configured 1.0.0
- libbox configured !0.1.0 available 1.0.0
- !libfoo configured 1.0.0
- !buc configured 1.0.0
- !bux configured 1.0.0
+ !bas configured 1.0.0
+ !bus configured 1.0.0
+ !foo configured 1.0.0
+ !libfoo configured 1.0.0
+ libbaz configured !0.1.0 available 1.0.0
!libbar configured 1.0.0
- !libfoo configured 1.0.0
- !tax configured 1.0.0
- !libbar configured 1.0.0
- !libfoo configured 1.0.0
- !tex configured 1.0.0
- !libbar configured 1.0.0
- !libfoo configured 1.0.0
- !tiz configured 1.0.0
- !libbar configured 1.0.0
+ !box configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
+ !bax configured 1.0.0
+ !libbar configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0
+ !libfoo configured 1.0.0
+ !buc configured 1.0.0
+ !bux configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
+ !tax configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
!tex configured 1.0.0
!libbar configured 1.0.0
!libfoo configured 1.0.0
- !dex configured 1.0.0
- !bar configured 1.0.0
+ !tiz configured 1.0.0
!libbar configured 1.0.0
- !libfoo configured 1.0.0
- !dox configured 1.0.0
+ !tex configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
!dex configured 1.0.0
!bar configured 1.0.0
!libbar configured 1.0.0
!libfoo configured 1.0.0
- !dix configured 1.0.0
- !dox configured 1.0.0
- !dex configured 1.0.0
- !bar configured 1.0.0
- !libbar configured 1.0.0
- !libfoo configured 1.0.0
- !libbar configured 1.0.0
- libbox configured !0.1.0 available 1.0.0
- !diz configured 1.0.0
!dox configured 1.0.0
!dex configured 1.0.0
!bar configured 1.0.0
!libbar configured 1.0.0
!libfoo configured 1.0.0
- !libbar configured 1.0.0
- libbox configured !0.1.0 available 1.0.0
- EOO
+ !dix configured 1.0.0
+ !dox configured 1.0.0
+ !dex configured 1.0.0
+ !bar configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
+ !libbar configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0
+ !diz configured 1.0.0
+ !dox configured 1.0.0
+ !dex configured 1.0.0
+ !bar configured 1.0.0
+ !libbar configured 1.0.0
+ !libfoo configured 1.0.0
+ !libbar configured 1.0.0
+ libbox configured !0.1.0 available 1.0.0
+ EOO
- $pkg_drop libfoo libbar foo fox fux fix fex bar \
- baz bac bat bas bus box bax bux bix bex \
- boo biz buz buc tax tex tix tiz toz tez \
- tux dex dix diz dox
+ $pkg_drop libfoo libbar foo fox fux fix fex bar \
+ baz bac bat bas bus box bax bux bix bex \
+ boo biz buz buc tax tex tix tiz toz tez \
+ tux dex dix diz dox
+ }
}
}