From 82ea0bd107006cb574d8b19a4e457fb5a4c8caf0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 22 Sep 2021 10:42:09 +0200 Subject: Add --keep-config pkg-disfigure option --- bpkg/pkg-build.cxx | 9 ++-- bpkg/pkg-configure.cxx | 6 ++- bpkg/pkg-disfigure.cli | 14 +++++-- bpkg/pkg-disfigure.cxx | 111 ++++++++++++++++++++++++++++--------------------- bpkg/pkg-disfigure.hxx | 11 ++--- bpkg/pkg-drop.cxx | 6 ++- 6 files changed, 95 insertions(+), 62 deletions(-) diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 4466e76..d8e7b3b 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -5170,8 +5170,8 @@ namespace bpkg check_any_available (cdb, t, &dr); } - // We will keep the output directory only if the external package is - // replaced with an external one (see above for details). + // We will keep the output directory only if the external package + // is replaced with an external one (see above for details). // bool keep_out (o.keep_out () && sp->external ()); @@ -6728,7 +6728,8 @@ namespace bpkg // transaction t (pdb, !simulate /* start */); - // Reset the flag if the package being unpacked is not an external one. + // Reset the keep_out flag if the package being unpacked is not an + // external one. // if (p.keep_out && !simulate) { @@ -6760,7 +6761,7 @@ namespace bpkg // Commits the transaction. // - pkg_disfigure (o, pdb, t, sp, !p.keep_out, simulate); + pkg_disfigure (o, pdb, t, sp, !p.keep_out, true, simulate); r = true; diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx index aaf9033..393ed68 100644 --- a/bpkg/pkg-configure.cxx +++ b/bpkg/pkg-configure.cxx @@ -232,7 +232,11 @@ namespace bpkg // Commits the transaction. // - pkg_disfigure (o, db, t, p, true /* clean */, false /* simulate */); + pkg_disfigure (o, db, t, + p, + true /* clean */, + true /* disfigure */, + false /* simulate */); throw; } } diff --git a/bpkg/pkg-disfigure.cli b/bpkg/pkg-disfigure.cli index 9f6c63b..0491a16 100644 --- a/bpkg/pkg-disfigure.cli +++ b/bpkg/pkg-disfigure.cli @@ -23,9 +23,11 @@ namespace bpkg source code package is returned to the \cb{unpacked} state. A system package is removed from the configuration. - By default \cb{pkg-disfigure} will also clean the package's output - directory. This behavior can be suppressed with the \cb{--keep-out} - option, for example, if the package is to be reconfigured." + By default \cb{pkg-disfigure} will remove the package's build system + configuration (\cb{config.build}) and also clean its output directory. + This behavior can be suppressed with the \cb{--keep-config} and + \cb{--keep-out} options, respectively, for example, if the package is + to be reconfigured." } class pkg_disfigure_options: configuration_options @@ -36,6 +38,12 @@ namespace bpkg { "Don't clean the package's output directory." } + + bool --keep-config + { + "Don't remove the package's build system configuration + (\cb{config.build})." + } }; " diff --git a/bpkg/pkg-disfigure.cxx b/bpkg/pkg-disfigure.cxx index 1c356f0..7ddd418 100644 --- a/bpkg/pkg-disfigure.cxx +++ b/bpkg/pkg-disfigure.cxx @@ -20,6 +20,7 @@ namespace bpkg transaction& t, const shared_ptr& p, bool clean, + bool disfigure, bool simulate) { assert (p->state == package_state::configured || @@ -94,9 +95,13 @@ namespace bpkg if (p->state == package_state::configured) { if (clean) - bspec = "clean('" + rep + "') "; + bspec = "clean('" + rep + "')"; - bspec += "disfigure('" + rep + "')"; + if (disfigure) + { + bspec += (bspec.empty () ? "" : " "); + bspec += "disfigure('" + rep + "')"; + } } else { @@ -111,65 +116,71 @@ namespace bpkg "')"; } - l4 ([&]{trace << "buildspec: " << bspec;}); - - // Disfigure. + // Clean and/or disfigure. // + if (!bspec.empty () && exists (out_root)) try { - if (exists (out_root)) + l4 ([&]{trace << "buildspec: " << bspec;}); + + // Note that for external packages out_root is only the output + // directory. It is also possible that the buildfiles in the source + // directory have changed in a way that they don't clean everything. + // So in this case we just remove the output directory manually rather + // then running 'b clean disfigure'. + // + // It may also happen that we cannot disfigure the external package' + // output directory (the source directory have moved, etc.). If that's + // the case, then we fallback to the output directory removal. + // + if (p->external ()) { - // Note that for external packages this is just the output - // directory. It is also possible that the buildfiles in the source - // directory have changed in a way that they don't clean everything. - // So in this case we just remove the output directory manually - // rather then running 'b clean disfigure'. + // clean disfigure // - // It may also happen that we can not disfigure the external - // package' output directory (the source directory have moved, etc.). - // If that's the case, then we fallback to the output directory - // removal. + // true true -- wipe the directory + // true false -- try to clean, ignore if failed + // false true -- try to disfigure, fallback to wipe if failed + // false false -- never get here (bspec is empty) // - if (p->external ()) + + if (!clean || !disfigure) { - if (!clean) + auto_fd dev_null (open_null ()); + + // Redirect stderr to /dev/null. Note that we don't expect + // anything to be written to stdout. + // + process pr (start_b (o, + 1 /* stdout */, + dev_null /* stderr */, + verb_b::quiet, + bspec)); + + // If the disfigure meta-operation failed then we report the + // abnormal termination and fallback to the output directory + // removal otherwise. + // + if (!pr.wait ()) { - auto_fd dev_null (open_null ()); - - // Redirect stderr to /dev/null. Note that we don't expect - // anything to be written to stdout. - // - process pr (start_b (o, - 1 /* stdout */, dev_null /* stderr */, - verb_b::quiet, - bspec)); - - // If the disfigure meta-operation failed then we report the - // abnormal termination and fallback to the output directory - // removal otherwise. - // - if (!pr.wait ()) - { - const process_exit& e (*pr.exit); - - if (!e.normal ()) - fail << "process " << name_b (o) << " " << e; - - clean = true; - } - } + const process_exit& e (*pr.exit); + + if (!e.normal ()) + fail << "process " << name_b (o) << " " << e; - if (clean) - rm_r (out_root); + clean = true; + } } - else - run_b (o, verb_b::quiet, bspec); + + if (clean && disfigure) + rm_r (out_root); } + else + run_b (o, verb_b::quiet, bspec); // Make sure the out directory is gone unless it is the same as src, - // or we didn't clean it. + // or we didn't clean or disfigure it. // - if (out_root != src_root && clean && exists (out_root)) + if (out_root != src_root && clean && disfigure && exists (out_root)) fail << "package output directory " << out_root << " still exists"; } catch (const failed&) @@ -223,7 +234,11 @@ namespace bpkg // Commits the transaction. // - pkg_disfigure (o, db, t, p, !o.keep_out (), false /* simulate */); + pkg_disfigure (o, db, t, + p, + !o.keep_out () /* clean */, + !o.keep_config () /* disfigure */, + false /* simulate */); assert (p->state == package_state::unpacked || p->state == package_state::transient); diff --git a/bpkg/pkg-disfigure.hxx b/bpkg/pkg-disfigure.hxx index d15b007..fab56a0 100644 --- a/bpkg/pkg-disfigure.hxx +++ b/bpkg/pkg-disfigure.hxx @@ -15,11 +15,11 @@ namespace bpkg int pkg_disfigure (const pkg_disfigure_options&, cli::scanner& args); - // Disfigure the package, update its state, and commit the - // transaction. If the package state is broken, then this - // is taken to mean it hasn't been successfully configured - // and no clean prior to disfigure is necessary (or possible, - // for that matter). + // Disfigure the package, update its state, and commit the transaction. If + // the package state is broken, then this is taken to mean it hasn't been + // successfully configured and no clean prior to disfigure is necessary (or + // possible, for that matter). If disfigure is false, then don't actually + // disfigure the package in the build system sense. // void pkg_disfigure (const common_options&, @@ -27,6 +27,7 @@ namespace bpkg transaction&, const shared_ptr&, bool clean, + bool disfigure, bool simulate); } diff --git a/bpkg/pkg-drop.cxx b/bpkg/pkg-drop.cxx index 014ddb9..2e9969c 100644 --- a/bpkg/pkg-drop.cxx +++ b/bpkg/pkg-drop.cxx @@ -419,7 +419,11 @@ namespace bpkg // Commits the transaction. // - pkg_disfigure (o, db, t, p, true /* clean */, false /* simulate */); + pkg_disfigure (o, db, t, + p, + true /* clean */, + true /* disfigure */, + false /* simulate */); assert (p->state == package_state::unpacked || p->state == package_state::transient); -- cgit v1.1