From 0c8e2951cc8b481a9b11af4f1815e63c17f25da1 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 31 May 2022 12:38:26 +0300 Subject: Complete 'override first non-replace position postponement with replace' logic --- bpkg/pkg-build.cxx | 79 +++++++++++++++++++++----------- tests/pkg-build.testscript | 110 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 159 insertions(+), 30 deletions(-) diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 2689b8f..e179d7c 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -2209,7 +2209,7 @@ namespace bpkg { public: // If true, override the first encountered non-replace position to replace - // and clear this flag. See collect_build_postponed () for details. + // and clear this flag. See collect_build_postponed() for details. // bool replace = false; @@ -2962,34 +2962,45 @@ namespace bpkg { auto pi (postponed_poss.find (dpk)); - if (pi != postponed_poss.end () && - pi->second.first < di && - pi->second.replace) + if (pi != postponed_poss.end () && pi->second.first < di) { - // Overwrite the existing dependent dependency information and - // fall through to proceed as for the normal case. + // If requested, override the first encountered non-replace + // position to replace. See collect_build_postponed () for + // details. // - bp = replace_existing_dependent_dependency ( - trace, - options, - ed, // Note: modified. - pi->second, - fdb, - rpt_depts, - apc, - initial_collection, - replaced_vers, - postponed_cfgs); + if (!pi->second.replace && postponed_poss.replace) + { + pi->second.replace = true; + postponed_poss.replace = false; + } - pk = package_key (bp->db, bp->name ()); + if (pi->second.replace) + { + // 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); + + pk = 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. + // 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. + } } } @@ -5608,6 +5619,15 @@ namespace bpkg 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 @@ -6413,10 +6433,15 @@ namespace bpkg // forward. // if (!postponed_cfgs.negotiated () && - find (postponed_poss.begin (), postponed_poss.end (), - [] () {return !replace;}) != postponed_poss.end () && + 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. diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index ff0377e..bc8a67a 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -9229,7 +9229,6 @@ test.options += --no-progress : dependency-new-downgrade : - if false { $clone_cfg; @@ -9444,8 +9443,113 @@ test.options += --no-progress 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): unexpected non-negotiated cluster {tix^ | tex->{tix/2,1}} - bpkg: /home/karen/work/build2/bpkg/bpkg/pkg-build.cxx:6413: void bpkg::build_packages::collect_build_postponed(const bpkg::pkg_build_options&, bpkg::replaced_versions&, bpkg::postponed_packages&, bpkg::postponed_packages&, bpkg::postponed_dependencies&, bpkg::postponed_configurations&, bpkg::postponed_positions&, const std::function&, const repointed_dependents&, const std::function >&&)>&, bpkg::postponed_configuration*): Assertion 'postponed_cfgs.negotiated ()' failed. + 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_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: add libbar/1.0.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 (1): begin {tix^ | libbar->{tix/1,1}} + %.* + trace: collect_build_postponed (1): skip being built existing dependent tex of dependency libbar + 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 + %.* + 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^ | libbar->{tix/1,1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libbar/1.0.0 + trace: collect_build_prerequisites: end libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_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.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: 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.3.0 + %.* + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tex/0.3.0 + trace: postponed_configurations::add: add {tex 1,1: libbar} to {tix^ | libbar->{tix/1,1}}! + trace: collect_build_prerequisites: cfg-postponing dependent tex/0.3.0 involves negotiated configurations and results in {tex tix^ | libbar->{tex/1,1 tix/1,1}}!, throwing retry_configuration + trace: collect_build_postponed (0): cfg-negotiation of {tix^ | libbar->{tix/1,1}} failed due to dependent tex, adding shadow dependent and re-negotiating + 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_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 + %.* + 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^ | libbar->{tix/1,1}} + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libbar/1.0.0 + trace: collect_build_prerequisites: end libbar/1.0.0 + trace: collect_build_postponed (1): recursively collect cfg-negotiated dependents + trace: collect_build_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.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: 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.3.0 + %.* + trace: collect_build_prerequisites: cfg-postpone dependency libbar/1.0.0 of dependent tex/0.3.0 + trace: postponed_configurations::add: add {tex 1,1: libbar} to {tix^ | libbar->{tix/1,1}}! + trace: collect_build_prerequisites: dependent tex/0.3.0 is a shadow dependent for {tex tix^ | libbar->{tex/1,1 tix/1,1}}! + trace: collect_build_prerequisites: configuration for cfg-postponed dependencies of dependent tex/0.3.0 is negotiated + trace: collect_build_prerequisites: dependency libbar/1.0.0 of dependent tex/0.3.0 is already (being) recursively collected, skipping + %.* + trace: collect_build: add libfoo/1.0.0 + trace: collect_build_prerequisites: cfg-postpone dependency libfoo/1.0.0 of dependent tex/0.3.0 + trace: postponed_configurations::add: create {tex | libfoo->{tex/2,1}} + trace: collect_build_prerequisites: postpone tex/0.3.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 (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 + trace: collect_build_postponed (3): cfg-negotiate begin {tex | libfoo->{tex/2,1}} + trace: collect_build_postponed (3): recursively collect cfg-negotiated dependencies + trace: collect_build_prerequisites: begin libfoo/1.0.0 + trace: collect_build_prerequisites: end libfoo/1.0.0 + trace: collect_build_postponed (3): recursively collect cfg-negotiated dependents + trace: collect_build_postponed (3): select cfg-negotiated dependency alternative for dependent tex/0.3.0 + trace: collect_build_prerequisites: resume tex/0.3.0 + 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 (1): end {tix^ | libbar->{tix/1,1}} + trace: collect_build_postponed (0): end + %.* + trace: execute_plan: simulate: yes + %.* EOE $pkg_drop tex tix -- cgit v1.1