aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-disfigure.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/pkg-disfigure.cxx')
-rw-r--r--bpkg/pkg-disfigure.cxx166
1 files changed, 98 insertions, 68 deletions
diff --git a/bpkg/pkg-disfigure.cxx b/bpkg/pkg-disfigure.cxx
index 9347bbc..2239314 100644
--- a/bpkg/pkg-disfigure.cxx
+++ b/bpkg/pkg-disfigure.cxx
@@ -15,11 +15,12 @@ using namespace butl;
namespace bpkg
{
void
- pkg_disfigure (const dir_path& c,
- const common_options& o,
+ pkg_disfigure (const common_options& o,
+ database& db,
transaction& t,
const shared_ptr<selected_package>& p,
bool clean,
+ bool disfigure,
bool simulate)
{
assert (p->state == package_state::configured ||
@@ -29,28 +30,30 @@ namespace bpkg
l4 ([&]{trace << *p;});
- database& db (t.database ());
tracer_guard tg (db, trace);
// Check that we have no dependents.
//
if (p->state == package_state::configured)
{
- using query = query<package_dependent>;
-
- auto r (db.query<package_dependent> (query::name == p->name));
-
- if (!r.empty ())
+ diag_record dr;
+ for (database& ddb: db.dependent_configs ())
{
- diag_record dr;
- dr << fail << "package " << p->name << " still has dependents:";
+ auto r (query_dependents (ddb, p->name, db));
- for (const package_dependent& pd: r)
+ if (!r.empty ())
{
- dr << info << "package " << pd.name;
+ if (dr.empty ())
+ dr << fail << "package " << p->name << db << " still has "
+ << "dependents:";
+
+ for (const package_dependent& pd: r)
+ {
+ dr << info << "package " << pd.name << ddb;
- if (pd.constraint)
- dr << " on " << p->name << " " << *pd.constraint;
+ if (pd.constraint)
+ dr << " on " << p->name << " " << *pd.constraint;
+ }
}
}
}
@@ -69,14 +72,19 @@ 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.
if (!simulate)
{
- dir_path src_root (p->effective_src_root (c));
- dir_path out_root (p->effective_out_root (c));
+ dir_path src_root (p->effective_src_root (db.config_orig));
+ dir_path out_root (p->effective_out_root (db.config_orig));
l4 ([&]{trace << "src_root: " << src_root << ", "
<< "out_root: " << out_root;});
@@ -92,9 +100,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
{
@@ -105,69 +117,77 @@ namespace bpkg
if (src_root == out_root)
bspec = "disfigure('" + rep + "')";
else
- bspec = "disfigure('" + src_root.representation () + "'@'" +
- rep + "')";
- }
+ bspec = "disfigure('" + src_root.representation () + "'@'" + rep +
+ "')";
- l4 ([&]{trace << "buildspec: " << bspec;});
+ disfigure = true; // Make sure the flag matches the behavior.
+ }
- // 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&)
@@ -179,10 +199,16 @@ namespace bpkg
db.update (p);
t.commit ();
- info << "package " << p->name << " is now broken; "
+ info << "package " << p->name << db << " is now broken; "
<< "use 'pkg-purge' to remove";
throw;
}
+
+ if (disfigure)
+ {
+ p->config_variables.clear ();
+ p->config_checksum.clear ();
+ }
}
p->out_root = nullopt;
@@ -207,7 +233,7 @@ namespace bpkg
package_name n (parse_package_name (args.next (),
false /* allow_version */));
- database db (open (c, trace));
+ database db (c, trace, true /* pre_attach */);
transaction t (db);
shared_ptr<selected_package> p (db.find<selected_package> (n));
@@ -221,7 +247,11 @@ namespace bpkg
// Commits the transaction.
//
- pkg_disfigure (c, o, 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);