aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/dist/init.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/dist/init.cxx')
-rw-r--r--libbuild2/dist/init.cxx192
1 files changed, 192 insertions, 0 deletions
diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx
new file mode 100644
index 0000000..959b2dd
--- /dev/null
+++ b/libbuild2/dist/init.cxx
@@ -0,0 +1,192 @@
+// file : libbuild2/dist/init.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <libbuild2/dist/init.hxx>
+
+#include <libbuild2/scope.hxx>
+#include <libbuild2/file.hxx>
+#include <libbuild2/diagnostics.hxx>
+
+#include <libbuild2/config/utility.hxx>
+
+#include <libbuild2/dist/rule.hxx>
+#include <libbuild2/dist/module.hxx>
+#include <libbuild2/dist/operation.hxx>
+
+using namespace std;
+using namespace butl;
+
+namespace build2
+{
+ namespace dist
+ {
+ static const rule rule_;
+
+ bool
+ boot (scope& rs, const location&, unique_ptr<module_base>& mod)
+ {
+ tracer trace ("dist::boot");
+
+ l5 ([&]{trace << "for " << rs;});
+
+ // Register the meta-operation.
+ //
+ rs.insert_meta_operation (dist_id, mo_dist);
+
+ // Enter module variables. Do it during boot in case they get assigned
+ // in bootstrap.build (which is customary for, e.g., dist.package).
+ //
+ auto& vp (var_pool.rw (rs));
+
+ // Note: some overridable, some not.
+ //
+ // config.dist.archives is a list of archive extensions (e.g., zip,
+ // tar.gz) that can be optionally prefixed with a directory. If it is
+ // relative, then it is prefixed with config.dist.root. Otherwise, the
+ // archive is written to the absolute location.
+ //
+ // config.dist.checksums is a list of archive checksum extensions (e.g.,
+ // sha1, sha256) that can also be optionally prefixed with a directory
+ // with the same semantics as config.dist.archives. If the directory is
+ // absent, then the checksum file is written into the same directory as
+ // the corresponding archive.
+ //
+ vp.insert<abs_dir_path> ("config.dist.root", true);
+ vp.insert<paths> ("config.dist.archives", true);
+ vp.insert<paths> ("config.dist.checksums", true);
+ vp.insert<path> ("config.dist.cmd", true);
+
+ // Allow distribution of uncommitted projects. This is enforced by the
+ // version module.
+ //
+ vp.insert<bool> ("config.dist.uncommitted", true);
+
+ vp.insert<dir_path> ("dist.root");
+ vp.insert<process_path> ("dist.cmd");
+ vp.insert<paths> ("dist.archives");
+ vp.insert<paths> ("dist.checksums");
+ vp.insert<paths> ("dist.uncommitted");
+
+ vp.insert<bool> ("dist", variable_visibility::target); // Flag.
+
+ // Project's package name.
+ //
+ auto& v_d_p (
+ vp.insert<string> ("dist.package", variable_visibility::project));
+
+ // Create the module.
+ //
+ mod.reset (new module (v_d_p));
+
+ return false;
+ }
+
+ bool
+ init (scope& rs,
+ scope&,
+ const location& l,
+ unique_ptr<module_base>&,
+ bool first,
+ bool,
+ const variable_map& config_hints)
+ {
+ tracer trace ("dist::init");
+
+ if (!first)
+ {
+ warn (l) << "multiple dist module initializations";
+ return true;
+ }
+
+ const dir_path& out_root (rs.out_path ());
+ l5 ([&]{trace << "for " << out_root;});
+
+ assert (config_hints.empty ()); // We don't known any hints.
+
+ // Register our wildcard rule. Do it explicitly for the alias to prevent
+ // something like insert<target>(dist_id, test_id) taking precedence.
+ //
+ rs.rules.insert<target> (dist_id, 0, "dist", rule_);
+ rs.rules.insert<alias> (dist_id, 0, "dist.alias", rule_); //@@ outer?
+
+ // Configuration.
+ //
+ // Note that we don't use any defaults for root -- the location
+ // must be explicitly specified or we will complain if and when
+ // we try to dist.
+ //
+ bool s (config::specified (rs, "dist"));
+
+ // Adjust module priority so that the config.dist.* values are saved at
+ // the end of config.build.
+ //
+ if (s)
+ config::save_module (rs, "dist", INT32_MAX);
+
+ // dist.root
+ //
+ {
+ value& v (rs.assign ("dist.root"));
+
+ if (s)
+ {
+ if (lookup l = config::optional (rs, "config.dist.root"))
+ v = cast<dir_path> (l); // Strip abs_dir_path.
+ }
+ }
+
+ // dist.cmd
+ //
+ {
+ value& v (rs.assign<process_path> ("dist.cmd"));
+
+ if (s)
+ {
+ if (lookup l = config::required (rs,
+ "config.dist.cmd",
+ path ("install")).first)
+ v = run_search (cast<path> (l), true);
+ }
+ }
+
+ // dist.archives
+ // dist.checksums
+ //
+ {
+ value& a (rs.assign ("dist.archives"));
+ value& c (rs.assign ("dist.checksums"));
+
+ if (s)
+ {
+ if (lookup l = config::optional (rs, "config.dist.archives"))
+ a = *l;
+
+ if (lookup l = config::optional (rs, "config.dist.checksums"))
+ {
+ c = *l;
+
+ if (!c.empty () && (!a || a.empty ()))
+ fail << "config.dist.checksums specified without "
+ << "config.dist.archives";
+
+ }
+ }
+ }
+
+ // dist.uncommitted
+ //
+ // Omit it from the configuration unless specified.
+ //
+ config::omitted (rs, "config.dist.uncommitted");
+
+ return true;
+ }
+
+ module_functions
+ build2_dist_load ()
+ {
+ return module_functions {&boot, &init};
+ }
+ }
+}