From 7221a63204a0b2a89e1c72fcbf9f2a7de0a575a3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2015 14:05:22 +0200 Subject: Implement pkg-{configure, disfigure} commands --- bpkg/pkg-disfigure.cxx | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 bpkg/pkg-disfigure.cxx (limited to 'bpkg/pkg-disfigure.cxx') diff --git a/bpkg/pkg-disfigure.cxx b/bpkg/pkg-disfigure.cxx new file mode 100644 index 0000000..7390e76 --- /dev/null +++ b/bpkg/pkg-disfigure.cxx @@ -0,0 +1,124 @@ +// file : bpkg/pkg-disfigure.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace butl; + +namespace bpkg +{ + void + pkg_disfigure (const dir_path& c, + transaction& t, + const shared_ptr& p) + { + tracer trace ("pkg_disfigure"); + + database& db (t.database ()); + + // Calculate package's src_root and out_root. + // + assert (p->src_root); // Must be set since unpacked. + assert (p->out_root); // Must be set since configured. + + dir_path src_root (p->src_root->absolute () + ? *p->src_root + : c / *p->src_root); + dir_path out_root (c / *p->out_root); // Always relative. + + level4 ([&]{trace << "src_root: " << src_root << ", " + << "out_root: " << out_root;}); + + // Form the buildspec. + // + // Why do we need to specify src_root? While it shouldn't be + // necessary for a completely configured package, we might + // also be called to disfigure a partially configured one. + // + string bspec; + + if (src_root == out_root) + bspec = "disfigure(" + out_root.string () + "/)"; + else + bspec = "disfigure(" + + src_root.string () + "/@" + + out_root.string () + "/)"; + + level4 ([&]{trace << "buildspec: " << bspec;}); + + // Disfigure. + // + try + { + if (exists (out_root)) + run_b (bspec); + + // Make sure the out directory is gone unless it is the same as src. + // + if (out_root != src_root && exists (out_root)) + fail << "package output directory " << out_root << " still exists"; + } + catch (const failed&) + { + // If we failed to disfigure the package, set it to the broken + // state. The user can then try to clean things up with pkg-purge. + // + p->state = state::broken; + db.update (p); + t.commit (); + + info << "package " << p->name << " is now broken; " + << "use 'pkg-purge' to remove"; + throw; + } + + p->out_root = optional (); + p->state = state::unpacked; + + db.update (p); + t.commit (); + } + + void + pkg_disfigure (const pkg_disfigure_options& o, cli::scanner& args) + { + tracer trace ("pkg_disfigure"); + + dir_path c (o.directory ()); + level4 ([&]{trace << "configuration: " << c;}); + + if (!args.more ()) + fail << "package name argument expected" << + info << "run 'bpkg help pkg-disfigure' for more information"; + + string n (args.next ()); + + database db (open (c)); + transaction t (db.begin ()); + + shared_ptr p (db.find (n)); + + if (p == nullptr) + fail << "package " << n << " does not exist in configuration " << c; + + if (p->state != state::configured) + fail << "package " << n << " is " << p->state << + info << "expected it to be configured"; + + level4 ([&]{trace << p->name << " " << p->version;}); + + pkg_disfigure (c, t, p); // Commits the transaction. + + if (verb) + text << "disfigured " << p->name << " " << p->version; + } +} -- cgit v1.1