| int dispatch_main(const options& opts) noexcept { | int dispatch_main(const options& opts) noexcept { | ||||
| dds::log::current_log_level = opts.log_level; | dds::log::current_log_level = opts.log_level; | ||||
| return dds::handle_cli_errors([&] { | return dds::handle_cli_errors([&] { | ||||
| DDS_E_SCOPE(opts.subcommand); | |||||
| switch (opts.subcommand) { | switch (opts.subcommand) { | ||||
| case subcommand::build: | case subcommand::build: | ||||
| return cmd::build(opts); | return cmd::build(opts); | ||||
| case subcommand::sdist: | |||||
| case subcommand::sdist: { | |||||
| DDS_E_SCOPE(opts.sdist.subcommand); | |||||
| switch (opts.sdist.subcommand) { | switch (opts.sdist.subcommand) { | ||||
| case sdist_subcommand::create: | case sdist_subcommand::create: | ||||
| return cmd::sdist_create(opts); | return cmd::sdist_create(opts); | ||||
| case sdist_subcommand::_none_:; | case sdist_subcommand::_none_:; | ||||
| } | } | ||||
| neo::unreachable(); | neo::unreachable(); | ||||
| case subcommand::pkg: | |||||
| } | |||||
| case subcommand::pkg: { | |||||
| DDS_E_SCOPE(opts.pkg.subcommand); | |||||
| switch (opts.pkg.subcommand) { | switch (opts.pkg.subcommand) { | ||||
| case pkg_subcommand::ls: | case pkg_subcommand::ls: | ||||
| return cmd::pkg_ls(opts); | return cmd::pkg_ls(opts); | ||||
| return cmd::pkg_get(opts); | return cmd::pkg_get(opts); | ||||
| case pkg_subcommand::import: | case pkg_subcommand::import: | ||||
| return cmd::pkg_import(opts); | return cmd::pkg_import(opts); | ||||
| case pkg_subcommand::repo: | |||||
| case pkg_subcommand::repo: { | |||||
| DDS_E_SCOPE(opts.pkg.repo.subcommand); | |||||
| switch (opts.pkg.repo.subcommand) { | switch (opts.pkg.repo.subcommand) { | ||||
| case pkg_repo_subcommand::add: | case pkg_repo_subcommand::add: | ||||
| return cmd::pkg_repo_add(opts); | return cmd::pkg_repo_add(opts); | ||||
| case pkg_repo_subcommand::_none_:; | case pkg_repo_subcommand::_none_:; | ||||
| } | } | ||||
| neo::unreachable(); | neo::unreachable(); | ||||
| } | |||||
| case pkg_subcommand::_none_:; | case pkg_subcommand::_none_:; | ||||
| } | } | ||||
| neo::unreachable(); | neo::unreachable(); | ||||
| case subcommand::repoman: | |||||
| } | |||||
| case subcommand::repoman: { | |||||
| DDS_E_SCOPE(opts.repoman.subcommand); | |||||
| switch (opts.repoman.subcommand) { | switch (opts.repoman.subcommand) { | ||||
| case repoman_subcommand::import: | case repoman_subcommand::import: | ||||
| return cmd::repoman_import(opts); | return cmd::repoman_import(opts); | ||||
| case repoman_subcommand::_none_:; | case repoman_subcommand::_none_:; | ||||
| } | } | ||||
| neo::unreachable(); | neo::unreachable(); | ||||
| } | |||||
| case subcommand::compile_file: | case subcommand::compile_file: | ||||
| return cmd::compile_file(opts); | return cmd::compile_file(opts); | ||||
| case subcommand::build_deps: | case subcommand::build_deps: |
| #include <fstream> | #include <fstream> | ||||
| namespace { | |||||
| using namespace dds; | |||||
| template <dds::cli::subcommand Val> | |||||
| using subcommand = boost::leaf::match<dds::cli::subcommand, Val>; | |||||
| namespace { | |||||
| auto handlers = std::tuple( // | auto handlers = std::tuple( // | ||||
| [](neo::url_validation_error exc, dds::e_url_string bad_url) { | |||||
| [](neo::url_validation_error exc, e_url_string bad_url) { | |||||
| dds_log(error, "Invalid URL '{}': {}", bad_url.value, exc.what()); | dds_log(error, "Invalid URL '{}': {}", bad_url.value, exc.what()); | ||||
| return 1; | return 1; | ||||
| }, | }, | ||||
| [](boost::leaf::catch_<dds::error_base> exc, | |||||
| json5::parse_error parse_err, | |||||
| boost::leaf::e_file_name* maybe_fpath) { | |||||
| [](boost::leaf::catch_<error_base> exc, | |||||
| json5::parse_error parse_err, | |||||
| boost::leaf::e_file_name* maybe_fpath) { | |||||
| dds_log(error, "{}", exc.value().what()); | dds_log(error, "{}", exc.value().what()); | ||||
| dds_log(error, "Invalid JSON5 was found: {}", parse_err.what()); | dds_log(error, "Invalid JSON5 was found: {}", parse_err.what()); | ||||
| if (maybe_fpath) { | if (maybe_fpath) { | ||||
| dds_log(error, " (While reading from [{}])", maybe_fpath->value); | dds_log(error, " (While reading from [{}])", maybe_fpath->value); | ||||
| } | } | ||||
| dds_log(error, "{}", exc.value().explanation()); | dds_log(error, "{}", exc.value().explanation()); | ||||
| dds::write_error_marker("package-json5-parse-error"); | |||||
| write_error_marker("package-json5-parse-error"); | |||||
| return 1; | |||||
| }, | |||||
| [](user_error<errc::test_failure> exc, matchv<cli::subcommand::build>) { | |||||
| write_error_marker("build-failed-test-failed"); | |||||
| dds_log(error, "{}", exc.what()); | |||||
| dds_log(error, "{}", exc.explanation()); | |||||
| dds_log(error, "Refer: {}", exc.error_reference()); | |||||
| return 1; | return 1; | ||||
| }, | }, | ||||
| [](boost::leaf::catch_<dds::error_base> exc) { | |||||
| [](boost::leaf::catch_<error_base> exc) { | |||||
| dds_log(error, "{}", exc.value().what()); | dds_log(error, "{}", exc.value().what()); | ||||
| dds_log(error, "{}", exc.value().explanation()); | dds_log(error, "{}", exc.value().explanation()); | ||||
| dds_log(error, "Refer: {}", exc.value().error_reference()); | dds_log(error, "Refer: {}", exc.value().error_reference()); | ||||
| return 1; | return 1; | ||||
| }, | }, | ||||
| [](dds::user_cancelled) { | |||||
| [](user_cancelled) { | |||||
| dds_log(critical, "Operation cancelled by the user"); | dds_log(critical, "Operation cancelled by the user"); | ||||
| return 2; | return 2; | ||||
| }, | }, | ||||
| [](dds::e_system_error_exc exc, boost::leaf::verbose_diagnostic_info const& diag) { | |||||
| [](e_system_error_exc exc, boost::leaf::verbose_diagnostic_info const& diag) { | |||||
| dds_log(critical, | dds_log(critical, | ||||
| "An unhandled std::system_error arose. THIS IS A DDS BUG! Info: {}", | "An unhandled std::system_error arose. THIS IS A DDS BUG! Info: {}", | ||||
| diag); | diag); |
| import pytest | import pytest | ||||
| from dds_ci import paths | from dds_ci import paths | ||||
| from dds_ci.testing.error import expect_error_marker | |||||
| from dds_ci.testing import Project, PackageJSON | from dds_ci.testing import Project, PackageJSON | ||||
| assert tmp_project.build_root.joinpath(f'test/foo{paths.EXE_SUFFIX}').is_file() | assert tmp_project.build_root.joinpath(f'test/foo{paths.EXE_SUFFIX}').is_file() | ||||
| def test_lib_with_failing_test(tmp_project: Project) -> None: | |||||
| tmp_project.write('src/foo.test.cpp', 'int main() { return 2; }') | |||||
| with expect_error_marker('build-failed-test-failed'): | |||||
| tmp_project.build() | |||||
| TEST_PACKAGE: PackageJSON = { | TEST_PACKAGE: PackageJSON = { | ||||
| 'name': 'test-pkg', | 'name': 'test-pkg', | ||||
| 'version': '0.2.2', | 'version': '0.2.2', |