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-configure.cxx | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 bpkg/pkg-configure.cxx (limited to 'bpkg/pkg-configure.cxx') diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx new file mode 100644 index 0000000..e680b61 --- /dev/null +++ b/bpkg/pkg-configure.cxx @@ -0,0 +1,122 @@ +// file : bpkg/pkg-configure.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace butl; + +namespace bpkg +{ + void + pkg_configure (const pkg_configure_options& o, cli::scanner& args) + { + tracer trace ("pkg_configure"); + + dir_path c (o.directory ()); + level4 ([&]{trace << "configuration: " << c;}); + + // Sort arguments into the package name and configuration variables. + // + string n; + strings vars; + + while (args.more ()) + { + string a (args.next ()); + + if (a.find ('=') != string::npos) + vars.push_back (move (a)); + else if (n.empty ()) + n = move (a); + else + fail << "unexpected argument '" << a << "'"; + } + + if (n.empty ()) + fail << "package name argument expected" << + info << "run 'bpkg help pkg-configure' for more information"; + + 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::unpacked) + fail << "package " << n << " is " << p->state << + info << "expected it to be unpacked"; + + level4 ([&]{trace << p->name << " " << p->version;}); + + // Calculate package's src_root and out_root. + // + assert (p->src_root); // Must be set since unpacked. + + dir_path src_root (p->src_root->absolute () + ? *p->src_root + : c / *p->src_root); + dir_path out_root (c / dir_path (p->name + "-" + p->version.string ())); + + level4 ([&]{trace << "src_root: " << src_root << ", " + << "out_root: " << out_root;}); + + // Form the buildspec. + // + string bspec; + + if (src_root == out_root) + bspec = "configure(" + out_root.string () + "/)"; + else + bspec = "configure(" + + src_root.string () + "/@" + + out_root.string () + "/)"; + + level4 ([&]{trace << "buildspec: " << bspec;}); + + // Configure. + // + try + { + run_b (bspec); + } + catch (const failed&) + { + // If we failed to configure the package, make sure we revert + // it back to the unpacked state by running disfigure (it is + // valid to run disfigure on an un-configured build). And if + // disfigure fails as well, then the package will be set into + // the broken state. + // + + // Pretend we are configured. + // + p->out_root = out_root.leaf (); + p->state = state::configured; + + pkg_disfigure (c, t, p); // Commits the transaction. + throw; + } + + p->out_root = out_root.leaf (); + p->state = state::configured; + + db.update (p); + t.commit (); + + if (verb) + text << "configured " << p->name << " " << p->version; + } +} -- cgit v1.1