aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2022-05-24 21:28:14 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2022-06-07 21:15:37 +0300
commit4c5b2c9f86f4ce5182a7f706f4c09d0ece11bb90 (patch)
tree58f3bf5dd086ea30d69a011ad43984a59ad0ec5a
parent5230dee88d9b7beb0e4f76761173b2b499abaa47 (diff)
Add postponed positions
-rw-r--r--bpkg/pkg-build.cxx272
-rw-r--r--tests/pkg-build.testscript192
2 files changed, 435 insertions, 29 deletions
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index b752ba3..1d2d413 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -1412,6 +1412,29 @@ namespace bpkg
return false;
}
+ // 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 config_package& cp) const
+ {
+ const pair<size_t, size_t>* r (nullptr);
+
+ auto i (dependents.find (cp));
+ 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;
+ }
+
// Notes:
//
// - Adds dependencies of the being merged from configuration to the end
@@ -2117,6 +2140,16 @@ namespace bpkg
}
};
+ // @@ TODO Describe.
+ //
+ using postponed_positions = map<config_package, pair<size_t, size_t>>;
+
+ struct postpone_position: scratch_collection
+ {
+ explicit
+ postpone_position (): scratch_collection ("earlier dependency position") {}
+ };
+
struct build_packages: build_package_list
{
build_packages () = default;
@@ -2270,6 +2303,7 @@ namespace bpkg
postponed_packages* postponed_repo = nullptr,
postponed_packages* postponed_alts = nullptr,
postponed_dependencies* postponed_deps = nullptr,
+ postponed_positions* postponed_poss = nullptr,
const function<verify_package_build_function>& vpb = nullptr)
{
using std::swap; // ...and not list::swap().
@@ -2281,7 +2315,8 @@ namespace bpkg
bool recursive (dep_chain != nullptr);
assert ((postponed_repo != nullptr) == recursive &&
(postponed_alts != nullptr) == recursive &&
- (postponed_deps != nullptr) == recursive);
+ (postponed_deps != nullptr) == recursive &&
+ (postponed_poss != nullptr) == recursive);
// Only builds are allowed here.
//
@@ -2595,7 +2630,8 @@ namespace bpkg
postponed_alts,
0 /* max_alt_index */,
*postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ *postponed_poss);
return &p;
}
@@ -2656,8 +2692,11 @@ namespace bpkg
// 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
- // without any dependent (see postponed_configurations for details).
+ // 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.
//
// If a dependency of a dependent with configuration clause is being
// negotiated (the negotiated member of the respective cluster in
@@ -2692,6 +2731,7 @@ namespace bpkg
size_t max_alt_index,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
+ postponed_positions& postponed_poss,
//
// @@ TMP This will probably be gone (see below).
//
@@ -2738,11 +2778,17 @@ namespace bpkg
pkg.reconfigure () &&
postponed_cfgs.find_dependency (cp) == nullptr)
{
+ // Note that there can be multiple existing dependents for a
+ // dependency. We, however, only add the first one in the assumption
+ // that the remaining dependents will also be considered when the time
+ // for negotiation comes.
+ //
vector<existing_dependent> eds (
query_existing_dependents (trace,
pdb,
nm,
replaced_vers,
+ postponed_cfgs,
rpt_depts));
if (!eds.empty ())
@@ -2750,8 +2796,7 @@ namespace bpkg
for (existing_dependent& ed: eds)
{
// @@ Here we need to first check if for this dependent there is a
- // record in the postponed_poss (not yet invented; any better
- // name?) map.
+ // record in the postponed_poss.
// (If the record exists and the dependency position
// is greater that the stored position, then we skip this
@@ -2763,9 +2808,6 @@ namespace bpkg
// position is equal), just add the dependency to the existing
// cluster.) -- Feels outdated.
//
- // Note that we also need to think if any such entries could
- // become bogus (and if we believe not, then assert so).
- //
// new ? exs exs
// ------------------
//
@@ -2778,7 +2820,53 @@ namespace bpkg
// equal neg -- impossible (should have been completed)
// equal non -- add missing dependencies
//
+
+ // Make sure that this existing dependent doesn't belong to any
+ // (being) negotiated configuration cluster with a greater
+ // dependency index. That would mean that the dependent is already
+ // re-evaluated with this index as a target and so this dependency
+ // cannot be properly configured anymore.
//
+ size_t di (ed.dependency_position.first);
+
+ for (const postponed_configuration& cfg: postponed_cfgs)
+ {
+ if (const pair<size_t, size_t>* p =
+ cfg.existing_dependent_position (cp))
+ {
+ size_t ei (p->first);
+
+ if (di < ei)
+ {
+ postponed_poss[cp] = ed.dependency_position;
+
+ l5 ([&]{trace << "cannot cfg-postpone dependency "
+ << pkg.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 ();
+
+ throw postpone_position ();
+ }
+
+ 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);
+ }
+ }
+ }
+
l5 ([&]{trace << "cfg-postpone dependency "
<< pkg.available_name_version_db ()
<< " of existing dependent " << *ed.selected
@@ -3778,6 +3866,7 @@ namespace bpkg
postponed_alts,
&postponed_deps,
&postponed_cfgs,
+ &postponed_poss,
&di,
reeval,
&reeval_pos,
@@ -3954,6 +4043,7 @@ namespace bpkg
nullptr /* postponed_repo */,
nullptr /* postponed_alts */,
nullptr /* postponed_deps */,
+ nullptr /* postponed_poss */,
verify));
config_package dcp (b.db, b.available->id.name);
@@ -4081,7 +4171,8 @@ namespace bpkg
postponed_alts,
0 /* max_alt_index */,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
}
// If this dependent has any dependencies with configurations
@@ -4278,6 +4369,7 @@ namespace bpkg
0 /* max_alt_index */,
postponed_deps,
postponed_cfgs,
+ postponed_poss,
true /* force_configured */);
}
else
@@ -4706,6 +4798,7 @@ namespace bpkg
postponed_packages& postponed_alts,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
+ postponed_positions& postponed_poss,
const function<find_database_function>& fdb,
const function<add_priv_cfg_function>& apc)
{
@@ -4788,7 +4881,8 @@ namespace bpkg
&dep_chain,
&postponed_repo,
&postponed_alts,
- &postponed_deps);
+ &postponed_deps,
+ &postponed_poss);
}
}
@@ -4974,7 +5068,8 @@ namespace bpkg
postponed_packages& postponed_alts,
size_t max_alt_index,
postponed_dependencies& postponed_deps,
- postponed_configurations& postponed_cfgs)
+ postponed_configurations& postponed_cfgs,
+ postponed_positions& postponed_poss)
{
auto mi (map_.find (db, name));
assert (mi != map_.end ());
@@ -4993,7 +5088,8 @@ namespace bpkg
&postponed_alts,
max_alt_index,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
}
// Note: depth is only used for tracing.
@@ -5005,6 +5101,7 @@ namespace bpkg
postponed_packages& postponed_alts,
postponed_dependencies& postponed_deps,
postponed_configurations& postponed_cfgs,
+ postponed_positions& postponed_poss,
const function<find_database_function>& fdb,
const repointed_dependents& rpt_depts,
const function<add_priv_cfg_function>& apc,
@@ -5077,6 +5174,8 @@ namespace bpkg
postponed_configurations postponed_cfgs_;
};
+ struct skip_configuration {};
+
size_t depth (pcfg != nullptr ? pcfg->depth : 0);
string t ("collect_build_postponed (" + to_string (depth) + ")");
@@ -5175,6 +5274,7 @@ namespace bpkg
p.db,
p.name,
replaced_vers,
+ postponed_cfgs,
rpt_depts))
{
config_package cp (ed.db, ed.selected->name);
@@ -5268,7 +5368,65 @@ namespace bpkg
// this cluster.
//
+ size_t di (ed.dependency_position.first);
+
const config_package& cp (d.first);
+
+ auto pi (postponed_poss.find (cp));
+ if (pi != postponed_poss.end () && pi->second.first < di)
+ {
+ l5 ([&]{trace << "pos-postponed existing dependent "
+ << cp << " re-evaluation for target "
+ << "dependency index " << di << ", skipping "
+ << *pcfg;});
+
+ throw skip_configuration ();
+ }
+
+ bool skip_cluster (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 (cp))
+ {
+ size_t ei (p->first);
+
+ if (!cfg.negotiated)
+ {
+ if (ei < di)
+ {
+ l5 ([&]{trace << "cannot re-evaluate dependent "
+ << cp << " for target dependency index "
+ << di << " due to earlier dependency "
+ << "index " << ei << " in " << cfg
+ << ", skipping " << *pcfg;});
+
+ skip_cluster = true;
+ }
+ }
+ else if (di < ei)
+ {
+ postponed_poss[cp] = ed.dependency_position;
+
+ l5 ([&]{trace << "cannot re-evaluate dependent "
+ << cp << " for target dependency index "
+ << di << " due to greater dependency "
+ << "index " << ei << " in " << cfg
+ << ", throwing postpone_position";});
+
+ throw postpone_position ();
+ }
+ }
+ }
+
+ if (skip_cluster)
+ throw skip_configuration ();
+
packages& ds (ed.dependencies);
pair<shared_ptr<available_package>,
@@ -5333,6 +5491,7 @@ namespace bpkg
numeric_limits<size_t>::max (),
postponed_deps,
postponed_cfgs,
+ postponed_poss,
false /* force_configured */,
ed.dependency_position);
@@ -5405,6 +5564,7 @@ namespace bpkg
0 /* max_alt_index */,
postponed_deps,
postponed_cfgs,
+ postponed_poss,
true /* force_configured */);
}
else
@@ -5525,7 +5685,8 @@ namespace bpkg
&postponed_alts,
0 /* max_alt_index */,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
}
// Negotiated (so can only be rolled back).
@@ -5572,7 +5733,8 @@ namespace bpkg
&pas,
0 /* max_alt_index */,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
}
// Save the potential new dependency alternative-related postpones.
@@ -5611,7 +5773,10 @@ namespace bpkg
size_t pcd (depth + 1);
pc->depth = pcd;
- for (;;) // Either return or retry the same cluster.
+ // Either return or retry the same cluster or skip this cluster and
+ // proceed to the next one.
+ //
+ for (;;)
{
// First assume we can negotiate this configuration rolling back
// if this doesn't pan out.
@@ -5630,6 +5795,7 @@ namespace bpkg
postponed_alts,
postponed_deps,
postponed_cfgs,
+ postponed_poss,
fdb,
rpt_depts,
apc,
@@ -5647,6 +5813,24 @@ namespace bpkg
return;
}
+ catch (const skip_configuration&)
+ {
+ // 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];
+
+ pc->depth = 0;
+
+ break;
+ }
catch (retry_configuration& e)
{
// If this is not "our problem", then keep looking.
@@ -5843,7 +6027,8 @@ namespace bpkg
&pas,
i,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
prog = (pas.find (p) == pas.end () ||
ndep != p->dependencies->size ());
@@ -5910,7 +6095,8 @@ namespace bpkg
nullptr,
0,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
assert (false); // Can't be here.
}
@@ -5931,7 +6117,8 @@ namespace bpkg
nullptr,
0,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
assert (false); // Can't be here.
}
@@ -6287,6 +6474,7 @@ namespace bpkg
database& db,
const package_name& name,
const replaced_versions& replaced_vers,
+ const postponed_configurations& postponed_cfgs,
const repointed_dependents& rpt_depts)
{
vector<existing_dependent> r;
@@ -6320,10 +6508,38 @@ namespace bpkg
(p->system || p->recollect_recursively (rpt_depts))) ||
*p->action == build_package::drop)
{
- l5 ([&]{trace << "skip being " << (build ? "built" : "dropped")
- << " existing dependent " << cp
- << " of dependency " << name << db;});
- continue;
+ // If the package is being built, the check if it was
+ // re-evaluated for the target position greater than the
+ // dependency position. If that's the case then don't ignore
+ // the dependent leave it to the caller to handle the
+ // situation.
+ //
+ bool skip (true);
+
+ if (build)
+ {
+ for (const postponed_configuration& cfg: postponed_cfgs)
+ {
+ if (cfg.negotiated)
+ {
+ if (const pair<size_t, size_t>* p =
+ cfg.existing_dependent_position (cp))
+ {
+ if (p->first > pos.first)
+ skip = false;
+ }
+ }
+ }
+ }
+
+ if (skip)
+ {
+ l5 ([&]{trace << "skip being "
+ << (build ? "built" : "dropped")
+ << " existing dependent " << cp
+ << " of dependency " << name << db;});
+ continue;
+ }
}
}
@@ -9478,6 +9694,7 @@ namespace bpkg
replaced_versions replaced_vers;
postponed_dependencies postponed_deps;
+ postponed_positions postponed_poss;
// Map the repointed dependents to the replacement flags (see
// repointed_dependents for details), unless --no-move is specified.
@@ -9760,6 +9977,7 @@ namespace bpkg
{
replaced_vers.clear ();
postponed_deps.clear ();
+ postponed_poss.clear ();
scratch_exe = false;
}
@@ -9843,7 +10061,8 @@ namespace bpkg
postponed_alts,
0 /* max_alt_index */,
postponed_deps,
- postponed_cfgs);
+ postponed_cfgs,
+ postponed_poss);
}
else
{
@@ -9896,6 +10115,7 @@ namespace bpkg
postponed_alts,
postponed_deps,
postponed_cfgs,
+ postponed_poss,
find_prereq_database,
add_priv_cfg);
}
@@ -9975,7 +10195,8 @@ namespace bpkg
&dep_chain,
&postponed_repo,
&postponed_alts,
- &postponed_deps);
+ &postponed_deps,
+ &postponed_poss);
}
}
@@ -10012,6 +10233,7 @@ namespace bpkg
postponed_alts,
postponed_deps,
postponed_cfgs,
+ postponed_poss,
find_prereq_database,
rpt_depts,
add_priv_cfg);
diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript
index 04cd62c..65e98e5 100644
--- a/tests/pkg-build.testscript
+++ b/tests/pkg-build.testscript
@@ -5628,26 +5628,210 @@ test.options += --no-progress
: non-negotiated
:
- if false
{
$clone_cfg;
$* tex 2>!;
- $* libfoo/0.1.0 libbar/0.1.0 2>>~%EOE%
+ $* libfoo/0.1.0 libbar/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 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: cfg-postpone dependency libbar/0.1.0 of existing dependent tex/1.0.0
+ trace: postponed_configurations::add: create {tex^ | libbar->{tex/1,1}}
+ 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 for target 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 (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: 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 {tex^ | libbar->{tex/1,1}}
+ trace: collect_build_prerequisites: re-evaluating dependent tex/1.0.0 results in {tex^ | libbar->{tex/1,1}}
+ trace: collect_build_prerequisites: re-evaluated tex/1.0.0
+ trace: collect_build_postponed (1): cfg-negotiate begin {tex^ | libbar->{tex/1,1}}
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
+ trace: collect_build_prerequisites: begin libbar/0.1.0
+ trace: collect_build_prerequisites: end libbar/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: 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: 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): 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): 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 (2): recursively collect cfg-negotiated dependents
+ 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 {tex^ | libbar->{tex/1,1}}
+ trace: collect_build_postponed (0): end
+ %.*
+ trace: execute_plan: simulate: yes
+ %.*
EOE
+
+ $pkg_status -r >>EOO;
+ !libbar configured !0.1.0 available 1.0.0
+ !libfoo configured !0.1.0 available 1.0.0
+ !tex configured 1.0.0
+ !libbar configured !0.1.0 available 1.0.0
+ !libfoo configured !0.1.0 available 1.0.0
+ EOO
+
+ $pkg_drop tex libfoo libbar
}
: negotiated
:
- if false
{
$clone_cfg;
$* tex 2>!;
- $* libfoo/0.1.0 bar/0.1.0 2>>~%EOE%
+ $* libfoo/0.1.0 bar/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 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: 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 for target 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: begin bar/0.1.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_postponed (1): pos-postponed existing dependent tex re-evaluation for target dependency index 2, skipping {tex^ | libfoo->{tex/2,1}}
+ trace: collect_build_postponed (1): begin {bar | libbar->{bar/1,1}}
+ %.*
+ trace: collect_build_postponed (1): re-evaluate existing dependents for {bar | libbar->{bar/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: 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}}
+ trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies
+ trace: collect_build_prerequisites: begin libbar/0.1.0
+ trace: collect_build_prerequisites: end libbar/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 bar/0.1.0
+ trace: collect_build_prerequisites: resume bar/0.1.0
+ trace: collect_build_prerequisites: end bar/0.1.0
+ 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: 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: 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): 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): 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 (2): recursively collect cfg-negotiated dependents
+ 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 (0): end
+ %.*
+ trace: execute_plan: simulate: yes
+ %.*
EOE
+
+ $pkg_status -r >>EOO;
+ !libfoo configured !0.1.0 available 1.0.0
+ !tex configured 1.0.0
+ libbar configured 0.1.0 available 1.0.0
+ !libfoo configured !0.1.0 available 1.0.0
+ !bar configured !0.1.0 available 1.0.0
+ libbar configured 0.1.0 available 1.0.0
+ EOO
+
+ $pkg_drop tex libfoo bar
}
: up-negotiate