From aeae50fe987b1787d1c1ae6f5c0bfb4f179205ef Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 12 Dec 2022 13:21:36 +0200 Subject: Add no_subprojects parameter to info meta-operation --- build2/b.cxx | 21 ++++++++----- libbuild2/b.cli | 9 ++++++ libbuild2/operation.cxx | 83 +++++++++++++++++++++++++++++++++++++------------ libbuild2/operation.hxx | 5 +++ 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 (params[0])); + for (const name& n: cast (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 (rs[ctx.var_project_url])); cout << endl << "src_root:" ; print_dir (cast (rs[ctx.var_src_root])); cout << endl << "out_root:" ; print_dir (cast (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 -- cgit v1.1