From a3a07e76263db6a2ecc44865fb92107e672a109b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 16 Jan 2019 13:20:33 +0300 Subject: Use `b info` command to check if package project/subprojects can be tested --- bbot/worker/worker.cxx | 145 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 117 insertions(+), 28 deletions(-) (limited to 'bbot') diff --git a/bbot/worker/worker.cxx b/bbot/worker/worker.cxx index 6a8eda0..fd6232c 100644 --- a/bbot/worker/worker.cxx +++ b/bbot/worker/worker.cxx @@ -10,10 +10,12 @@ #include #include -#include // strchr() +#include // strchr() #include #include +#include // find() +#include #include #include #include @@ -210,6 +212,29 @@ static result_status run_b (tracer& t, string& log, const regexes& warn_detect, const V& envvars, + const strings& buildspecs, A&&... a) +{ + string name ("b"); + for (const string& s: buildspecs) + { + if (!name.empty ()) + name += ' '; + + name += s; + } + + return run_cmd (t, + log, warn_detect, + name, + process_env ("b", envvars), + "-v", buildspecs, forward (a)...); +} + +template +static result_status +run_b (tracer& t, + string& log, const regexes& warn_detect, + const V& envvars, const string& buildspec, A&&... a) { return run_cmd (t, @@ -577,8 +602,33 @@ build (size_t argc, const char* argv[]) rm.status |= r.status; } - // Test. + // Query the package's build system information with `b info`. + // + dir_path prj_dir (tm.name.string () + '-' + tm.version.string ()); + b_project_info prj; + + // Note that `b info` diagnostics will not be copied into any of the build + // logs. This seems to be fine, as this is likely to be an infrastructural + // problem, given that the project distribution has been successfully + // created. It's actually not quite clear which log this diagnostics could + // go into. + // + try + { + prj = b_info (prj_dir, verb, trace); + } + catch (const b_error& e) + { + if (e.normal ()) + throw failed (); // Assume the build2 process issued diagnostics. + + fail << "unable to query project " << prj_dir << " info: " << e; + } + + // Test the package if the test operation is supported by the project. // + if (find (prj.operations.begin (), prj.operations.end (), "test") != + prj.operations.end ()) { operation_result& r (add_result ("test")); @@ -587,8 +637,7 @@ build (size_t argc, const char* argv[]) // uncommon for them to expect that tests should run in the project root // directory. // - dir_path d (tm.name.string () + '-' + tm.version.string ()); - dir_path rwd (change_wd (trace, &r.log, d)); + dir_path rwd (change_wd (trace, &r.log, prj_dir)); // bpkg test // @@ -624,9 +673,9 @@ build (size_t argc, const char* argv[]) // // 1. Install the package. // - // 2. If the package project has the 'tests' subdirectory that is a - // subproject, then configure, build and test it out of the source tree - // against the installed package. + // 2. If the package has subprojects that support the test operation, then + // configure, build, and test them out of the source tree against the + // installed package. // // 3. Uninstall the package. // @@ -654,15 +703,40 @@ build (size_t argc, const char* argv[]) // Test installed. // - // The package tests subdirectory path (may not exist). + // Collect the "testable" subprojects. // - dir_path tests_dir (tm.name.string () + "-" + tm.version.string ()); - tests_dir /= "tests"; + dir_paths subprj_dirs; + for (const b_project_info::subproject& sp: prj.subprojects) + { + // Retrieve the subproject information similar to how we've done it for + // the package. + // + dir_path sd (prj_dir / sp.path); + + // Note that `b info` diagnostics will not be logged (see above for + // details). + // + try + { + b_project_info si (b_info (sd, verb, trace)); + + const strings& ops (si.operations); + if (find (ops.begin (), ops.end (), "test") != ops.end ()) + subprj_dirs.push_back (sp.path); + } + catch (const b_error& e) + { + if (e.normal ()) + throw failed (); // Assume the build2 process issued diagnostics. - // We will consider the tests subdirectory to be a subproject if it - // contains a build2 bootstrap file. + fail << "unable to query subproject " << sd << " info: " << e; + } + } + + // If there are any "testable" subprojects, then configure them + // (sequentially) and test/build in parallel afterwards. // - if (file_exists (tests_dir / path ("build/bootstrap.build"))) + if (!subprj_dirs.empty ()) { operation_result& r (add_result ("test-installed")); @@ -714,35 +788,50 @@ build (size_t argc, const char* argv[]) small_vector envvars {move (paths)}; - // b configure(@) - // - // - // b.test-installed.configure + // Configure subprojects and create buildspecs for their testing. // - dir_path tests_out_dir (out_dir / dir_path ("tests")); + strings test_specs; + for (const dir_path& d: subprj_dirs) + { + // b configure(@) + // + // + // b.test-installed.configure + // + dir_path subprj_src_dir (build_dir / prj_dir / d); + dir_path subprj_out_dir (out_dir / d); + + r.status |= run_b ( + trace, r.log, wre, + envvars, + "configure(" + + subprj_src_dir.representation () + '@' + + subprj_out_dir.representation () + ")", + step_args (config_args, step_id::b_test_installed_configure), + step_args (env_args, step_id::b_test_installed_configure)); + + if (!r.status) + break; - r.status |= run_b ( - trace, r.log, wre, - envvars, - "configure(" + - (build_dir / tests_dir).representation () + '@' + - tests_out_dir.representation () + ")", - step_args (config_args, step_id::b_test_installed_configure), - step_args (env_args, step_id::b_test_installed_configure)); + test_specs.push_back ( + "test(" + subprj_out_dir.representation () + ')'); + } if (!r.status) break; rm.status |= r.status; - // b test() + // Build/test subprojects. + // + // b test()... // // b.test-installed.test // r.status |= run_b ( trace, r.log, wre, envvars, - "test(" + tests_out_dir.representation () + ')', + test_specs, step_args (config_args, step_id::b_test_installed_test), step_args (env_args, step_id::b_test_installed_test)); -- cgit v1.1