diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2019-01-16 13:20:33 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2019-01-16 18:27:12 +0300 |
commit | a3a07e76263db6a2ecc44865fb92107e672a109b (patch) | |
tree | de4cc9c0971acfb761797a7afde5c8c41800fceb /bbot/worker/worker.cxx | |
parent | f2440755ae42b70ecd9969bb7ed59884a85f4965 (diff) |
Use `b info` command to check if package project/subprojects can be tested
Diffstat (limited to 'bbot/worker/worker.cxx')
-rw-r--r-- | bbot/worker/worker.cxx | 145 |
1 files changed, 117 insertions, 28 deletions
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 <map> #include <regex> -#include <cstring> // strchr() +#include <cstring> // strchr() #include <sstream> #include <iostream> +#include <algorithm> // find() +#include <libbutl/b.mxx> #include <libbutl/pager.mxx> #include <libbutl/filesystem.mxx> #include <libbutl/string-parser.mxx> @@ -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> (a)...); +} + +template <typename V, typename... A> +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 <config-args> <env-config-args> <package-name> // @@ -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<string, 1> envvars {move (paths)}; - // b configure(<tests-dir>@<tests-out-dir>) <config-args> - // <env-config-args> - // - // 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(<subprj-src-dir>@<subprj-out-dir>) <config-args> + // <env-config-args> + // + // 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(<tests-out-dir>) <config-args> <env-config-args> + // Build/test subprojects. + // + // b test(<subprj-out-dir>)... <config-args> <env-config-args> // // 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)); |