aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-12-12 13:21:36 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-12-12 13:21:36 +0200
commitaeae50fe987b1787d1c1ae6f5c0bfb4f179205ef (patch)
treeeee92e23aa81b057688b5cea7fae6487b0470244
parent272437d0680dc39607140fc041bac9d3cdfbd626 (diff)
Add no_subprojects parameter to info meta-operation
-rw-r--r--build2/b.cxx21
-rw-r--r--libbuild2/b.cli9
-rw-r--r--libbuild2/operation.cxx83
-rw-r--r--libbuild2/operation.hxx5
4 files changed, 90 insertions, 28 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 0e52d25..2f94bbc 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -476,13 +476,13 @@ main (int argc, char* argv[])
// Note: omit reserving anything for the info meta-operation since it
// won't be loading the buildfiles and needs to be as fast as possible.
//
- if (bspec.size () == 1 &&
- bspec.front ().size () == 1 &&
- (bspec.front ().name == "info" ||
- (bspec.front ().name.empty () &&
- bspec.front ().front ().name == "info")))
- ;
- else
+ bool info (bspec.size () == 1 &&
+ bspec.front ().size () == 1 &&
+ (bspec.front ().name == "info" ||
+ (bspec.front ().name.empty () &&
+ bspec.front ().front ().name == "info")));
+
+ if (!info)
pctx->reserve (context::reserves {
30000 /* targets */,
1100 /* variables */});
@@ -895,8 +895,13 @@ main (int argc, char* argv[])
// Now that we have src_root, load the src_root bootstrap file,
// if there is one.
//
+ // As an optimization, omit discovering subprojects for the info
+ // meta-operation if not needed.
+ //
bootstrap_pre (rs, altn);
- bootstrap_src (rs, altn);
+ bootstrap_src (rs, altn,
+ nullopt /* amalgamation */,
+ !info || info_subprojects (mparams) /*subprojects*/);
// If this is a simple project, then implicitly load the test and
// install modules.
diff --git a/libbuild2/b.cli b/libbuild2/b.cli
index 773e29e..5d6ead2 100644
--- a/libbuild2/b.cli
+++ b/libbuild2/b.cli
@@ -328,11 +328,20 @@ namespace build2
version: 1.0.0
src_root: /tmp/libfoo
out_root: /tmp/libfoo
+ subprojects: @tests
project: libbar
version: 2.0.0
src_root: /tmp/libbar
out_root: /tmp/libbar-out
+ subprojects: @tests
+ \
+
+ To omit discovering and printing subprojects information, use the
+ \cb{no_subprojects} parameter, for example:
+
+ \
+ $ b info: libfoo/,no_subprojects
\
To instead print this information in the JSON format, use the
diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx
index 4146b57..0e782d1 100644
--- a/libbuild2/operation.cxx
+++ b/libbuild2/operation.cxx
@@ -807,31 +807,66 @@ namespace build2
// Note: similar approach to forward() in configure.
//
- static bool
- info_json (const values& params,
- const char* mo = nullptr,
- const location& l = location ())
+ struct info_params
{
+ bool json = false;
+ bool subprojects = true;
+ };
+
+ // Note: should not fail if mo is NULL (see info_subprojects() below).
+ //
+ static info_params
+ info_parse_params (const values& params,
+ const char* mo = nullptr,
+ const location& l = location ())
+ {
+ info_params r;
+
if (params.size () == 1)
{
- const names& ns (cast<names> (params[0]));
+ for (const name& n: cast<names> (params[0]))
+ {
+ if (n.simple ())
+ {
+ if (n.value == "json")
+ {
+ r.json = true;
+ continue;
+ }
+
+ if (n.value == "no_subprojects")
+ {
+ r.subprojects = false;
+ continue;
+ }
+
+ // Fall through.
+ }
- if (ns.size () == 1 && ns[0].simple () && ns[0].value == "json")
- return true;
- else if (!ns.empty ())
- fail (l) << "unexpected parameter '" << ns << "' for "
- << "meta-operation " << mo;
+ if (mo != nullptr)
+ fail (l) << "unexpected parameter '" << n << "' for "
+ << "meta-operation " << mo;
+ }
}
else if (!params.empty ())
+ {
+ if (mo != nullptr)
fail (l) << "unexpected parameters for meta-operation " << mo;
+ }
- return false;
+ return r;
+ }
+
+ bool
+ info_subprojects (const values& params)
+ {
+ return info_parse_params (params).subprojects;
}
static void
info_pre (context&, const values& params, const location& l)
{
- info_json (params, "info", l); // Validate.
+ info_parse_params (params, "info", l); // Validate.
}
static operation_id
@@ -884,7 +919,7 @@ namespace build2
}
static void
- info_execute_lines (action_targets& ts)
+ info_execute_lines (action_targets& ts, bool subp)
{
for (size_t i (0); i != ts.size (); ++i)
{
@@ -958,8 +993,13 @@ namespace build2
<< "url:" ; print_empty (cast_empty<string> (rs[ctx.var_project_url])); cout << endl
<< "src_root:" ; print_dir (cast<dir_path> (rs[ctx.var_src_root])); cout << endl
<< "out_root:" ; print_dir (cast<dir_path> (rs[ctx.var_out_root])); cout << endl
- << "amalgamation:" ; print_pdir (*rs.root_extra->amalgamation); cout << endl
- << "subprojects:" ; print_null (*rs.root_extra->subprojects); cout << endl
+ << "amalgamation:" ; print_pdir (*rs.root_extra->amalgamation); cout << endl;
+ if (subp)
+ {
+ cout
+ << "subprojects:" ; print_null (*rs.root_extra->subprojects); cout << endl;
+ }
+ cout
<< "operations:" ; print_ops (rs.root_extra->operations, ctx.operation_table); cout << endl
<< "meta-operations:"; print_ops (rs.root_extra->meta_operations, ctx.meta_operation_table); cout << endl
<< "modules:" ; print_mods (); cout << endl;
@@ -968,7 +1008,7 @@ namespace build2
#ifndef BUILD2_BOOTSTRAP
static void
- info_execute_json (action_targets& ts)
+ info_execute_json (action_targets& ts, bool subp)
{
json::stream_serializer s (cout);
s.begin_array ();
@@ -1039,6 +1079,7 @@ namespace build2
// Print subprojects.
//
+ if (subp)
{
const subprojects* sps (*rs.root_extra->subprojects);
@@ -1101,7 +1142,7 @@ namespace build2
}
#else
static void
- info_execute_json (action_targets&)
+ info_execute_json (action_targets&, bool)
{
}
#endif //BUILD2_BOOTSTRAP
@@ -1113,14 +1154,16 @@ namespace build2
uint16_t,
bool)
{
+ info_params ip (info_parse_params (params));
+
// Note that both outputs will not be "ideal" if the user does something
// like `b info(foo/) info(bar/)` instead of `b info(foo/ bar/)`. Oh,
// well.
//
- if (info_json (params))
- info_execute_json (ts);
+ if (ip.json)
+ info_execute_json (ts, ip.subprojects);
else
- info_execute_lines (ts);
+ info_execute_lines (ts, ip.subprojects);
}
const meta_operation_info mo_info {
diff --git a/libbuild2/operation.hxx b/libbuild2/operation.hxx
index 2ff82ad..fd5eea0 100644
--- a/libbuild2/operation.hxx
+++ b/libbuild2/operation.hxx
@@ -182,6 +182,11 @@ namespace build2
LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_perform;
LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_info;
+ // Return true if params does not contain no_subprojects.
+ //
+ bool
+ info_subprojects (const values& params);
+
// Operation info.
//
// NOTE: keep POD-like to ensure can be constant-initialized in order to