From 559197bc4f8d1f58e7853d2854070cd6399fecc6 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Tue, 25 Jul 2023 19:09:30 +0200 Subject: [PATCH 01/39] feat(core): add native filter, with arguments --- apps/CMakeLists.txt | 40 +++- apps/filters/coveralls.py | 5 +- apps/filters/native/platform.cc | 35 +++ apps/filters/native/platform.hh | 13 + apps/filters/native/str.hh | 55 +++++ .../filters/native/strip_excludes/excludes.cc | 124 ++++++++++ .../filters/native/strip_excludes/excludes.hh | 47 ++++ apps/filters/native/strip_excludes/parser.cc | 28 +++ apps/filters/native/strip_excludes/parser.hh | 44 ++++ apps/filters/strip_excludes.cc | 225 ++++++++++++++++++ apps/report-schema.json | 4 +- .../008-report-A/067-report-help.json | 2 +- docs/roadmap.md | 1 + libs/cov-rt/include/cov/app/report_command.hh | 5 +- libs/cov-rt/include/cov/app/tools.hh | 1 + libs/cov-rt/src/posix.cc | 3 +- libs/cov-rt/src/report_command.cc | 43 +++- libs/cov-rt/src/win32.cc | 3 +- 18 files changed, 662 insertions(+), 16 deletions(-) create mode 100644 apps/filters/native/platform.cc create mode 100644 apps/filters/native/platform.hh create mode 100644 apps/filters/native/str.hh create mode 100644 apps/filters/native/strip_excludes/excludes.cc create mode 100644 apps/filters/native/strip_excludes/excludes.hh create mode 100644 apps/filters/native/strip_excludes/parser.cc create mode 100644 apps/filters/native/strip_excludes/parser.hh create mode 100644 apps/filters/strip_excludes.cc diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index a90ba898..22c9f728 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -17,6 +17,10 @@ set(REPORT_FILTERS coveralls ) +set(NATIVE_FILTERS + strip-excludes +) + set(SOURCES cov/cov.cc ) @@ -34,7 +38,7 @@ string(REPLACE ";" ", " BUILTIN_LIST "${BUILTINS}") message(STATUS "Builtins: ${BUILTIN_LIST}") include(builtins) -string(REPLACE ";" ", " REPORT_FILTER_LIST "${REPORT_FILTERS}") +string(REPLACE ";" ", " REPORT_FILTER_LIST "${REPORT_FILTERS};${NATIVE_FILTERS}") message(STATUS "Filters: ${REPORT_FILTER_LIST}") if (WIN32) @@ -97,6 +101,40 @@ foreach(NAME ${REPORT_FILTERS}) ) endforeach() +foreach(NAME ${NATIVE_FILTERS}) + string(REPLACE "-" "_" SAFE_NAME "${NAME}") + add_cov_tool(${NAME} + filters/${SAFE_NAME}.cc + filters/native/platform.cc + filters/native/platform.hh) + target_compile_options(${NAME} PRIVATE ${ADDITIONAL_WALL_FLAGS}) + target_link_options(${NAME} PRIVATE ${ADDITIONAL_LINK_FLAGS}) + target_include_directories(${NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/filters + ${CMAKE_CURRENT_BINARY_DIR}/gen + ) + set_target_properties(${NAME} PROPERTIES FOLDER apps) + + set_target_properties(${NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" + ) + + foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set_target_properties(${NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" + ) + endforeach() +endforeach() + +target_link_libraries(strip-excludes PRIVATE ctre::ctre) +target_sources(strip-excludes PRIVATE + filters/native/strip_excludes/parser.cc + filters/native/strip_excludes/parser.hh + filters/native/strip_excludes/excludes.cc + filters/native/strip_excludes/excludes.hh +) + ######################################################## # add_cov_ext(serve) diff --git a/apps/filters/coveralls.py b/apps/filters/coveralls.py index 2d8adb21..1efb2f46 100755 --- a/apps/filters/coveralls.py +++ b/apps/filters/coveralls.py @@ -5,13 +5,13 @@ from typing import Dict, List, Optional -def lines_from(lines: List[Optional[int]]) -> Dict[int, int]: +def lines_from(lines: List[Optional[int]]) -> Dict[str, int]: result: Dict[int, int] = {} for index in range(len(lines)): count = lines[index] if count is not None: result[index + 1] = count - return result + return {str(line): count for line, count in result.items()} def cov_from(coveralls: dict) -> dict: @@ -36,4 +36,5 @@ def cov_from(coveralls: dict) -> dict: "files": [cov_from(source_file) for source_file in data["source_files"]], }, sys.stdout, + sort_keys=True, ) diff --git a/apps/filters/native/platform.cc b/apps/filters/native/platform.cc new file mode 100644 index 00000000..ec8389aa --- /dev/null +++ b/apps/filters/native/platform.cc @@ -0,0 +1,35 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "platform.hh" +#include +#include + +using namespace std::literals; + +namespace cov::app::platform { + std::filesystem::path const& sys_root() { + static auto const root = [] { + auto const dir = exec_path().parent_path(); + // share/cov-XY/filters + return dir.parent_path().parent_path().parent_path(); + }(); + + return root; + } + + std::filesystem::path locale_dir() { + return sys_root() / directory_info::share / "locale"sv; + } // GCOV_EXCL_LINE + + std::vector read_input() { + std::vector result{}; + char8_t buffer[8192]; + + while (auto read = std::fread(buffer, 1, sizeof(buffer), stdin)) { + result.insert(result.end(), buffer, buffer + read); + } + + return result; + } +}; // namespace cov::app::platform diff --git a/apps/filters/native/platform.hh b/apps/filters/native/platform.hh new file mode 100644 index 00000000..d71e5c76 --- /dev/null +++ b/apps/filters/native/platform.hh @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include + +namespace cov::app::platform { + std::filesystem::path const& sys_root(); + std::filesystem::path locale_dir(); + std::vector read_input(); +}; // namespace cov::app::platform diff --git a/apps/filters/native/str.hh b/apps/filters/native/str.hh new file mode 100644 index 00000000..b44162ae --- /dev/null +++ b/apps/filters/native/str.hh @@ -0,0 +1,55 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include + +namespace cov::app { + inline std::u8string_view to_u8(std::string_view str) { + return {reinterpret_cast(str.data()), str.size()}; + } + + inline std::string_view from_u8(std::u8string_view str) { + return {reinterpret_cast(str.data()), str.size()}; + } + + inline std::string_view trim(std::string_view s) { + while (!s.empty() && + std::isspace(static_cast(s.front()))) + s = s.substr(1); + while (!s.empty() && std::isspace(static_cast(s.back()))) + s = s.substr(0, s.size() - 1); + return s; + } + + inline std::string tolower(std::string_view s) { + std::string result{}; + result.assign(s); + for (auto& c : result) { + c = static_cast(std::tolower(static_cast(c))); + } + return result; + } + + template + inline void split(std::string_view text, char sep, Callback&& cb) { + auto pos = text.find(sep); + decltype(pos) prev = 0; + + unsigned block = 0; + while (pos != std::string_view::npos) { + auto const block_end = pos; + auto const block_start = prev; + ++block; + prev = pos + 1; + pos = text.find(sep, prev); + cb(block, text.substr(block_start, block_end - block_start)); + } + ++block; + cb(block, text.substr(prev)); + } +}; // namespace cov::app diff --git a/apps/filters/native/strip_excludes/excludes.cc b/apps/filters/native/strip_excludes/excludes.cc new file mode 100644 index 00000000..c330d719 --- /dev/null +++ b/apps/filters/native/strip_excludes/excludes.cc @@ -0,0 +1,124 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "excludes.hh" +#include +#include +#include + +using namespace std::literals; + +namespace cov::app::strip { + static constexpr auto matches_tags = + ctre::search<"(?:G|L|GR)COV_EXCL_(?:START|LINE)\\[([^\\]]+)\\]">; + static constexpr auto matches_line = + ctre::search<"(?:G|L|GR)COV_EXCL_LINE">; + static constexpr auto matches_start = + ctre::search<"(?:G|L|GR)COV_EXCL_START">; + static constexpr auto matches_stop = + ctre::search<"(?:G|L|GR)COV_EXCL_STOP">; + static constexpr auto matches_end = ctre::search<"(?:G|L|GR)COV_EXCL_END">; + + bool excludes::has_any_marker(std::string_view markers) { + bool has = false; + split(markers, ',', [&](unsigned, std::string_view marker) { + if (has) return; + auto const key = tolower(trim(marker)); + for (auto const& known : valid_markers) { + if (known == key) { + has = true; + break; + } + } + }); + return has; + } + + void excludes::on_line(unsigned line_no, std::string_view text) { + if (trim(text).empty()) { + empties.insert(line_no); + return; + } + + if (auto const has_tags = matches_tags(text); has_tags) { + auto tags = has_tags.get<1>().to_view(); + if (!has_any_marker(tags)) return; + } + + auto switch_off = false; + if (matches_stop(text)) { + switch_off = true; + } else if (auto end_match = matches_end(text); end_match) { + if (inside_exclude) { + auto const end = end_match.get<0>().to_view(); + warn(line_no, end_match.get<0>().begin() - text.data() + 1, + fmt::format("found {}; did you mean {}?"sv, end, + stop_for(end, "_END"sv))); + } + } else if (auto start_match = matches_start(text); start_match) { + if (inside_exclude) { + warn(line_no, start_match.get<0>().begin() - text.data() + 1, + fmt::format("double start: found {}"sv, + start_match.get<0>().to_view())); + note(std::get<0>(last_start), std::get<1>(last_start), + "see previous start"); + } else { + last_start = {line_no, + start_match.get<0>().begin() - text.data() + 1, + start_match.get<0>().to_string()}; + } + inside_exclude = true; + } + + if (inside_exclude || matches_line(text)) { + exclude(line_no); + } + + if (switch_off) { + inside_exclude = false; + } + } + + void excludes::after_lines() { + if (inside_exclude) { + std::string_view start = std::get<2>(last_start); + warn(std::get<0>(last_start), std::get<1>(last_start), + fmt::format("{} not matched with {}"sv, start, + stop_for(start, "_START"sv))); + } + } + + void excludes::exclude(unsigned line) { + if (!result.empty() && result.back().end + 1 == line) { + result.back().end = line; + return; + } + result.push_back({line, line}); + } + + void excludes::warn(unsigned line, unsigned column, std::string_view msg) { + message(line, column, "\033[1;35mwarning"sv, msg); + } + + void excludes::note(unsigned line, unsigned column, std::string_view msg) { + message(line, column, "\033[1;36mnote"sv, msg); + } + + void excludes::message(unsigned line, + unsigned column, + std::string_view tag, + std::string_view msg) { + fmt::print(stderr, "\033[1;37m{}:{}:{}:\033[m {}:\033[m {}\n", path, + line, column, tag, msg); + } + + std::string excludes::stop_for(std::string_view start, + std::string_view suffix) { + if (start.ends_with(suffix)) + return fmt::format( + "{}_STOP", start.substr(0, start.length() - suffix.length())); + std::string stop{}; + stop.assign("GCOV_EXCL_STOP"sv); + return stop; + } +} // namespace cov::app::strip diff --git a/apps/filters/native/strip_excludes/excludes.hh b/apps/filters/native/strip_excludes/excludes.hh new file mode 100644 index 00000000..0053f132 --- /dev/null +++ b/apps/filters/native/strip_excludes/excludes.hh @@ -0,0 +1,47 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace cov::app::strip { + struct excl_block { + unsigned start{}; + unsigned end{}; + auto operator<=>(excl_block const&) const noexcept = default; + }; + + using exclude_result = + std::pair, std::set>; + + struct excludes { + std::string path; + std::span valid_markers; + bool inside_exclude{false}; + std::tuple last_start{}; + std::vector result{}; + std::set empties{}; + + bool has_any_marker(std::string_view markers); + void on_line(unsigned line_no, std::string_view text); + void after_lines(); + void exclude(unsigned line); + void warn(unsigned line, unsigned column, std::string_view msg); + void note(unsigned line, unsigned column, std::string_view msg); + void message(unsigned line, + unsigned column, + std::string_view tag, + std::string_view msg); + static std::string stop_for(std::string_view start, + std::string_view suffix); + }; + +} // namespace cov::app::strip diff --git a/apps/filters/native/strip_excludes/parser.cc b/apps/filters/native/strip_excludes/parser.cc new file mode 100644 index 00000000..d65ac459 --- /dev/null +++ b/apps/filters/native/strip_excludes/parser.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "parser.hh" + +namespace cov::app::strip { + parser::parser(::args::args_view const& arguments, + str::translator_open_info const& langs) + : base_parser{langs, arguments} { + using namespace str; + + parser_.arg(src_dir, "src").meta(tr_(args::lng::DIR_META)).opt(); + parser_.arg(compiler, "c", "compiler").meta(tr_(args::lng::NAME_META)); + parser_.arg(os, "os").meta(tr_(args::lng::NAME_META)); + } + + void parser::parse() { + parser_.parse(); + + if (!compiler) + compiler = + std::string{default_compiler.data(), default_compiler.size()}; + if (!os) os = std::string{platform.data(), platform.size()}; + + os = tolower(trim(*os)); + compiler = tolower(trim(*compiler)); + } +} // namespace cov::app::strip diff --git a/apps/filters/native/strip_excludes/parser.hh b/apps/filters/native/strip_excludes/parser.hh new file mode 100644 index 00000000..bc082dc7 --- /dev/null +++ b/apps/filters/native/strip_excludes/parser.hh @@ -0,0 +1,44 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace cov::app { + using errlng = str::errors::lng; + using ErrorsStrings = str::errors::Strings; + + template <> + struct lngs_traits + : base_lngs_traits {}; +}; // namespace cov::app + +namespace cov::app::strip { +#ifdef _WIN32 + static constexpr auto default_compiler = "msvc"sv; + static constexpr auto platform = "win32"sv; +#endif +#ifdef __linux__ + static constexpr auto default_compiler = "gcc"sv; + static constexpr auto platform = "posix"sv; +#endif + + struct parser : base_parser { + parser(::args::args_view const& arguments, + str::translator_open_info const& langs); + + void parse(); + + std::string src_dir{".", 1}; + std::optional compiler; + std::optional os; + }; +} // namespace cov::app::strip diff --git a/apps/filters/strip_excludes.cc b/apps/filters/strip_excludes.cc new file mode 100644 index 00000000..3e60f9c0 --- /dev/null +++ b/apps/filters/strip_excludes.cc @@ -0,0 +1,225 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace cov::app::strip { + exclude_result find_excl_blocks( + std::span valid_markers, + std::string_view path, + std::filesystem::path src_dir) { + std::error_code ec{}; + + auto const full_path = src_dir / make_u8path(path); + auto const opened = io::fopen(full_path, "rb"); + if (opened) { + auto stg = opened.read(); + excludes builder{.path = get_u8path(full_path), + .valid_markers = valid_markers}; + + auto const chars = std::string_view{ + reinterpret_cast(stg.data()), stg.size()}; + split(chars, '\n', [&](unsigned line_no, std::string_view text) { + builder.on_line(line_no, text); + }); + builder.after_lines(); + auto tmp = exclude_result{std::move(builder.result), + std::move(builder.empties)}; + return tmp; + } + + return {}; + } + enum which_lines { soft = false, hard = true }; + bool non_zero(json::node const& n) { + auto num = cast(n); + return num && *num; + } + + bool erase_line(json::map& line_coverage, + unsigned line, + which_lines intensity) { + auto const str = fmt::format("{}", line); + auto key = to_u8s(str); + auto it = line_coverage.find(key); + if (it != line_coverage.end()) { + if (intensity == hard || it->second == json::node{0}) { + line_coverage.erase(it); + return true; + } + } + return false; + } + + excl_block mask_range(json::map const& range, + std::span blocks) { + auto json_range_start = cast(range, u8"start_line"); + auto json_range_end = cast(range, u8"end_line"); + if (!json_range_start) return {.start = 1, .end = 0}; + auto start_line = *json_range_start; + auto end_line = json_range_end ? *json_range_end : start_line; + + for (auto const& block : blocks) { + auto const block_start = static_cast(block.start); + auto const block_end = static_cast(block.end); + + if (end_line < block_start || start_line > block_end) continue; + if (start_line >= block_start) start_line = block_end + 1; + if (end_line <= block_end) end_line = block_start - 1; + if (end_line < start_line) break; + } + return {.start = static_cast(start_line), + .end = static_cast(end_line)}; + } + + size_t filter_blocks(json::array* array, + std::span blocks) { + json::array visible{}; + size_t counter{}; + visible.reserve(array->size()); + for (auto& node_range : *array) { + auto json_range = cast(node_range); + if (!json_range) { + ++counter; + continue; + } + auto const block = mask_range(*json_range, blocks); + if (block.start > block.end) { + ++counter; + continue; + } + visible.emplace_back(std::move(node_range)); + } + *array = std::move(visible); + return counter; + } + + int tool(args::args_view const& arguments) { + parser p{arguments, {platform::locale_dir(), ::lngs::system_locales()}}; + p.parse(); + + std::vector valid_markers{*p.os, *p.compiler}; + if (*p.compiler == "clang"sv) + valid_markers.push_back("llvm"sv); + else if (*p.compiler == "llvm"sv) + valid_markers.push_back("clang"sv); + + auto const text = platform::read_input(); + auto root = json::read_json({text.data(), text.size()}); + auto cvg = json::cast(root); + if (!cvg) return 1; + + git::init memory{}; + + // TODO: after first major release, add code for compatibility check + // through $schema + auto head = json::cast_from_json(root, u8"git.head"sv); + auto files = json::cast_from_json(root, u8"files"sv); + if (!files || !head) return 1; + + auto const src_dir = + std::filesystem::weakly_canonical(make_u8path(p.src_dir)); + + size_t line_counter = 0, fn_counter = 0, br_counter = 0; + + for (auto& file_node : *files) { + auto file = json::cast(file_node); + if (!file) continue; + + auto json_file_name = json::cast(file, u8"name"); + auto json_file_digest = json::cast(file, u8"digest"); + auto json_file_lines = + json::cast(file, u8"line_coverage"); + + if (!json_file_name || !json_file_digest || !json_file_lines) + continue; + + auto [excludes, empties] = find_excl_blocks( + valid_markers, from_u8(*json_file_name), src_dir); + if (excludes.empty() && empties.empty()) continue; + + std::sort(excludes.begin(), excludes.end()); + + // LINES + // =========================================================== + for (auto const [start, stop] : excludes) { + for (auto line = start; line <= stop; ++line) { + if (erase_line(*json_file_lines, line, hard)) + ++line_counter; + } + } + + for (auto const empty : empties) { + if (erase_line(*json_file_lines, empty, soft)) ++line_counter; + } + + // FUNCTIONS + // =========================================================== + + if (auto json_array = json::cast(file, u8"functions"); + json_array) { + fn_counter += filter_blocks(json_array, excludes); + } + + // BRANCHES + // =========================================================== + + if (auto json_array = json::cast(file, u8"branches"); + json_array) { + br_counter += filter_blocks(json_array, excludes); + } + } + + // SUMMARY + // =========================================================== + if (line_counter || fn_counter || br_counter) { + bool first = true; + fmt::print(stderr, "strip-excludes: excluded "); + if (line_counter) { + first = false; + fmt::print(stderr, "{} {}", line_counter, + line_counter == 1 ? "line"sv : "lines"sv); + } + if (fn_counter) { + if (first) fmt::print(stderr, ", "); + first = false; + fmt::print(stderr, "{} {}", fn_counter, + fn_counter == 1 ? "function"sv : "functions"sv); + } + if (br_counter) { + if (first) fmt::print(stderr, ", "); + first = false; + fmt::print(stderr, "{} {}", br_counter, + br_counter == 1 ? "branch"sv : "branches"sv); + } + fmt::print(stderr, "\n"); + } + + json::write_json(stdout, root, json::concise); + return 0; + } +}; // namespace cov::app::strip + +int tool(args::args_view const& arguments) { + return cov::app::strip::tool(arguments); +} diff --git a/apps/report-schema.json b/apps/report-schema.json index 8e53d24c..c636e9a8 100644 --- a/apps/report-schema.json +++ b/apps/report-schema.json @@ -94,11 +94,11 @@ "patternProperties": { "^[1-9][0-9]*$": { "type": "integer", - "minimum": 1 + "minimum": 0 }, "^0[0-9]+$": { "type": "integer", - "minimum": 1 + "minimum": 0 }, "^0$": { "title": "line numbers should start from 1", diff --git a/apps/tests/main-set/008-report-A/067-report-help.json b/apps/tests/main-set/008-report-A/067-report-help.json index 0e92e139..08c7ce68 100644 --- a/apps/tests/main-set/008-report-A/067-report-help.json +++ b/apps/tests/main-set/008-report-A/067-report-help.json @@ -10,7 +10,7 @@ "", "optional arguments:", " -h, --help shows this help message and exits", - " -f, --filter filters other report formats to internal cov format; known filters are: ‘cobertura’ and ‘coveralls’", + " -f, --filter filters other report formats to internal cov format; known filters are: ‘cobertura’, ‘coveralls’ and ‘strip-excludes’", " -p, --prop = adds a property to this build report; if the is one of 'true', 'false', 'on' or 'off', it will treated as a boolean, if it looks like a whole number, it will be treated as a number, otherwise it will be treated as string; good names for properties could be 'os', 'arch', 'build_type' or 'compiler'", " --amend replaces the tip of the current branch by creating a new commit\n" ], diff --git a/docs/roadmap.md b/docs/roadmap.md index dc3b5d6e..92cba08e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -78,6 +78,7 @@ - [ ] Look into tortoise and a hare (mzdun/cov#62) - [ ] Major release - Update schema id and references in filters + - [ ] change `SHARE_DIR` to `share/cov-${PROJECT_VERSION_MAJOR}` - [ ] Freeze translation IDs (mzdun/cov#63) - [ ] `cov serve` - [ ] Boost.Beast WS diff --git a/libs/cov-rt/include/cov/app/report_command.hh b/libs/cov-rt/include/cov/app/report_command.hh index 566713ff..26cd9a69 100644 --- a/libs/cov-rt/include/cov/app/report_command.hh +++ b/libs/cov-rt/include/cov/app/report_command.hh @@ -32,7 +32,8 @@ namespace cov::app::builtin::report { }; parse_results parse(); - std::string report_contents(git::repository_handle repo) const; + std::string report_contents(git::repository_handle repo, + ::args::arglist args) const; std::string_view report_path() const noexcept { return report_; } std::string_view report_filter() const noexcept { @@ -90,6 +91,7 @@ namespace cov::app::builtin::report { // "private : std::vector" std::vector filter(std::vector const& contents, std::string_view filter, + ::args::arglist args, std::filesystem::path const& cwd) const; // visual space @@ -116,6 +118,7 @@ namespace cov::app::builtin::report { std::optional filter_{}; std::vector props_{}; bool amend_{}; + std::optional output_{}; }; struct stored_file { diff --git a/libs/cov-rt/include/cov/app/tools.hh b/libs/cov-rt/include/cov/app/tools.hh index 77a1f378..9852cb73 100644 --- a/libs/cov-rt/include/cov/app/tools.hh +++ b/libs/cov-rt/include/cov/app/tools.hh @@ -63,6 +63,7 @@ namespace cov::app { captured_output run_filter(std::filesystem::path const& filter_dir, std::filesystem::path const& cwd, std::string_view filter, + args::arglist args, std::vector const& input); } // namespace platform } // namespace cov::app diff --git a/libs/cov-rt/src/posix.cc b/libs/cov-rt/src/posix.cc index 96b8cc9a..8be17188 100644 --- a/libs/cov-rt/src/posix.cc +++ b/libs/cov-rt/src/posix.cc @@ -280,9 +280,10 @@ namespace cov::app::platform { captured_output run_filter(std::filesystem::path const& filter_dir, std::filesystem::path const& cwd, std::string_view filter, + args::arglist args, std::vector const& input) { return execute(filter_dir, "COV_FILTER_PATH", - std::string(filter.data(), filter.size()), {}, &input, + std::string(filter.data(), filter.size()), args, &input, &cwd, true); } } // namespace cov::app::platform diff --git a/libs/cov-rt/src/report_command.cc b/libs/cov-rt/src/report_command.cc index bad67815..de936e53 100644 --- a/libs/cov-rt/src/report_command.cc +++ b/libs/cov-rt/src/report_command.cc @@ -54,8 +54,8 @@ namespace cov::app::builtin::report { parser::parser(::args::args_view const& arguments, str::translator_open_info const& langs) : base_parser{langs, arguments} { - static constexpr std::string_view filters[] = {"cobertura"sv, - "coveralls"sv}; + static constexpr std::string_view filters[] = { + "cobertura"sv, "coveralls"sv, "strip-excludes"sv}; parser_.arg(report_) .meta(tr_(replng::REPORT_FILE_META)) @@ -70,16 +70,43 @@ namespace cov::app::builtin::report { parser_.set(amend_, "amend") .help(tr_(replng::AMEND_DESCRIPTION)) .opt(); + parser_.arg(output_, "o", "out").opt(); } parser::parse_results parser::parse() { using namespace str; - parser_.parse(); + auto rest = parser_.parse(::args::parser::allow_subcommands); + if (!rest.empty()) { + if (rest[0] != "--"sv) { + error(fmt::format(fmt::runtime(tr_(args::lng::UNRECOGNIZED)), + rest[0])); + } + rest = rest.shift(); + } parse_results result{open_here(*this, tr_)}; - if (!result.report.load_from_text(report_contents(result.repo.git()))) { + if (output_) { + if (!filter_) error("--out requires --filter"); + if (amend_) error("--out cannot be used with --amend"); + + auto const text = report_contents(result.repo.git(), rest); + if (*output_ == "-") { + fputs(text.c_str(), stdout); + } else { + auto filename = make_u8path(*output_); + std::error_code ec{}; + std::filesystem::create_directories(filename.parent_path(), ec); + if (ec) error(ec, tr_); + auto file = io::fopen(filename, "wb"); + if (file) file.store(text.data(), text.size()); + std::exit(0); + } + } + + if (!result.report.load_from_text( + report_contents(result.repo.git(), rest))) { if (filter_) { error(tr_.format(replng::ERROR_FILTERED_REPORT_ISSUES, report_, *filter_)); @@ -91,7 +118,8 @@ namespace cov::app::builtin::report { return result; } // GCOV_EXCL_LINE[GCC] -- and now it wants th throw something... - std::string parser::report_contents(git::repository_handle repo) const { + std::string parser::report_contents(git::repository_handle repo, + ::args::arglist args) const { auto source = io::fopen(make_u8path(report_)); if (!source) error(tr_.format(str::args::lng::FILE_NOT_FOUND, report_)); @@ -99,7 +127,7 @@ namespace cov::app::builtin::report { if (filter_) { auto dir = repo.workdir(); if (!dir) dir = repo.commondir(); - content = filter(content, *filter_, make_u8path(*dir)); + content = filter(content, *filter_, args, make_u8path(*dir)); } return {reinterpret_cast(content.data()), content.size()}; @@ -108,10 +136,11 @@ namespace cov::app::builtin::report { std::vector parser::filter( std::vector const& contents, std::string_view filter, + ::args::arglist args, std::filesystem::path const& cwd) const { auto output = platform::run_filter( platform::sys_root() / directory_info::share / "filters"sv, cwd, - filter, contents); + filter, args, contents); if (!output.error.empty()) fwrite(output.error.data(), 1, output.error.size(), stderr); diff --git a/libs/cov-rt/src/win32.cc b/libs/cov-rt/src/win32.cc index e4659c19..150bd5c4 100644 --- a/libs/cov-rt/src/win32.cc +++ b/libs/cov-rt/src/win32.cc @@ -522,8 +522,9 @@ namespace cov::app::platform { captured_output run_filter(std::filesystem::path const& filter_dir, std::filesystem::path const& cwd, std::string_view filter, + args::arglist args, std::vector const& input) { - return execute(filter_dir, L"COV_FILTER_PATH", from_utf8(filter), {}, + return execute(filter_dir, L"COV_FILTER_PATH", from_utf8(filter), args, &input, &cwd, true); } } // namespace cov::app::platform From 0f4d87176df80f31f63b55e088c7ce4b05e0527c Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Thu, 27 Jul 2023 07:35:06 +0200 Subject: [PATCH 02/39] test: take `report --out` into consideration --- apps/tests/main-set/008-report-A/066-report-no-args.json | 2 +- apps/tests/main-set/008-report-A/067-report-help.json | 5 +++-- apps/tests/main-set/008-report-A/068-report-no-cov.json | 2 +- .../main-set/008-report-A/072-report-not-the-json.json | 2 +- .../008-report-A/073-report-not-the-json-filtered.json | 2 +- .../main-set/009-report-B/077-report-amend-on-empty.json | 2 +- apps/tests/messages-pl/005-report/066-report-no-args.json | 2 +- apps/tests/messages-pl/005-report/067-report-help.json | 7 ++++--- apps/tests/messages-pl/005-report/068-report-no-cov.json | 2 +- .../messages-pl/005-report/072-report-not-the-json.json | 2 +- .../005-report/073-report-not-the-json-filtered.json | 2 +- .../messages-pl/005-report/077-report-amend-on-empty.json | 2 +- 12 files changed, 17 insertions(+), 15 deletions(-) diff --git a/apps/tests/main-set/008-report-A/066-report-no-args.json b/apps/tests/main-set/008-report-A/066-report-no-args.json index b081f041..948b301f 100644 --- a/apps/tests/main-set/008-report-A/066-report-no-args.json +++ b/apps/tests/main-set/008-report-A/066-report-no-args.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: error: argument is required\n" ] ] diff --git a/apps/tests/main-set/008-report-A/067-report-help.json b/apps/tests/main-set/008-report-A/067-report-help.json index 08c7ce68..25f0b3b2 100644 --- a/apps/tests/main-set/008-report-A/067-report-help.json +++ b/apps/tests/main-set/008-report-A/067-report-help.json @@ -3,7 +3,7 @@ "expected": [ 0, [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "", "positional arguments:", " selects report to import", @@ -12,7 +12,8 @@ " -h, --help shows this help message and exits", " -f, --filter filters other report formats to internal cov format; known filters are: ‘cobertura’, ‘coveralls’ and ‘strip-excludes’", " -p, --prop = adds a property to this build report; if the is one of 'true', 'false', 'on' or 'off', it will treated as a boolean, if it looks like a whole number, it will be treated as a number, otherwise it will be treated as string; good names for properties could be 'os', 'arch', 'build_type' or 'compiler'", - " --amend replaces the tip of the current branch by creating a new commit\n" + " --amend replaces the tip of the current branch by creating a new commit", + " -o, --out \n" ], "" ] diff --git a/apps/tests/main-set/008-report-A/068-report-no-cov.json b/apps/tests/main-set/008-report-A/068-report-no-cov.json index 5ffffa42..ac2f529d 100644 --- a/apps/tests/main-set/008-report-A/068-report-no-cov.json +++ b/apps/tests/main-set/008-report-A/068-report-no-cov.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: error: Cannot find a Cov repository in $TMP\n" ] ], diff --git a/apps/tests/main-set/008-report-A/072-report-not-the-json.json b/apps/tests/main-set/008-report-A/072-report-not-the-json.json index 2dcbc923..455b61fe 100644 --- a/apps/tests/main-set/008-report-A/072-report-not-the-json.json +++ b/apps/tests/main-set/008-report-A/072-report-not-the-json.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: error: there were issues with $DATA/no-git-coverage.json\n" ] ], diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index 6924bc87..e232f91f 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter" ] ], diff --git a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json index d4386457..7dbe9f67 100644 --- a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json +++ b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json @@ -8,7 +8,7 @@ "", [ "[ADD] src/main.cc", - "usage: cov report [-h] [-f ] [-p = ...] [--amend]", + "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: error: you have nothing to amend\n" ] ], diff --git a/apps/tests/messages-pl/005-report/066-report-no-args.json b/apps/tests/messages-pl/005-report/066-report-no-args.json index 566e8437..96f57d8f 100644 --- a/apps/tests/messages-pl/005-report/066-report-no-args.json +++ b/apps/tests/messages-pl/005-report/066-report-no-args.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: błąd: argument jest wymagany\n" ] ] diff --git a/apps/tests/messages-pl/005-report/067-report-help.json b/apps/tests/messages-pl/005-report/067-report-help.json index 95b63fb1..99c48a35 100644 --- a/apps/tests/messages-pl/005-report/067-report-help.json +++ b/apps/tests/messages-pl/005-report/067-report-help.json @@ -4,16 +4,17 @@ "expected": [ 0, [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "", "argumenty pozycyjne:", " wybiera raport do zaimportowania", "", "argumenty opcjonalne:", " -h, --help pokazuje ten komunikat pomocy i wychodzi", - " -f, --filter filtruje inne formaty raportów do wewnętrznego formatu cov; znane filtry to: ‘cobertura’ i ‘coveralls’", + " -f, --filter filtruje inne formaty raportów do wewnętrznego formatu cov; znane filtry to: ‘cobertura’, ‘coveralls’ i ‘strip-excludes’", " -p, --prop = dodaje właściwość do tego raportu z kompilacji; jeśli jest jedną z „true”, „false”, „on” or „off”, będzie traktowana jako wartość logiczna, jeśli wygląda jak liczba całkowita, będzie traktowana jako liczba, w przeciwnym razie będzie traktowana jako ciąg znaków; dobrymi nazwami właściwości mogą być „os”, „arch”, „build_type” lub „compiler”", - " --amend zastępuje końcówkę bieżącej gałęzi, tworząc nowy zapis\n" + " --amend zastępuje końcówkę bieżącej gałęzi, tworząc nowy zapis", + " -o, --out \n" ], "" ] diff --git a/apps/tests/messages-pl/005-report/068-report-no-cov.json b/apps/tests/messages-pl/005-report/068-report-no-cov.json index b3fc1240..53e80d29 100644 --- a/apps/tests/messages-pl/005-report/068-report-no-cov.json +++ b/apps/tests/messages-pl/005-report/068-report-no-cov.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: błąd: Nie można znaleźć repozytorium Cov w $TMP\n" ] ], diff --git a/apps/tests/messages-pl/005-report/072-report-not-the-json.json b/apps/tests/messages-pl/005-report/072-report-not-the-json.json index a1f52e2f..4f49e58d 100644 --- a/apps/tests/messages-pl/005-report/072-report-not-the-json.json +++ b/apps/tests/messages-pl/005-report/072-report-not-the-json.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json\n" ] ], diff --git a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json index 5f5161d7..2e539d99 100644 --- a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json +++ b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json przetworzonym przez filtr echo-to-stdout" ] ], diff --git a/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json b/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json index cd786bee..f804214f 100644 --- a/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json +++ b/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json @@ -9,7 +9,7 @@ "", [ "[ADD] src/main.cc", - "użycie: cov report [-h] [-f ] [-p = ...] [--amend]", + "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", "cov report: błąd: nie masz nic do poprawienia\n" ] ], From 042211bfbed0f127598e973896566b90338feebd Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Thu, 27 Jul 2023 07:34:35 +0200 Subject: [PATCH 03/39] feat(core): add `cov collect` --- .covcollect.in | 15 + .covmodules | 4 + .vscode/launch.json | 16 + .vscode/settings.json | 4 +- CMakeLists.txt | 20 +- apps/CMakeLists.txt | 23 + apps/builtins/builtin_show.cc | 3 +- apps/collect/gnu.cc | 246 ++++++++++ apps/collect/llvm.cc | 437 ++++++++++++++++++ apps/collect/main.cc | 214 +++++++++ apps/collect/msvc.cc | 207 +++++++++ apps/collect/queue.hh | 79 ++++ apps/collect/report.cc | 212 +++++++++ apps/collect/report.hh | 82 ++++ apps/collect/task_watcher.cc | 71 +++ apps/collect/task_watcher.hh | 45 ++ apps/collect/thread_pool.cc | 57 +++ apps/collect/thread_pool.hh | 24 + apps/collect/toolkit.cc | 143 ++++++ apps/collect/toolkit.hh | 86 ++++ apps/collect/walk.cc | 187 ++++++++ apps/collect/walk.hh | 30 ++ apps/filters/native/str.hh | 20 + .../filters/native/strip_excludes/excludes.cc | 14 +- apps/tests/test_driver.py | 5 +- cmake/builtins.cmake | 12 +- conanfile.txt | 1 + external/json | 2 +- flow.py | 5 +- libs/app/CMakeLists.txt | 12 +- libs/app/include/cov/app/run.hh | 48 ++ libs/{cov-rt => app}/src/path_env.hh | 0 libs/app/src/{posix.cc => posix/exec_path.cc} | 0 .../src/posix.cc => app/src/posix/run.cc} | 79 +++- libs/app/src/{win32.cc => win32/exec_path.cc} | 0 .../src/win32.cc => app/src/win32/run.cc} | 55 ++- libs/cov-api/include/cov/git2/repository.hh | 4 + libs/cov-api/include/cov/io/types.hh | 2 +- libs/cov-api/src/cov/format/facades.cc | 18 +- libs/cov-api/src/cov/io/function_coverage.cc | 3 - libs/cov-api/tests/cov/diff-test.cc | 10 +- libs/cov-api/tests/cov/format/facade-test.cc | 2 +- libs/cov-rt/CMakeLists.txt | 6 - libs/cov-rt/include/cov/app/tools.hh | 19 +- libs/cov-rt/src/cvg_info.cc | 4 +- libs/cov-rt/src/line_printer.cc | 4 +- libs/cov-rt/src/show.cc | 2 +- libs/cov-rt/tests/tools-test.cc | 1 + tools/flow/lib/matrix.py | 89 +++- tools/flow/lib/runner.py | 12 +- tools/flow/run.py | 5 +- 51 files changed, 2543 insertions(+), 96 deletions(-) create mode 100644 .covcollect.in create mode 100644 apps/collect/gnu.cc create mode 100644 apps/collect/llvm.cc create mode 100644 apps/collect/main.cc create mode 100644 apps/collect/msvc.cc create mode 100644 apps/collect/queue.hh create mode 100644 apps/collect/report.cc create mode 100644 apps/collect/report.hh create mode 100644 apps/collect/task_watcher.cc create mode 100644 apps/collect/task_watcher.hh create mode 100644 apps/collect/thread_pool.cc create mode 100644 apps/collect/thread_pool.hh create mode 100644 apps/collect/toolkit.cc create mode 100644 apps/collect/toolkit.hh create mode 100644 apps/collect/walk.cc create mode 100644 apps/collect/walk.hh create mode 100644 libs/app/include/cov/app/run.hh rename libs/{cov-rt => app}/src/path_env.hh (100%) rename libs/app/src/{posix.cc => posix/exec_path.cc} (100%) rename libs/{cov-rt/src/posix.cc => app/src/posix/run.cc} (75%) rename libs/app/src/{win32.cc => win32/exec_path.cc} (100%) rename libs/{cov-rt/src/win32.cc => app/src/win32/run.cc} (90%) diff --git a/.covcollect.in b/.covcollect.in new file mode 100644 index 00000000..344a90d6 --- /dev/null +++ b/.covcollect.in @@ -0,0 +1,15 @@ +[collect] + compiler = @CMAKE_CXX_COMPILER@ + output = collected.json + bin-dir = . + src-dir = ../.. + include = @SRC_INCLUDE@ + exclude = @SRC_EXCLUDE@ + +[clang] + exec = bin/cov + exec = bin/cov-* + exec = libexec/cov/cov-* + exec = share/cov-*/**/filters/* + raw = .profraw + profdata = llvm-profiler diff --git a/.covmodules b/.covmodules index d1fb65c1..f4a5986f 100644 --- a/.covmodules +++ b/.covmodules @@ -11,6 +11,10 @@ [module "app/main"] path = apps/cov/ path = apps/builtins/ +[module "app/ext"] + path = apps/collect +[module "app/filters"] + path = apps/filters [module "hilite/lighter"] path = libs/hilite/hilite path = libs/hilite/lighter diff --git a/.vscode/launch.json b/.vscode/launch.json index 2ca1e8fc..3be4f482 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,6 +10,22 @@ "args": [ "--gtest_filter=*" ] + }, + { + "type": "cppdbg", + "request": "launch", + "name": "Launch cov collect (gdb)", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/build/debug/libexec/cov/cov-collect", + "args": [] + }, + { + "type": "cppvsdbg", + "request": "launch", + "name": "Launch cov collect (vs)", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/build/debug/libexec/cov/cov-collect", + "args": [] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index d7e68769..147dd65e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "cfglng", "cobertura", "covdata", + "covcollect", "covlng", "covmodules", "demangled", @@ -127,6 +128,7 @@ "cfloat": "cpp", "climits": "cpp", "queue": "cpp", - "source_location": "cpp" + "source_location": "cpp", + "condition_variable": "cpp" } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 1297ac52..cda0befa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND CMAKE_PREFIX_PATH "${PROJECT_BINARY_DIR}/conan") set(CONAN_CMAKE_SILENT_OUTPUT ON) find_package(Python3 COMPONENTS Interpreter REQUIRED) +find_package(ctre REQUIRED) find_package(libgit2 REQUIRED) find_package(fmt REQUIRED) find_package(mbits-args REQUIRED) @@ -55,11 +56,8 @@ if (COV_TESTING) find_package(GTest REQUIRED) set(COVERALLS_PREFIX cov_) - set(cov_COVERALLS_DIRS - apps/builtins - apps/cov - ) + set(INCLUDED_IN_COVERAGE apps) foreach(module libs/cov-api libs/cell @@ -68,11 +66,16 @@ if (COV_TESTING) libs/app libs/cov-rt ) - list(APPEND cov_COVERALLS_DIRS ${module}/include ${module}/src) + list(APPEND INCLUDED_IN_COVERAGE ${module}/include ${module}/src) endforeach() + foreach(extra cxx py3 ts) - list(APPEND cov_COVERALLS_DIRS libs/hilite/hilite-${extra}/src) + list(APPEND INCLUDED_IN_COVERAGE libs/hilite/hilite-${extra}/src) endforeach() + + set(EXCLUDED_FROM_COVERAGE apps/tests) + + set(cov_COVERALLS_DIRS ${INCLUDED_IN_COVERAGE}) include(${PROJECT_SOURCE_DIR}/tools/coveralls/Coveralls.cmake) set(TEST_REPORT_DIR "${PROJECT_BINARY_DIR}/test-results") @@ -216,6 +219,8 @@ if (MSVC_VERSION GREATER_EQUAL 1936 AND MSVC_IDE) lighter-stress-test date-tz json + strip-excludes + cov-collect ) if(TARGET ${TGT}) set_target_properties(${TGT} PROPERTIES VS_USER_PROPS "${PROJECT_SOURCE_DIR}/cmake/VS17.NoModules.props") @@ -252,3 +257,6 @@ else() endif() file(GENERATE OUTPUT "${PROJECT_BINARY_DIR}/report_answers.txt" CONTENT "${COV_PROPERTIES}\n") +string(REPLACE ";" "\n include = " SRC_INCLUDE "${INCLUDED_IN_COVERAGE}") +string(REPLACE ";" "\n exclude = " SRC_EXCLUDE "${EXCLUDED_FROM_COVERAGE}") +configure_file("${PROJECT_SOURCE_DIR}/.covcollect.in" "${PROJECT_BINARY_DIR}/.covcollect" @ONLY) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 22c9f728..ed684d6a 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -139,6 +139,29 @@ target_sources(strip-excludes PRIVATE # add_cov_ext(serve) +add_cov_ext(collect) +target_include_directories(cov-collect PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/collect + ${CMAKE_CURRENT_SOURCE_DIR}/filters +) +target_link_libraries(cov-collect PRIVATE ctre::ctre) +target_sources(cov-collect PRIVATE + collect/gnu.cc + collect/llvm.cc + collect/msvc.cc + collect/queue.hh + collect/report.cc + collect/report.hh + collect/toolkit.cc + collect/toolkit.hh + collect/task_watcher.cc + collect/task_watcher.hh + collect/thread_pool.cc + collect/thread_pool.hh + collect/walk.cc + collect/walk.hh +) + print_cov_ext() ######################################################## diff --git a/apps/builtins/builtin_show.cc b/apps/builtins/builtin_show.cc index bc82c75e..d6642794 100644 --- a/apps/builtins/builtin_show.cc +++ b/apps/builtins/builtin_show.cc @@ -103,7 +103,6 @@ namespace cov::app::builtin::show { ref_ptr get_files(git::oid_view id, cov::repository const& repo) { - git::oid ref{}; std::error_code ec{}; auto generic = repo.lookup(id, ec); if (!generic || ec) return {}; @@ -167,7 +166,7 @@ namespace cov::app::builtin::show { view.fname.prefix.empty(); auto const print_build_props = [&repo = info.repo, &range = info.range, - &ec = ec, &p = p]() { + &p = p]() { using namespace std::chrono; auto const now = floor(system_clock::now()); diff --git a/apps/collect/gnu.cc b/apps/collect/gnu.cc new file mode 100644 index 00000000..2636f847 --- /dev/null +++ b/apps/collect/gnu.cc @@ -0,0 +1,246 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +// Alpine: g++ (GCC) 13.1.1 20230429 +// Jammy: g++ (Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0 +// MINGW-w64: g++.exe (Rev7, Built by MSYS2 project) 13.1.0 +#define GXX "g\\+\\+" +#define WORD "[a-zA-Z0-9_]" +#define COMMENT R"(\([^)]+\))" +#define VERSION "[0-9.]+" +static constexpr auto GNU = + ctre::match<"^(?:" GXX "(?:.exe)?|" WORD "+-" WORD "+-" WORD "+-" GXX + "(?:-" VERSION ")?) " COMMENT " (" VERSION ")(?: [0-9]+)?$">; + +static constexpr auto TRIPLET = ctre::match< + // the triplet + "^(" WORD "+-" WORD "+-" WORD "+-)" GXX "(?:-" VERSION ")? \\(.*$">; + +namespace cov::app::collect { + static unsigned u(long long val) { + static constexpr long long max_uint = + std::numeric_limits::max(); + return std::max(0u, static_cast(std::min(max_uint, val))); + } + + struct gnu_toolkit : toolkit { + gnu_toolkit(std::filesystem::path const& compiler, + std::string&& ver, + std::string&& triplet) + : ver_{std::move(ver)} + , triplet_{std::move(triplet)} + , compiler_{compiler} {} + std::string_view label() const noexcept override { return "GNU"sv; } + std::string_view version() const noexcept override { return ver_; } + + void hello(config const&) const override { + fmt::print(" [gcov] {}\n", get_u8path(gcov_)); + } + + void clean(config const& cfg) const override { + remove_all(cfg.bin_dir / "**/*.gcda"); + } + + int observe(config const&, + std::string_view command, + args::arglist arguments) const { + return platform::call(make_u8path(command), arguments); + } + + int report(config const& cfg, coverage& cvg) override { + using namespace std::filesystem; + std::unordered_map> paths; + walk(cfg.bin_dir / "**/*.gcno", + [&](std::filesystem::path const& path) { + paths[path.parent_path()].insert(path.filename()); + }); + + closure state{.cfg = cfg, .cvg = cvg}; + + for (auto const& [dirname, filenames] : paths) { + state.push([&, this]() { + std::vector nodes; + + if (state.set_return_code( + load_directory(dirname, filenames, nodes))) + return; + + for (auto& node : nodes) { + state.push([this, &state, node = std::move(node)] { + auto const ret = + analyze_node(state.cfg, state.cvg, node); + state.task_finished(); + if (!ret) state.set_return_code(1); + }); + } + state.task_finished(); + }); + } + + return state.wait(); + } + + bool find_tools() { + auto const hint = compiler_.parent_path(); + auto const ver = split(ver_, '.'); + return find_tool(gcov_, hint, fmt::format("{}gcov", triplet_), ver); + } + + private: + int load_directory( + std::filesystem::path const& dirname, + std::unordered_set const& filenames, + std::vector& nodes); + + bool analyze_node(config const& cfg, + coverage& cvg, + json::node const& root); + + std::string ver_; + std::string triplet_; + std::filesystem::path compiler_; + std::filesystem::path gcov_; + }; + + std::unique_ptr gnu(config const& cfg, + std::span lines) { + if (auto matched = GNU(lines[0]); matched) { + auto triplet_matched = TRIPLET(lines[0]); + auto triplet = triplet_matched + ? triplet_matched.get<1>().to_string() + : std::string{}; + auto tk = std::make_unique( + cfg.compiler, matched.get<1>().to_string(), std::move(triplet)); + if (!tk->find_tools()) tk.reset(); + return tk; + } + return {}; + } + + int gnu_toolkit::load_directory( + std::filesystem::path const& dirname, + std::unordered_set const& filenames, + std::vector& nodes) { + std::vector args{"--branch-probabilities"s, "--branch-counts"s, + "--json-format"s, "--stdout"s, + "--object-directory"s, get_u8path(dirname)}; + args.reserve(args.size() + filenames.size()); + for (auto const& gcno : filenames) + args.push_back(get_u8path(dirname / gcno)); + + auto proc = platform::run(get_u8path(gcov_), arguments{args}); + if (proc.return_code) { + std::fwrite(proc.error.data(), 1, proc.error.size(), stderr); + return proc.return_code; + } + + auto view = json::string_view{ + reinterpret_cast(proc.output.data()), + proc.output.size()}; + while (!view.empty()) { + size_t read{}; + auto root = + json::read_json(view, {}, json::read_mode::serialized, &read); + if (!read || std::holds_alternative(root)) break; + view = view.substr(read); + + nodes.push_back(std::move(root)); + } + + return 0; + } + + bool gnu_toolkit::analyze_node(config const& cfg, + coverage& cvg, + json::node const& json_root) { + auto root = cast(json_root, u8"files"); + if (!root) return false; + for (auto const& json_file : *root) { + auto json_name = cast(json_file, u8"file"); + auto json_lines = cast(json_file, u8"lines"); + auto json_functions = cast(json_file, u8"functions"); + + if (!json_name || !json_lines) continue; + auto filename = std::filesystem::path{*json_name}; + if (!filename.is_absolute()) filename = cfg.bin_dir / filename; + + auto sink = cvg.get_file_mt(get_u8path(filename)); + if (!sink) { + filename = std::filesystem::weakly_canonical(filename); + sink = cvg.get_file_mt(get_u8path(filename)); + if (!sink) { + continue; + } + } + + for (auto const& json_line : *json_lines) { + auto json_line_number = + cast(json_line, u8"line_number"); + auto json_count = cast(json_line, u8"count"); + + if (!json_line_number || !json_count) continue; + sink->on_visited(u(*json_line_number), u(*json_count)); + } + + if (json_functions) { + for (auto const& json_function : *json_functions) { + auto json_start_line = + cast(json_function, u8"start_line"); + auto json_end_line = + cast(json_function, u8"end_line"); + auto json_start_column = + cast(json_function, u8"start_column"); + auto json_end_column = + cast(json_function, u8"end_column"); + auto json_execution_count = + cast(json_function, u8"execution_count"); + auto json_fn_name = + cast(json_function, u8"name"); + auto json_demangled_name = + cast(json_function, u8"demangled_name"); + + if (!json_start_line || !json_execution_count || + !(json_fn_name && json_demangled_name)) + continue; + + text_pos start{ + .line = u(*json_start_line), + .col = u(json_start_column ? *json_start_column : 0)}; + text_pos stop{ + .line = u(json_end_line ? *json_end_line + : *json_start_line), + .col = u(json_end_column ? *json_end_column : 0)}; + unsigned count = u(*json_execution_count); + std::string name = from_u8s( + *(json_fn_name ? json_fn_name : json_demangled_name)); + std::string demangled; + if (json_fn_name && json_demangled_name) + demangled = from_u8s(*json_demangled_name); + + sink->on_function(start, stop, count, name, demangled); + } + } + + cvg.handover_mt(std::move(sink)); + } + return true; + } +} // namespace cov::app::collect diff --git a/apps/collect/llvm.cc b/apps/collect/llvm.cc new file mode 100644 index 00000000..edfb47ff --- /dev/null +++ b/apps/collect/llvm.cc @@ -0,0 +1,437 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std::literals; + +// Ubuntu clang version () +// clang version -- on windows +static constexpr auto CLANG = + ctre::match; + +#ifdef _WIN32 +int setenv(const char* name, const char* value, int) { + return _putenv_s(name, value); +} +#endif + +namespace cov::app::collect { + struct execution { + unsigned line; + std::optional count; + }; + + static unsigned u(long long val) { + static constexpr long long max_uint = + std::numeric_limits::max(); + return std::max(0u, static_cast(std::min(max_uint, val))); + } + + struct region_ref { + text_pos start; + text_pos end; + + static std::optional encompassing_function( + json::array const& regions) { + std::optional result{std::nullopt}; + + for (auto const& json_region : regions) { + auto region = cast(json_region); + if (!region || region->size() < 8) return std::nullopt; + auto start_line = cast((*region)[0]); + auto start_col = cast((*region)[1]); + auto end_line = cast((*region)[2]); + auto end_col = cast((*region)[3]); + auto file_id = cast((*region)[5]); + auto type = cast((*region)[7]); + + if (!start_line || !start_col || !end_line || !end_col || + !type || !file_id) + return std::nullopt; + if (*type || *file_id) continue; + + text_pos start{.line = u(*start_line), .col = u(*start_col)}; + text_pos end{.line = u(*end_line), .col = u(*end_col)}; + + if (!result) { + result = region_ref{.start = start, .end = end}; + continue; + } + + if (result->start > start) result->start = start; + if (result->end < end) result->end = end; + } + + return result; + } + }; + + struct cvg_segment { + text_pos pos; + unsigned count; + bool has_count; + bool is_entry; + bool is_gap; + + bool is_start_of_region() const { + return !is_gap && has_count && is_entry; + } + + static std::optional from(json::array const& arr) { + // [24, 37, 21, true, true, false] + if (arr.size() < 6) return std::nullopt; + auto line = cast(arr[0]); + auto column = cast(arr[1]); + auto count = cast(arr[2]); + auto has_count = cast(arr[3]); + auto is_entry = cast(arr[4]); + auto is_gap = cast(arr[5]); + + if (!line || !column || !count || !has_count || !is_entry || + !is_gap) + return std::nullopt; + + return cvg_segment{.pos = {.line = u(*line), .col = u(*column)}, + .count = u(*count), + .has_count = *has_count, + .is_entry = *is_entry, + .is_gap = *is_gap}; + } + + static execution make_stats( + std::span const& line_segments, + cvg_segment const* wrapped_segment, + unsigned line) { + execution result{line, std::nullopt}; + + unsigned min_region_count = 0; + for (auto const& segment : line_segments) { + if (min_region_count > 1) break; + if (segment->is_start_of_region()) ++min_region_count; + } + + auto const start_of_skipped_region = + (!line_segments.empty() && line_segments[0]->has_count && + line_segments[0]->is_entry); + + auto mapped = !start_of_skipped_region && + ((wrapped_segment && wrapped_segment->has_count) or + (min_region_count > 0)); + if (!mapped) return result; + + if (wrapped_segment) result.count = wrapped_segment->count; + + for (auto const& segment : line_segments) { + if (segment->is_start_of_region()) + result.count = std::max(*result.count, segment->count); + } + + return result; + } + + static void run_coverage(std::span const& coverage, + coverage_file& sink) { + cvg_segment const* wrapped = nullptr; + auto line = coverage.empty() ? 0u : coverage[0].pos.line; + + std::vector segments{}; + segments.reserve(coverage.size()); + + auto const end_index = coverage.size(); + decltype(coverage.size()) index = 0; + + while (index < end_index) { + if (!segments.empty()) wrapped = segments.back(); + segments.clear(); + + while (index < end_index && coverage[index].pos.line == line) { + segments.push_back(&coverage[index]); + ++index; + } + + auto const mark = make_stats(segments, wrapped, line); + ++line; + + if (mark.count) sink.on_visited(mark.line, *mark.count); + } + } + }; + + struct llvm_toolkit : toolkit { + llvm_toolkit(std::filesystem::path const& compiler, std::string&& ver) + : ver_{std::move(ver)}, compiler_{compiler} {} + + bool load_config(config const& settings); + bool find_tools() { + auto const hint = compiler_.parent_path(); + auto const ver = split(ver_, '.'); + return find_tool(merger_, hint, "llvm-profdata"sv, ver) && + find_tool(exporter_, hint, "llvm-cov"sv, ver); + } + + std::string_view label() const noexcept override { return "LLVM"sv; } + std::string_view version() const noexcept override { return ver_; } + + void hello(config const&) const override { + fmt::print(" [merge] {}\n", get_u8path(merger_)); + fmt::print(" [cov] {}\n", get_u8path(exporter_)); + if (!raw_ext_.empty()) fmt::print(" [raw] {}\n", raw_ext_); + if (!prof_data_dir_.empty()) + fmt::print(" [data] {}\n", get_u8path(prof_data_dir_)); + if (!exec_.empty()) { + fmt::print(" [exe]\n"); + for (auto const& exe : exec_) { + fmt::print(" - {}\n", get_u8path(exe)); + } + } + } + + auto merged() const { return prof_data_dir_ / "merged.db"sv; } + + void clean(config const& cfg) const override { + std::error_code ec{}; + remove_all(cfg.bin_dir / ("**/*" + raw_ext_)); + std::filesystem::remove_all(cfg.bin_dir / prof_data_dir_, ec); + if (ec) return; + std::filesystem::create_directories(cfg.bin_dir / prof_data_dir_, + ec); + } + + int observe(config const& cfg, + std::string_view command, + args::arglist arguments) const { + auto const file_mask = get_u8path(cfg.bin_dir / prof_data_dir_ / + "raw"sv / ("%p" + raw_ext_)); + setenv("LLVM_PROFILE_FILE", file_mask.c_str(), 1); + return platform::call(make_u8path(command), arguments); + } + + bool needs_preprocess() const override { return true; } + int preprocess(config const& cfg) override; + int report(config const& cfg, coverage& cvg) override { + closure state{.cfg = cfg, .cvg = cvg, .pool{}}; + + for (auto const& exe : exec_) { + state.push([&, exe] { + state.set_return_code( + report_exe(state.cfg, state.cvg, exe)); + state.task_finished(); + }); + } + + return state.wait(); + } + + int report_exe(config const& cfg, + coverage& cvg, + std::filesystem::path const& exe); + + private: + std::string ver_; + std::filesystem::path compiler_; + std::filesystem::path merger_; + std::filesystem::path exporter_; + std::vector exec_; + std::filesystem::path prof_data_dir_; + std::string raw_ext_; + }; + + std::unique_ptr llvm(config const& cfg, + std::span lines) { + if (auto matched = CLANG(lines[0]); matched) { + auto tk = std::make_unique( + cfg.compiler, matched.get<1>().to_string()); + if (!tk->load_config(cfg) || !tk->find_tools()) tk.reset(); + return tk; + } + return {}; + } + + bool llvm_toolkit::load_config(config const& settings) { + std::set patterns; + std::set execs; + + auto cfg = git::config::create(); + cfg.add_file_ondisk(settings.cfg_dir / ".covcollect"sv); + cfg.foreach_entry( + [this, &patterns](git_config_entry const* entry) -> int { + auto name = std::string_view{entry->name}; + static constexpr auto prefix = "clang."sv; +#ifdef _WIN32 + auto const ext = ".exe"s; +#endif + + if (!name.starts_with(prefix)) return 0; + auto key = name.substr(prefix.length()); + + if (key == "profdata"sv) { + prof_data_dir_ = make_u8path(entry->value); + } else if (key == "exec"sv) { +#ifdef _WIN32 + patterns.insert(make_u8path(entry->value + ext)); +#else + patterns.insert(make_u8path(entry->value)); +#endif + } else if (key == "raw"sv) { + raw_ext_ = entry->value; + } + return 0; + }); + + prof_data_dir_ = std::filesystem::weakly_canonical( + prof_data_dir_.empty() ? settings.bin_dir / "llvm"sv + : settings.bin_dir / prof_data_dir_); + for (auto& pattern : patterns) { + auto const path = + std::filesystem::weakly_canonical(settings.bin_dir / pattern); + walk(path, [&execs](auto const& found) { + auto f = io::fopen(found, "rb"); + if (f) { + char hash_bang[2]; + if (f.load(hash_bang, 2) == 2) { + if (hash_bang[0] == '#' && hash_bang[1] == '!') { + // it's a script! + return; + } + } + } + execs.insert(found); + }); + } + + exec_.clear(); + exec_.insert(exec_.begin(), execs.begin(), execs.end()); + + return true; + } + + int llvm_toolkit::preprocess(config const& cfg) { + std::error_code ec{}; + using namespace std::filesystem; + + auto const db = merged(); + create_directories(prof_data_dir_, ec); + if (ec) return 1; + remove(db, ec); + if (ec) { + std::cerr << "error: " << ec.message() << '\n'; + return 1; + } + + std::vector stg{"merge"s, "-sparse"s}; + + walk(cfg.bin_dir / ("**/*" + raw_ext_), + [&stg](auto const& path) { stg.push_back(get_u8path(path)); }); + + stg.reserve(stg.size() + 2); + stg.push_back("-o"s); + stg.push_back(get_u8path(db)); + + return platform::call(merger_, arguments{stg}); + } + + int llvm_toolkit::report_exe(config const&, + coverage& cvg, + std::filesystem::path const& exe) { + std::array args{"export"s, "-format"s, + "text"s, "-skip-expansions"s, + "-instr-profile"s, get_u8path(merged()), + get_u8path(exe)}; + auto proc = platform::run(get_u8path(exporter_), arguments{args}); + if (proc.return_code) { + std::fwrite(proc.error.data(), 1, proc.error.size(), stderr); + return proc.return_code; + } + + auto root = json::read_json( + {reinterpret_cast(proc.output.data()), + proc.output.size()}); + + auto root_map = cast(root); + if (!root_map) return 1; + + { + auto root_version = cast(root_map, u8"version"); + auto version = split(from_u8(*root_version), '.'); + if (version.empty() || version[0] != "2"sv) return 1; + } + + if (auto root_data = cast(root_map, u8"data"); root_data) { + for (auto const& json_data : *root_data) { + auto files = cast(json_data, u8"files"); + auto functions = cast(json_data, u8"functions"); + if (files) { + for (auto const& json_file : *files) { + auto filename = + cast(json_file, u8"filename"); + auto segments = + cast(json_file, u8"segments"); + auto branches = + cast(json_file, u8"branches"); + + if (!filename || (!segments && !branches)) continue; + + auto sink = cvg.get_file(from_u8(*filename)); + if (!sink) continue; + + if (segments) { + std::vector data{}; + data.reserve(segments->size()); + for (auto const& json_segment : *segments) { + auto segment = cast(json_segment); + if (!segment) return 1; + auto cvg_seg = cvg_segment::from(*segment); + if (!cvg_seg) return 1; + data.push_back(*cvg_seg); + } + + cvg_segment::run_coverage(data, *sink); + } + } + } + if (functions) { + for (auto const& json_function : *functions) { + auto filenames = + cast(json_function, u8"filenames"); + auto regions = + cast(json_function, u8"regions"); + auto name = cast(json_function, u8"name"); + auto count = cast(json_function, u8"count"); + + if (!filenames || filenames->empty() || !regions || + regions->empty() || !name || !count) + continue; + + auto region = + region_ref::encompassing_function(*regions); + if (!region) continue; + + auto filename = cast((*filenames)[0]); + auto sink = cvg.get_file(from_u8(*filename)); + if (sink) + sink->on_function(region->start, region->end, + u(*count), get_u8path(*name), {}); + } + } + } + } + return 0; + } + +} // namespace cov::app::collect diff --git a/apps/collect/main.cc b/apps/collect/main.cc new file mode 100644 index 00000000..7ff39c65 --- /dev/null +++ b/apps/collect/main.cc @@ -0,0 +1,214 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; +using namespace cov::app; +using namespace cov; + +git::repository open_here() { + std::error_code ec{}; + auto const common = git::repository::discover("."sv, ec); + if (ec) return {}; + auto repo = git::repository::open(common, ec); + if (ec) return {}; + return repo; +} + +bool repo_head(git::repository const& repo, + json::string& branch, + git::oid& ref) { + std::error_code ec{}; + auto head = repo.head(ec); + if (ec == git::errc::unbornbranch || ec == git::errc::notfound) { + fmt::print(stderr, "[git] called on unborn branch\n"); + return false; + } + + auto branch_name = head.shorthand(); + if (branch_name) branch = to_u8(branch_name); + + auto resolved = head.resolve(ec); + if (!ec) { + auto oid = git_reference_target(resolved.raw()); + if (oid) { + ref.assign(*oid); + return true; + } + } + fmt::print(stderr, "[git] cannot resolve HEAD to a commit\n"); + return false; +} + +enum class command { clean, observe, collect }; + +template +using cmd_val = std::integral_constant; + +struct params { + std::optional config{std::nullopt}; + command cmd{command::collect}; + args::args_view observed; +}; + +params parse_arguments(args::args_view const& arguments) { + params result{}; + + args::null_translator tr{}; + args::parser p{{}, arguments, &tr}; + p.arg(result.config, "c", "config").opt(); + p.set>(result.cmd, "clean").opt(); + p.set>(result.cmd, "observe").opt(); + + auto rest = p.parse(args::parser::allow_subcommands); + if (!rest.empty() && result.cmd != command::observe) { + p.error(tr(args::lng::unrecognized, rest[0], {})); + } + + if (!rest.empty()) { + result.observed.progname = rest[0]; + result.observed.args = rest.shift(); + } else if (result.cmd == command::observe) { + p.error("argument --observe: missing tool name and arguments"); + } + + return result; +} + +std::filesystem::path workdir(git::repository const& repo) { + auto const dir_view = repo.workdir(); + if (!dir_view) return std::filesystem::current_path(); + return make_u8path(*dir_view); +} + +void find_config(git::repository const& repo, + std::optional& config) { + auto root = workdir(repo); + + for (auto const& dirname : {"build/debug"sv, "build"sv, "debug"sv, ""sv}) { + auto path = root / dirname / ".covcollect"sv; + if (std::filesystem::is_regular_file(path)) { + config = get_u8path(path); + return; + } + } +} + +template Callback> +int measure(std::string_view label, Callback&& cb) { + using namespace std::chrono; + + fmt::print(stderr, "[{}] start...\n", label); + + auto const then = steady_clock::now(); + auto const ret = cb(); + auto const now = steady_clock::now(); + auto const ms = duration_cast(now - then); + auto const cent_s = (ms.count() + 5) / 10; + fmt::print(stderr, "[{}] {}.{:02} s\n", label, cent_s / 100, cent_s % 100); + + return ret; +} + +int tool(args::args_view const& arguments) { + git::init memory{}; + + auto repo = open_here(); + if (!repo) return 1; + json::string branch{}; + git::oid ref{}; + if (!repo_head(repo, branch, ref)) return 1; + + auto params = parse_arguments(arguments); + + if (!params.config) { + find_config(repo, params.config); + if (!params.config) return 1; + } + + collect::config cfg{}; + cfg.load(*params.config); + + auto const toolkit = collect::recognize_toolkit(cfg); + if (!toolkit) return 1; + + if (params.cmd == command::clean) { + toolkit->clean(cfg); + return 0; + } + + if (params.cmd == command::observe) { + return toolkit->observe(cfg, params.observed.progname, + params.observed.args); + } + + fmt::print(stderr, "[toolkit] {} {} (from {})\n", toolkit->label(), + toolkit->version(), get_u8path(*params.config)); + collect::report cvg{cfg}; + + if (toolkit->needs_preprocess()) { + auto const ret = + measure("preprocess"sv, [&] { return toolkit->preprocess(cfg); }); + if (ret) return ret; + } + + auto ret = measure("report"sv, [&] { return toolkit->report(cfg, cvg); }); + if (ret) return ret; + + cvg.post_process(); + auto const summary = cvg.summary(); + + fmt::print(stderr, "[files] {}\n", summary.lines_total); + fmt::print(stderr, "[lines] {} / {}\n", summary.lines.visited, + summary.lines.relevant); + fmt::print(stderr, "[functions] {} / {}\n", summary.functions.visited, + summary.functions.relevant); + + { + struct output : json::output { + output(std::filesystem::path path) : file{io::fopen(path, "w")} {} + void write(json::string_view view) override { + file.store(view.data(), view.size()); + } + void write(byte_type ch) override { file.store(&ch, 1); } + io::file file; + }; + + auto outname = cfg.bin_dir / cfg.output; + + { + std::error_code ignore; + std::filesystem::create_directories(outname.parent_path(), ignore); + } + + output results{outname}; + if (!results.file) { + fmt::print(stderr, "[i/o] cannot open {}\n", get_u8path(outname)); + return 1; + } + auto node = cvg.get_json(branch, ref); + json::write_json(results, node); + fmt::print(stderr, "[i/o] {}\n", get_u8path(outname)); + } + return 0; +} diff --git a/apps/collect/msvc.cc b/apps/collect/msvc.cc new file mode 100644 index 00000000..51abaa20 --- /dev/null +++ b/apps/collect/msvc.cc @@ -0,0 +1,207 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace cov::app::collect { + static unsigned u(long long val) { + static constexpr long long max_uint = + std::numeric_limits::max(); + return std::max(0u, static_cast(std::min(max_uint, val))); + } + + std::string dos_path(std::filesystem::path const& path) { + auto copy = path; + copy.make_preferred(); + return get_u8path(copy); + } + + std::string dos_path(std::filesystem::path&& path) { + path.make_preferred(); + return get_u8path(path); + } + + struct msvc_toolkit : toolkit { + msvc_toolkit(std::filesystem::path const& compiler) + : compiler_{compiler} {} + + bool load_config(config const& settings); + bool get_version(config const& cfg); + bool find_tools() { + auto const hint = compiler_.parent_path(); + auto const ver = split(ver_, '.'); + if (!find_tool(occ_, LR"(C:/Program Files/OpenCppCoverage)"sv, + "OpenCppCoverage"sv, {})) + return false; + occ_.make_preferred(); + return true; + } + + std::string_view label() const noexcept override { return "MSVC"sv; } + std::string_view version() const noexcept override { return ver_; } + + void hello(config const&) const override { + fmt::print(" [occ] {}\n", get_u8path(occ_)); + fmt::print(" [outfile] {}\n", + get_u8path("" / occ_dir_ / occ_output_)); + } + + void clean(config const&) const override {} + + int observe(config const& cfg, + std::string_view command, + ::args::arglist args) const override { + if (occ_.empty()) { + return platform::call(make_u8path(command), args); + } + + /* + OpenCppCoverage + -q + --working_dir + --export_type :\\\\.xml + --source + --cover_children + -- + ...*/ + std::vector occ_args{ + "-q"s, + "--working_dir"s, + dos_path(cfg.src_dir), + "--export_type"s, + fmt::format("{}:{}", occ_filter_, + dos_path(cfg.bin_dir / occ_dir_ / occ_output_)), + }; + // +2 for "--cover_children --"; +1 for command + occ_args.reserve(occ_args.size() + 2 * cfg.include.size() + 2 + 1 + + args.size()); + + for (auto const& include : cfg.include) { + std::error_code ec{}; + auto src = std::filesystem::absolute(cfg.src_dir / include, ec); + if (ec) continue; + occ_args.push_back("--source"s); + occ_args.push_back(dos_path(std::move(src))); + } + occ_args.push_back("--cover_children"s); + occ_args.push_back("--"s); + + std::filesystem::path cmd{}; + if (!find_tool(cmd, {}, command, {})) { + cmd = make_u8path(command); + } + cmd.make_preferred(); + occ_args.push_back(get_u8path(cmd)); + for (auto index = 0u; index < args.size(); ++index) { + auto arg = args[index]; + occ_args.push_back({arg.data(), arg.size()}); + } + + return platform::call(occ_, arguments{occ_args}); + } + + int report(config const&, coverage&) override { return 0; } + + private: + std::string ver_; + std::filesystem::path compiler_; + std::filesystem::path occ_; + std::filesystem::path occ_dir_{"OpenCppCoverage"sv}; + std::string occ_filter_{"cobertura"sv}; + std::filesystem::path occ_output_{"cobertura.xml"sv}; + }; + + std::unique_ptr msvc(config const& cfg) { + auto tk = std::make_unique(cfg.compiler); + if (!tk->load_config(cfg) || !tk->get_version(cfg) || !tk->find_tools()) + tk.reset(); + return tk; + } + + bool msvc_toolkit::load_config(config const& settings) { + auto cfg = git::config::create(); + cfg.add_file_ondisk(settings.cfg_dir / ".covcollect"sv); + cfg.foreach_entry([this](git_config_entry const* entry) -> int { + auto name = std::string_view{entry->name}; + static constexpr auto prefix = "msvc."sv; +#ifdef _WIN32 + auto const ext = ".exe"s; +#endif + + if (!name.starts_with(prefix)) return 0; + auto key = name.substr(prefix.length()); + + if (key == "output-dir"sv) { + occ_dir_ = make_u8path(entry->value); + } else if (key == "filter"sv) { + occ_filter_ = entry->value; + } else if (key == "output"sv) { + occ_output_ = entry->value; + } + return 0; + }); + + if (occ_dir_.empty()) occ_dir_ = "OpenCppCoverage"sv; + if (occ_filter_.empty()) occ_filter_ = "cobertura"sv; + if (occ_output_.empty()) occ_output_ = "cobertura.xml"sv; + + return true; + } + + bool msvc_toolkit::get_version(config const& cfg) { + static constexpr auto MSC_VER = "_MSC_VER\n_MSC_FULL_VER"sv; + std::error_code ec{}; + auto const msc_ver = cfg.bin_dir / occ_dir_ / "msc_ver.c"; + std::filesystem::create_directories(msc_ver.parent_path(), ec); + if (ec) return false; + { + auto file = io::fopen(msc_ver, "w"); + if (!file) return false; + if (file.store(MSC_VER.data(), MSC_VER.size()) != MSC_VER.size()) + return false; + } + std::vector cl_args = {"/nologo"s, "/EP"s, + get_u8path(msc_ver.filename())}; + auto proc = platform::run(cfg.compiler, arguments{cl_args}, + msc_ver.parent_path(), {}); + if (proc.return_code) { + std::fwrite(proc.error.data(), 1, proc.error.size(), stderr); + return false; + } + + auto const ver_text = + trim({reinterpret_cast(proc.output.data()), + proc.output.size()}); + auto const ver_lines = split(ver_text, '\n'); + auto const first_line = trim(ver_lines.front()); + + auto major = first_line.substr(0, 2); + auto minor = first_line.size() > 2 ? first_line.substr(2) : "00"sv; + + if (ver_lines.size() > 1) { + auto const second_line = trim(ver_lines[1]); + if (second_line.size() > first_line.size()) { + auto const patch = second_line.substr(first_line.size()); + + ver_ = fmt::format("{}.{}.{}", major, minor, patch); + return true; + } + } + ver_ = fmt::format("{}.{}", major, minor); + return true; + } +} // namespace cov::app::collect diff --git a/apps/collect/queue.hh b/apps/collect/queue.hh new file mode 100644 index 00000000..3c6302b8 --- /dev/null +++ b/apps/collect/queue.hh @@ -0,0 +1,79 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include + +namespace cov { + template + class queue { + public: + queue() = default; + queue(queue const& other) { + std::lock_guard lock{other.m_}; + items_ = other.items_; + } + queue& operator=(queue const& other) { + std::unique_lock self{m_, std::defer_lock}; + std::unique_lock lock{other.m_, std::defer_lock}; + std::lock(self, lock); + items_ = other.items_; + return *this; + } + + bool empty() const { + std::lock_guard lock{m_}; + return items_.empty(); + } + + size_t size() const { + std::lock_guard lock{m_}; + return items_.size(); + } + + void wake() { cv_.notify_all(); } + + void push(Element const& value) { + std::lock_guard lock{m_}; + items_.push(value); + ++total_; + // fmt::print(stderr, + // "...new item (size: {}, total: {}, popped: {})\n", + // items_.size(), total_, popped_); + cv_.notify_one(); + } + void push(Element&& value) { + std::lock_guard lock{m_}; + items_.push(std::move(value)); + ++total_; + // fmt::print(stderr, + // "...new item (size: {}, total: {}, popped: {});\n", + // items_.size(), total_, popped_); + cv_.notify_one(); + } + + bool wait_and_pop(Element& result, std::stop_token tok) { + std::unique_lock lock{m_}; + cv_.wait(lock, [this, &tok] { + return !items_.empty() || tok.stop_requested(); + }); + if (!items_.empty()) { + result = std::move(items_.front()); + items_.pop(); + ++popped_; + } + return !tok.stop_requested(); + } + + private: + mutable std::mutex m_{}; + std::condition_variable cv_{}; + size_t total_{}; + size_t popped_{}; + std::queue items_{}; + }; +} // namespace cov diff --git a/apps/collect/report.cc b/apps/collect/report.cc new file mode 100644 index 00000000..954c0cac --- /dev/null +++ b/apps/collect/report.cc @@ -0,0 +1,212 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "report.hh" +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace cov::app::collect { + coverage_file* report::get_file(std::string_view path) { + if (!path.starts_with(src_prefix_)) return nullptr; + path = path.substr(src_prefix_.length()); + for (auto const& excl_path : cfg_.exclude) { + auto excl = get_u8path(excl_path); + if (!path.starts_with(excl)) continue; + auto rest = path.substr(excl.size()); + if (rest.empty() || rest.front() == '/') return nullptr; + } + for (auto const& incl_path : cfg_.include) { + auto incl = get_u8path(incl_path); + if (!path.starts_with(incl)) continue; + auto rest = path.substr(incl.size()); + if (rest.empty() || rest.front() == '/') { + auto key = std::string{path.data(), path.size()}; + auto it = files_.find(key); + if (it == files_.end()) { + bool ignore = false; + std::tie(it, ignore) = + files_.insert({key, std::make_unique(key)}); + } + return it->second.get(); + } + } + return nullptr; + {} + } + + std::unique_ptr report::get_file_mt(std::string_view path) { + if (!path.starts_with(src_prefix_)) return nullptr; + path = path.substr(src_prefix_.length()); + for (auto const& excl_path : cfg_.exclude) { + auto excl = get_u8path(excl_path); + if (!path.starts_with(excl)) continue; + auto rest = path.substr(excl.size()); + if (rest.empty() || rest.front() == '/') return nullptr; + } + for (auto const& incl_path : cfg_.include) { + auto incl = get_u8path(incl_path); + if (!path.starts_with(incl)) continue; + auto rest = path.substr(incl.size()); + if (rest.empty() || rest.front() == '/') { + return std::make_unique( + std::string{path.data(), path.size()}); + } + } + return nullptr; + } + + void report::handover_mt(std::unique_ptr&& returned) { + std::lock_guard lock{m_}; + std::unique_ptr src{static_cast(returned.release())}; + + auto it = files_.find(src->filename()); + if (it == files_.end()) { + bool ignore = false; + std::tie(it, ignore) = + files_.insert({src->filename(), std::move(src)}); + return; + } + it->second->merge(*src); + } + + void report::post_process() { + for (auto& [name, data] : files_) { + data->post_process(cfg_.src_dir / make_u8path(name)); + } + } + + io::v1::coverage_stats report::summary() const { + auto result = io::v1::coverage_stats::init(); + result.lines_total = static_cast(files_.size()); // reuse + for (auto& [name, data] : files_) { + result.lines.relevant += + static_cast(data->lines().size()); + for (auto const& [_, count] : data->lines()) { + if (count) ++result.lines.visited; + } + + result.functions.relevant += + static_cast(data->functions().size()); + for (auto const& fun : data->functions()) { + if (fun.count) ++result.functions.visited; + } + } + return result; + } + + json::node report::get_json(json::string const& branch, git::oid_view ref) { + json::array json_files{}; + json_files.reserve(files_.size()); + for (auto const& [filename, file] : files_) { + json_files.push_back(file->get_json(filename)); + } + + return json::map{ + {u8"$schema"s, + to_u8s(fmt::format("https://raw.githubusercontent.com/mzdun/cov/" + "v{}/apps/report-schema.json", + cov::version::string))}, + { + u8"git"s, + json::map{{u8"branch"s, branch}, + {u8"head"s, to_u8s(ref.str())}}, + }, + {u8"files"s, std::move(json_files)}, + }; + } + + std::string report::build_prefix() const { + return fmt::format("{}/", get_u8path(cfg_.src_dir)); + } + + json::node report::function_cvg::get_json() const { + json::map item{ + {u8"name"s, to_u8s(name)}, + {u8"count"s, count}, + {u8"start_line"s, start.line}, + }; + if (start.col) item[u8"start_column"s] = start.col; + if (stop.line) item[u8"end_line"s] = stop.line; + if (stop.col) item[u8"end_column"s] = stop.col; + if (!demangled.empty()) item[u8"demangled"s] = to_u8s(demangled); + return {std::move(item)}; + } + + void report::file::on_visited(unsigned line, unsigned count) { + lines_[line] += count; + } + + void report::file::on_function(text_pos const& start, + text_pos const& stop, + unsigned count, + std::string const& name, + std::string const& demangled) { + functions_.push_back({.start = start, + .stop = stop, + .count = count, + .name = name, + .demangled = demangled}); + } + + void report::file::merge(file& src) { + for (auto const& [line, count] : src.lines_) + lines_[line] += count; + functions_.insert(functions_.end(), + std::make_move_iterator(src.functions_.begin()), + std::make_move_iterator(src.functions_.end())); + } + + void report::file::post_process(std::filesystem::path const& path) { + auto input = cov::io::fopen(path, "rb"); + if (!input) { + hash_.clear(); + return; + } + + std::byte buffer[8192]; + hash::sha1 m{}; + + while (auto size = input.load(buffer, sizeof(buffer))) { + m.update({buffer, size}); + } + hash_ = fmt::format("sha1:{}", m.finalize().str()); + + std::sort(functions_.begin(), functions_.end()); + } + + json::node report::file::get_json(std::string_view filename) const { + json::map result{{u8"name"s, to_u8s(filename)}, + {u8"digest"s, to_u8s(hash_)}, + {u8"line_coverage"s, get_lines()}}; + if (!functions_.empty()) { + result[u8"functions"s] = get_functions(); + } + + return {std::move(result)}; + } + + json::node report::file::get_lines() const { + json::map result{}; + for (auto const& [line, count] : lines_) { + result[to_u8s(fmt::format("{}", line))] = count; + } + return {std::move(result)}; + } + + json::node report::file::get_functions() const { + json::array result{}; + result.reserve(functions_.size()); + + for (auto const& function : functions_) { + result.emplace_back(function.get_json()); + } + return {result}; + } +} // namespace cov::app::collect diff --git a/apps/collect/report.hh b/apps/collect/report.hh new file mode 100644 index 00000000..6c71dbc1 --- /dev/null +++ b/apps/collect/report.hh @@ -0,0 +1,82 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace cov::app::collect { + struct report : coverage { + report(config const& cfg) : cfg_{cfg} {} + coverage_file* get_file(std::string_view path) override; + std::unique_ptr get_file_mt( + std::string_view path) override; + void handover_mt(std::unique_ptr&&) override; + + void post_process(); + io::v1::coverage_stats summary() const; + json::node get_json(json::string const& branch, git::oid_view ref); + + private: + std::string build_prefix() const; + + struct function_cvg { + cov::app::collect::text_pos start; + cov::app::collect::text_pos stop; + unsigned count; + std::string name; + std::string demangled; + + json::node get_json() const; + auto operator<=>(function_cvg const&) const noexcept = default; + }; + + struct file : coverage_file { + file(std::string const& filename) : filename_{filename} {} + + void on_visited(unsigned line, unsigned count) override; + void on_function(text_pos const& start, + text_pos const& stop, + unsigned count, + std::string const& name, + std::string const& demangled) override; + + void merge(file& src); + + std::string const& filename() const noexcept { return filename_; } + + std::map const& lines() const noexcept { + return lines_; + } + std::vector const& functions() const noexcept { + return functions_; + } + + void post_process(std::filesystem::path const& path); + json::node get_json(std::string_view filename) const; + json::node get_lines() const; + json::node get_functions() const; + + private: + std::string filename_; + std::map lines_{}; + std::vector functions_{}; + std::string hash_{}; + }; + + std::mutex m_; + config const& cfg_; + std::string src_prefix_{build_prefix()}; + std::map> files_{}; + }; +} // namespace cov::app::collect diff --git a/apps/collect/task_watcher.cc b/apps/collect/task_watcher.cc new file mode 100644 index 00000000..0065efff --- /dev/null +++ b/apps/collect/task_watcher.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "task_watcher.hh" +#include +#include + +using namespace std::literals; + +namespace cov::app::collect { + void task_watcher::print() { + auto const now = clock::now(); + auto const duration = now - last_print_; + if (duration < 1s) return; + last_print_ = now; + fmt::print(stderr, "[{}/{}] collecting...\r", finished_, total_); + std::fflush(stderr); + } + + void task_watcher::task_prepared() { + std::lock_guard lock{m_}; + if (run_all_.stop_requested()) return; + ++counter_; + ++total_; + print(); + } + + void task_watcher::task_finished() { + std::lock_guard lock{m_}; + if (run_all_.stop_requested()) return; + if (counter_) { + ++finished_; + --counter_; + if (!counter_) cv_.notify_one(); + print(); + } + } + + void task_watcher::abort() { + run_all_.request_stop(); + cv_.notify_one(); + } + + void task_watcher::wait() { + std::unique_lock lock{m_}; + cv_.wait(lock, + [this] { return counter_ == 0 || run_all_.stop_requested(); }); + fmt::print(stderr, "[{}/{}] finished \n", finished_, total_); + } + + bool closure::set_return_code(int ret) { + if (!ret) return false; + int zero{}; + if (return_code.compare_exchange_weak(zero, ret, + std::memory_order_relaxed)) + fmt::print(stderr, "[report] aborting...\n"); + watcher.abort(); + return true; + } + + void closure::task_finished() { watcher.task_finished(); } + void closure::push(std::function const& task) { + watcher.task_prepared(); + pool.push(task); + } + + int closure::wait() { + watcher.wait(); + return return_code; + } +} // namespace cov::app::collect diff --git a/apps/collect/task_watcher.hh b/apps/collect/task_watcher.hh new file mode 100644 index 00000000..f61fff5f --- /dev/null +++ b/apps/collect/task_watcher.hh @@ -0,0 +1,45 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace cov::app::collect { + class task_watcher { + using clock = std::chrono::steady_clock; + std::mutex m_; + size_t counter_{}; + size_t total_{}; + size_t finished_{}; + clock::time_point last_print_{}; + std::condition_variable cv_{}; + std::stop_source run_all_{}; + + public: + void print(); + void task_prepared(); + void task_finished(); + void abort(); + void wait(); + }; + + struct closure { + config const& cfg; + coverage& cvg; + thread_pool pool{std::thread::hardware_concurrency() * 2}; + std::atomic return_code{0}; + task_watcher watcher{}; + + bool set_return_code(int ret); + void task_finished(); + void push(std::function const& task); + int wait(); + }; + +} // namespace cov::app::collect diff --git a/apps/collect/thread_pool.cc b/apps/collect/thread_pool.cc new file mode 100644 index 00000000..f959b956 --- /dev/null +++ b/apps/collect/thread_pool.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include + +using namespace std::literals; + +// define REPORT_TIMES 1 + +namespace cov { + thread_pool::thread_pool(size_t size) { + if (!size) size = 1; + threads_.reserve(size); + for (size_t index = 0; index < size; ++index) + threads_.push_back(std::jthread{thread_proc, std::ref(tasks_)}); + } + thread_pool::~thread_pool() { + for (auto& thread : threads_) + thread.request_stop(); + tasks_.wake(); + } + + std::atomic counter{1}; + void thread_pool::thread_proc(std::stop_token tok, + queue>& tasks) { +#if REPORT_TIMES + using namespace std::chrono; + size_t id{1}, internal{}; + steady_clock::duration runtime{}; + while (!counter.compare_exchange_weak(id, id + 1, + std::memory_order_relaxed)) + ; +#endif + while (!tok.stop_requested()) { + std::function task; + if (tasks.wait_and_pop(task, tok)) { +#if REPORT_TIMES + ++internal; + auto const then = steady_clock::now(); +#endif + task(); +#if REPORT_TIMES + auto const now = steady_clock::now(); + runtime += now - then; +#endif + } + } + +#if REPORT_TIMES + auto const ms = duration_cast(runtime); + auto const cent_s = (ms.count() + 5) / 10; + fmt::print(stderr, "[#{}] {} call{}, {}.{:02} s\n", id, internal, + internal == 1 ? ""sv : "s"sv, cent_s / 100, cent_s % 100); +#endif + } +} // namespace cov diff --git a/apps/collect/thread_pool.hh b/apps/collect/thread_pool.hh new file mode 100644 index 00000000..2335fb1a --- /dev/null +++ b/apps/collect/thread_pool.hh @@ -0,0 +1,24 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include + +namespace cov { + class thread_pool { + public: + thread_pool(size_t size = std::thread::hardware_concurrency()); + ~thread_pool(); + + void push(std::function const& task) { tasks_.push(task); } + + private: + static void thread_proc(std::stop_token, + queue>& tasks); + queue> tasks_{}; + std::vector threads_{}; + }; +} // namespace cov diff --git a/apps/collect/toolkit.cc b/apps/collect/toolkit.cc new file mode 100644 index 00000000..92b57671 --- /dev/null +++ b/apps/collect/toolkit.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "toolkit.hh" + +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace cov::app::collect { + std::unique_ptr llvm(config const& cfg, + std::span lines); + std::unique_ptr gnu(config const& cfg, + std::span lines); + std::unique_ptr msvc(config const& cfg); + + static constexpr std::array toolkits = {gnu, llvm}; + + coverage_file::~coverage_file() = default; + coverage::~coverage() = default; + toolkit::~toolkit() = default; + + bool toolkit::needs_preprocess() const { return false; } + int toolkit::preprocess(config const&) { return 0; } + + bool toolkit::find_tool(std::filesystem::path& dst, + std::filesystem::path const& hint, + std::string_view tool, + std::span version) { + std::vector names{}; + names.reserve(version.size() + 1); + while (!version.empty()) { + names.push_back( + fmt::format("{}-{}", tool, fmt::join(version, "."))); + version = version.subspan(0, version.size() - 1); + } + names.push_back(fmt::format("{}", tool)); + auto result = platform::find_program(names, hint); + if (!result) return false; + dst = std::move(*result); + return true; + } + + void toolkit::remove_all(std::filesystem::path const& mask) { + walk(mask, [&](std::filesystem::path const& path) { + std::error_code ignore{}; + // fmt::print(stderr, "{}\n", get_u8path(path)); + std::filesystem::remove(path, ignore); + }); + } + + std::unique_ptr recognize_toolkit(config const& cfg) { +#ifdef _WIN32 + if (cfg.compiler.filename() == L"cl.exe"sv) return msvc(cfg); +#endif + char ver[] = "--version"; + char* v_args[] = {ver, nullptr}; + auto const proc = platform::run(cfg.compiler, {1, v_args}); + if (proc.return_code) return {}; + + auto view = trim({reinterpret_cast(proc.output.data()), + proc.output.size()}); + auto lines = split(view, '\n'); + + for (auto toolkit : toolkits) { + auto result = toolkit(cfg, lines); + if (result) return result; + } + + fmt::print( + stderr, + "[toolkit] could not find toolkit compatible with the compiler;\n" + "[toolkit] called: `{} --version`\n", + get_u8path(cfg.compiler)); + if (!lines.empty() && !lines.front().empty()) + fmt::print(stderr, "[toolkit] first line: `{}`\n", lines.front()); + + return {}; + } + + void config::load(std::filesystem::path const& filename) { + cfg_dir = std::filesystem::weakly_canonical(filename.parent_path()); + compiler.clear(); + bin_dir.clear(); + src_dir.clear(); + include.clear(); + exclude.clear(); + output.clear(); + + auto cfg = git::config::create(); + cfg.add_file_ondisk(filename); + cfg.foreach_entry([this](git_config_entry const* entry) -> int { + auto view = std::string_view{entry->name}; + if (view.starts_with("collect."sv)) { + auto key = view.substr("collect."sv.length()); + + if (key == "compiler"sv) { + this->compiler = make_u8path(entry->value); + return 0; + } + + if (key == "output"sv) { + this->output = make_u8path(entry->value); + return 0; + } + + if (key == "bin-dir"sv) { + this->bin_dir = std::filesystem::weakly_canonical( + this->cfg_dir / make_u8path(entry->value)); + return 0; + } + + if (key == "src-dir"sv) { + this->src_dir = std::filesystem::weakly_canonical( + this->cfg_dir / make_u8path(entry->value)); + return 0; + } + + if (key == "include"sv) { + this->include.push_back(make_u8path(entry->value)); + return 0; + } + + if (key == "exclude"sv) { + this->exclude.push_back(make_u8path(entry->value)); + return 0; + } + } + + return 0; + }); + + if (bin_dir.empty()) bin_dir = cfg_dir; + if (src_dir.empty()) src_dir = cfg_dir; + if (output.empty()) output = "cov-collect.json"; + } +} // namespace cov::app::collect diff --git a/apps/collect/toolkit.hh b/apps/collect/toolkit.hh new file mode 100644 index 00000000..79c4e308 --- /dev/null +++ b/apps/collect/toolkit.hh @@ -0,0 +1,86 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace cov::app::collect { + struct config { + std::filesystem::path cfg_dir; + std::filesystem::path compiler; + std::filesystem::path bin_dir; + std::filesystem::path src_dir; + std::filesystem::path output; + std::vector include; + std::vector exclude; + + void load(std::filesystem::path const& filename); + }; + + struct text_pos { + unsigned line{0}; + unsigned col{0}; + auto operator<=>(text_pos const&) const noexcept = default; + }; + + struct coverage_file { + virtual ~coverage_file(); + virtual void on_visited(unsigned line, unsigned count) = 0; + virtual void on_function(text_pos const& start, + text_pos const& stop, + unsigned count, + std::string const& name, + std::string const& demangled) = 0; + }; + + struct coverage { + virtual ~coverage(); + virtual coverage_file* get_file(std::string_view path) = 0; + virtual std::unique_ptr get_file_mt( + std::string_view path) = 0; + virtual void handover_mt(std::unique_ptr&&) = 0; + }; + + struct toolkit { + virtual ~toolkit(); + virtual std::string_view label() const noexcept = 0; + virtual std::string_view version() const noexcept = 0; + virtual void hello(config const&) const = 0; + virtual void clean(config const& cfg) const = 0; + virtual int observe(config const& cfg, + std::string_view command, + args::arglist arguments) const = 0; + virtual bool needs_preprocess() const; + virtual int preprocess(config const&); + virtual int report(config const&, coverage&) = 0; + + static bool find_tool(std::filesystem::path& dst, + std::filesystem::path const& hint, + std::string_view tool, + std::span version); + static void remove_all(std::filesystem::path const& mask); + }; + + struct arguments { + explicit arguments(std::span stg) { + mem_.reserve(stg.size()); + std::transform(stg.begin(), stg.end(), std::back_inserter(mem_), + [](auto& s) { return s.data(); }); + } + + operator ::args::arglist() noexcept { + return {static_cast(mem_.size()), mem_.data()}; + } + + public: + std::vector mem_; + }; + + std::unique_ptr recognize_toolkit(config const& cfg); +} // namespace cov::app::collect diff --git a/apps/collect/walk.cc b/apps/collect/walk.cc new file mode 100644 index 00000000..6984f105 --- /dev/null +++ b/apps/collect/walk.cc @@ -0,0 +1,187 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "walk.hh" + +#include +#include + +#ifdef WIN32 +#include +#pragma comment(lib, "shlwapi.lib") +namespace cov::app::platform { + bool glob_matches(std::filesystem::path const& match, + std::filesystem::path const name) { + return !!PathMatchSpecW(name.c_str(), match.c_str()); + } +} // namespace cov::app::platform +#else +#include +int fnmatch(const char* pattern, const char* string, int flags); +namespace cov::app::platform { + bool glob_matches(std::filesystem::path const& match, + std::filesystem::path const name) { + return !fnmatch(match.c_str(), name.c_str(), FNM_PATHNAME); + } +} // namespace cov::app::platform +#endif + +using namespace std::literals; + +namespace cov::app::collect { + std::vector> split_path( + std::filesystem::path const& path) { + std::vector> tmp{}; + + for (auto const& part : path) { + auto const u8part = get_u8path(part); + auto const kind = + u8part == "**"sv ? walk_type::recursive + : u8part.find_first_of("*?"sv) != std::string::npos + ? walk_type::directory_glob + : walk_type::directory; + tmp.push_back({kind, part}); + } + + if (!tmp.empty()) { + switch (tmp.back().first) { + case walk_type::directory: + tmp.back().first = walk_type::filename; + break; + case walk_type::directory_glob: + tmp.back().first = walk_type::filename_glob; + break; + default: + break; + } + } + std::vector> rewrite{}; + for (auto& [kind, part] : tmp) { + if (!rewrite.empty() && rewrite.back().first == kind && + (kind == walk_type::directory || + kind == walk_type::recursive)) { + rewrite.back().second /= part; + continue; + } + + rewrite.push_back({kind, part}); + } + + return rewrite; + } + + static void walk_impl( + std::filesystem::path const& root, + std::span const> stack, + std::function const& cb); + + static void notify( + std::filesystem::path const& path, + std::function const& cb) { + std::error_code ec{}; + auto exists = std::filesystem::is_regular_file(path, ec); + if (!ec && exists) cb(path); + } + + static void walk_notify( + std::filesystem::path const& path, + std::filesystem::path const& mask, + std::function const& cb) { + using namespace std::filesystem; + + std::error_code ec{}; + directory_iterator entries{path, ec}; + if (ec) return; + + for (auto const& entry : entries) { + if (!is_regular_file(entry.status())) continue; + if (!platform::glob_matches(mask, entry.path().filename())) + continue; + cb(entry.path()); + } + } + + static void walk_directory( + std::filesystem::path const& path, + std::filesystem::path const& mask, + std::span const> stack, + std::function const& cb) { + using namespace std::filesystem; + + std::error_code ec{}; + directory_iterator entries{path, ec}; + if (ec) return; + + for (auto const& entry : entries) { + if (!is_directory(entry.status())) continue; + if (!platform::glob_matches(mask, entry.path().filename())) + continue; + + walk_impl(entry.path(), stack, cb); + } + } + + static void recurse( + std::filesystem::path const& root, + std::span const> stack, + std::function const& cb) { + using namespace std::filesystem; + + // first, `.`: + walk_impl(root, stack, cb); + + std::error_code ec{}; + recursive_directory_iterator entries{root, ec}; + if (ec) return; + + for (auto const& entry : entries) { + if (!is_directory(entry.status())) continue; + walk_impl(entry.path(), stack, cb); + } + } + + static void walk_impl( + std::filesystem::path const& root, + std::span const> stack, + std::function const& cb) { + if (stack.empty()) return; + auto [type, chunk] = stack.front(); + stack = stack.subspan(1); + + switch (type) { + case walk_type::filename: + notify(root / chunk, cb); + return; + case walk_type::filename_glob: + walk_notify(root, chunk, cb); + return; + case walk_type::directory: + walk_impl(root / chunk, stack, cb); + return; + case walk_type::directory_glob: + walk_directory(root, chunk, stack, cb); + return; + case walk_type::recursive: + if (stack.empty()) return; + recurse(root, stack, cb); + return; + } + } + + void walk_split( + std::span const> stack, + std::function const& cb) { + std::filesystem::path root{"."sv}; + if (!stack.empty() && stack.front().first == walk_type::directory) { + root = stack.front().second; + stack = stack.subspan(1); + } + + walk_impl(root, stack, cb); + } + + void walk(std::filesystem::path const& path, + std::function const& cb) { + walk_split(split_path(path), cb); + } +} // namespace cov::app::collect diff --git a/apps/collect/walk.hh b/apps/collect/walk.hh new file mode 100644 index 00000000..00852ef3 --- /dev/null +++ b/apps/collect/walk.hh @@ -0,0 +1,30 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include + +namespace cov::app::collect { + enum class walk_type { + directory, + directory_glob, + filename, + filename_glob, + recursive, + }; + + std::vector> split_path( + std::filesystem::path const& path); + + void walk_split( + std::span const>, + std::function const&); + + void walk(std::filesystem::path const& path, + std::function const&); +} // namespace cov::app::collect diff --git a/apps/filters/native/str.hh b/apps/filters/native/str.hh index b44162ae..20014f48 100644 --- a/apps/filters/native/str.hh +++ b/apps/filters/native/str.hh @@ -7,16 +7,25 @@ #include #include #include +#include namespace cov::app { inline std::u8string_view to_u8(std::string_view str) { return {reinterpret_cast(str.data()), str.size()}; } + inline std::u8string to_u8s(std::string_view str) { + return {reinterpret_cast(str.data()), str.size()}; + } + inline std::string_view from_u8(std::u8string_view str) { return {reinterpret_cast(str.data()), str.size()}; } + inline std::string from_u8s(std::u8string_view str) { + return {reinterpret_cast(str.data()), str.size()}; + } + inline std::string_view trim(std::string_view s) { while (!s.empty() && std::isspace(static_cast(s.front()))) @@ -52,4 +61,15 @@ namespace cov::app { ++block; cb(block, text.substr(prev)); } + + inline std::vector split(std::string_view text, + char sep) { + size_t length{}; + split(text, sep, [&length](auto, auto const&) { ++length; }); + std::vector result{}; + result.reserve(length); + split(text, sep, + [&result](auto, auto view) { result.push_back(view); }); + return result; + } }; // namespace cov::app diff --git a/apps/filters/native/strip_excludes/excludes.cc b/apps/filters/native/strip_excludes/excludes.cc index c330d719..3dc417cb 100644 --- a/apps/filters/native/strip_excludes/excludes.cc +++ b/apps/filters/native/strip_excludes/excludes.cc @@ -34,6 +34,13 @@ namespace cov::app::strip { return has; } + template + unsigned column_from(std::string_view text, Match const& matcher) { + auto const diff = matcher.get<0>().to_view().data() - text.data(); + decltype(diff) zero = 0; + return static_cast(std::max(zero, diff) + 1); + } + void excludes::on_line(unsigned line_no, std::string_view text) { if (trim(text).empty()) { empties.insert(line_no); @@ -51,20 +58,19 @@ namespace cov::app::strip { } else if (auto end_match = matches_end(text); end_match) { if (inside_exclude) { auto const end = end_match.get<0>().to_view(); - warn(line_no, end_match.get<0>().begin() - text.data() + 1, + warn(line_no, column_from(text, end_match), fmt::format("found {}; did you mean {}?"sv, end, stop_for(end, "_END"sv))); } } else if (auto start_match = matches_start(text); start_match) { if (inside_exclude) { - warn(line_no, start_match.get<0>().begin() - text.data() + 1, + warn(line_no, column_from(text, start_match), fmt::format("double start: found {}"sv, start_match.get<0>().to_view())); note(std::get<0>(last_start), std::get<1>(last_start), "see previous start"); } else { - last_start = {line_no, - start_match.get<0>().begin() - text.data() + 1, + last_start = {line_no, column_from(text, start_match), start_match.get<0>().to_string()}; } inside_exclude = true; diff --git a/apps/tests/test_driver.py b/apps/tests/test_driver.py index c3e2af32..53a430cb 100755 --- a/apps/tests/test_driver.py +++ b/apps/tests/test_driver.py @@ -256,7 +256,10 @@ def __main__(): counters.report(outcome, test_id, message) shutil.rmtree(tempdir, ignore_errors=True) else: - with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: + hw_concurrency = os.cpu_count() + with concurrent.futures.ThreadPoolExecutor( + min(61, max(1, hw_concurrency * 2)) + ) as executor: futures = [] for test, counter in independent_tests: futures.append(executor.submit(task, env, test, counter)) diff --git a/cmake/builtins.cmake b/cmake/builtins.cmake index 9b7b8844..6e6056da 100644 --- a/cmake/builtins.cmake +++ b/cmake/builtins.cmake @@ -69,7 +69,17 @@ function(setup_cov_ext COV_TOOL) endfunction() macro(add_cov_ext COV_TOOL) - add_cov_tool(cov-${COV_TOOL} cov-${COV_TOOL}.cc) + string(REPLACE "-" "_" __COV_TOOL_SAFE_NAME "${COV_TOOL}") + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cov_${__COV_TOOL_SAFE_NAME}.cc) + set(${COV_TOOL}_CODE cov_${__COV_TOOL_SAFE_NAME}.cc) + elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/main.cc) + set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/main.cc) + elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) + set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) + else() + message(FATAL_ERROR "Cannot find code for ${COV_TOOL}'s tool()") + endif() + add_cov_tool(cov-${COV_TOOL} ${${COV_TOOL}_CODE}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES cov-${COV_TOOL}.cc) setup_cov_ext(${COV_TOOL}) diff --git a/conanfile.txt b/conanfile.txt index e54c7cc7..16224aca 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -3,6 +3,7 @@ mbits-args/0.12.3 fmt/9.1.0 gtest/cci.20210126 mbits-lngs/0.7.6 +ctre/3.7.2 zlib/1.2.12 libcurl/8.1.2 diff --git a/external/json b/external/json index 424d468d..111bcdc5 160000 --- a/external/json +++ b/external/json @@ -1 +1 @@ -Subproject commit 424d468df53020a47f2dd8f1c585b4231a125004 +Subproject commit 111bcdc5c2f88976d84993ccc0bc8212faf47299 diff --git a/flow.py b/flow.py index 73076783..d6bba687 100755 --- a/flow.py +++ b/flow.py @@ -31,4 +31,7 @@ def list_flows(): sys.exit(0) args = [sys.executable, os.path.join(__flow__, f"{sys.argv[1]}.py"), *sys.argv[2:]] -sys.exit(subprocess.run(args, shell=False).returncode) +try: + sys.exit(subprocess.run(args, shell=False).returncode) +except KeyboardInterrupt: + sys.exit(1) diff --git a/libs/app/CMakeLists.txt b/libs/app/CMakeLists.txt index b91e743a..6990e793 100644 --- a/libs/app/CMakeLists.txt +++ b/libs/app/CMakeLists.txt @@ -9,18 +9,26 @@ set(LOCALE_DIR "${PROJECT_BINARY_DIR}/${SHARE_DIR}/locale") set(SOURCES src/args.cc + src/path_env.hh src/path.cc src/tr.cc include/cov/app/args.hh include/cov/app/path.hh + include/cov/app/run.hh include/cov/app/tr.hh ) if (UNIX) - list(APPEND SOURCES src/posix.cc) + list(APPEND SOURCES + src/posix/exec_path.cc + src/posix/run.cc + ) elseif(WIN32) - list(APPEND SOURCES src/win32.cc) + list(APPEND SOURCES + src/win32/exec_path.cc + src/win32/run.cc + ) endif() set(GEN_SOURCES diff --git a/libs/app/include/cov/app/run.hh b/libs/app/include/cov/app/run.hh new file mode 100644 index 00000000..6a5a1f39 --- /dev/null +++ b/libs/app/include/cov/app/run.hh @@ -0,0 +1,48 @@ +// Copyright (c) 2022 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include +#include +#include +#include + +namespace cov::app::platform { + int run_tool(std::filesystem::path const& tooldir, + std::string_view tool, + args::arglist args); + + struct captured_output { + std::vector output{}; + std::vector error{}; + int return_code{}; + }; + + captured_output run_filter(std::filesystem::path const& filter_dir, + std::filesystem::path const& cwd, + std::string_view filter, + args::arglist args, + std::vector const& input); + + std::optional find_program( + std::span names, + std::filesystem::path const& hint = {}); + + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input); + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input = {}); + int call(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input); + + int call(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input = {}); +} // namespace cov::app::platform diff --git a/libs/cov-rt/src/path_env.hh b/libs/app/src/path_env.hh similarity index 100% rename from libs/cov-rt/src/path_env.hh rename to libs/app/src/path_env.hh diff --git a/libs/app/src/posix.cc b/libs/app/src/posix/exec_path.cc similarity index 100% rename from libs/app/src/posix.cc rename to libs/app/src/posix/exec_path.cc diff --git a/libs/cov-rt/src/posix.cc b/libs/app/src/posix/run.cc similarity index 75% rename from libs/cov-rt/src/posix.cc rename to libs/app/src/posix/run.cc index 8be17188..26c9e5dd 100644 --- a/libs/cov-rt/src/posix.cc +++ b/libs/app/src/posix/run.cc @@ -4,11 +4,12 @@ #include #include #include -#include +#include +#include #include #include #include -#include "path_env.hh" +#include "../path_env.hh" #ifdef RUNNING_GCOV extern "C" { @@ -35,6 +36,8 @@ namespace cov::app::platform { std::filesystem::path where(std::filesystem::path const& bin, char const* environment_variable, std::string const& program) { + if (program.find('/') != std::string::npos) return program; + auto path_str = env(environment_variable); auto dirs = split(bin.native(), path_str); @@ -140,6 +143,37 @@ namespace cov::app::platform { this, std::ref(src)); } + static void dump(std::span buffer) { + static constexpr auto len = 20zu; + char line[len * 4 + 2]; + line[len * 4] = '\n'; + line[len * 4 + 1] = 0; + auto index = 0zu; + for (auto b : buffer) { + if (index == len) { + fputs(line, stdout); + index = 0; + } + + static constexpr char alphabet[] = "0123456789ABCDEF"; + auto const c = static_cast(b); + line[index * 3] = alphabet[(c >> 4) & 0xF]; + line[index * 3 + 1] = alphabet[c & 0xF]; + line[index * 3 + 2] = ' '; + line[len * 3 + index] = std::isprint(c) ? c : '.'; + ++index; + } + if (index < len) { + for (; index < len; ++index) { + line[index * 3] = ' '; + line[index * 3 + 1] = ' '; + line[index * 3 + 2] = ' '; + line[len * 3 + index] = ' '; + } + fputs(line, stdout); + } + } + std::thread async_read(std::vector& dst) { return std::thread( [](int fd, std::vector& bytes) { @@ -149,6 +183,7 @@ namespace cov::app::platform { auto const actual = ::read(fd, buffer, std::size(buffer)); if (actual <= 0) break; + // dump({buffer, buffer + actual}); bytes.insert(bytes.end(), buffer, buffer + actual); } }, @@ -286,4 +321,44 @@ namespace cov::app::platform { std::string(filter.data(), filter.size()), args, &input, &cwd, true); } + + std::optional find_program( + std::span names, + std::filesystem::path const& hint) { + for (auto const& name : names) { + auto candidate = where(hint, "PATH", name); + if (!candidate.empty()) return candidate; + } + return std::nullopt; + } + + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input) { + return execute({}, "PATH", get_u8path(exec), args, &input, &cwd, true); + } + + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input) { + return execute({}, "PATH", get_u8path(exec), args, &input, nullptr, + true); + } + + int call(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input) { + return execute({}, "PATH", get_u8path(exec), args, &input, &cwd, false) + .return_code; + } + + int call(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input) { + return execute({}, "PATH", get_u8path(exec), args, &input, nullptr, + false) + .return_code; + } } // namespace cov::app::platform diff --git a/libs/app/src/win32.cc b/libs/app/src/win32/exec_path.cc similarity index 100% rename from libs/app/src/win32.cc rename to libs/app/src/win32/exec_path.cc diff --git a/libs/cov-rt/src/win32.cc b/libs/app/src/win32/run.cc similarity index 90% rename from libs/cov-rt/src/win32.cc rename to libs/app/src/win32/run.cc index 150bd5c4..32288c3c 100644 --- a/libs/cov-rt/src/win32.cc +++ b/libs/app/src/win32/run.cc @@ -6,15 +6,15 @@ #include #include #include -#include +#include #include #include #include #include #include #include +#include "../path_env.hh" #include "fmt/format.h" -#include "path_env.hh" namespace cov::app::platform { namespace { @@ -373,12 +373,16 @@ namespace cov::app::platform { std::filesystem::path where(std::filesystem::path const& bin, wchar_t const* environment_variable, std::wstring const& program) { - auto path_str = env(environment_variable); - auto dirs = split(bin.native(), path_str); - auto ext_str = env(L"PATHEXT"); auto path_ext = split(std::wstring{}, ext_str); + if (program.find_first_of(L"\\/"sv) != std::string::npos) { + return program; + } + + auto path_str = env(environment_variable); + auto dirs = split(bin.native(), path_str); + for (auto const& dir : dirs) { for (auto const ext : path_ext) { auto path = @@ -527,4 +531,45 @@ namespace cov::app::platform { return execute(filter_dir, L"COV_FILTER_PATH", from_utf8(filter), args, &input, &cwd, true); } + + std::optional find_program( + std::span names, + std::filesystem::path const& hint) { + for (auto const& name : names) { + auto candidate = where(hint, L"PATH", from_utf8(name)); + if (!candidate.empty()) return candidate; + } + return std::nullopt; + } + + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input) { + return execute({}, L"PATH", exec.native(), args, &input, &cwd, true); + } + + captured_output run(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input) { + return execute({}, L"PATH", exec.native(), args, &input, nullptr, true); + } + + int call(std::filesystem::path const& exec, + args::arglist args, + std::filesystem::path const& cwd, + std::vector const& input) { + auto input_ptr = input.empty() ? nullptr : &input; + return execute({}, L"PATH", exec.native(), args, input_ptr, &cwd, false) + .return_code; + } + + int call(std::filesystem::path const& exec, + args::arglist args, + std::vector const& input) { + auto input_ptr = input.empty() ? nullptr : &input; + return execute({}, L"PATH", exec.native(), args, input_ptr, nullptr, + false) + .return_code; + } } // namespace cov::app::platform diff --git a/libs/cov-api/include/cov/git2/repository.hh b/libs/cov-api/include/cov/git2/repository.hh index bb2761cc..b895303b 100644 --- a/libs/cov-api/include/cov/git2/repository.hh +++ b/libs/cov-api/include/cov/git2/repository.hh @@ -25,6 +25,10 @@ namespace git { return git::create_handle(ec, git_reference_resolve, this->get()); } + + char const* shorthand() const noexcept { + return git_reference_shorthand(this->get()); + } }; template diff --git a/libs/cov-api/include/cov/io/types.hh b/libs/cov-api/include/cov/io/types.hh index 86498153..47c8e2b3 100644 --- a/libs/cov-api/include/cov/io/types.hh +++ b/libs/cov-api/include/cov/io/types.hh @@ -295,7 +295,7 @@ namespace cov::io { // would not overflow an uintmax... return {static_cast(out / divider), static_cast(out % divider), digits}; - // GCOV_EXCL_END + // GCOV_EXCL_STOP } }; diff --git a/libs/cov-api/src/cov/format/facades.cc b/libs/cov-api/src/cov/format/facades.cc index 451a0845..d137cc8c 100644 --- a/libs/cov-api/src/cov/format/facades.cc +++ b/libs/cov-api/src/cov/format/facades.cc @@ -12,9 +12,7 @@ namespace cov::placeholder { class file_facade : public object_facade { public: - file_facade(cov::files::entry const* data, - cov::repository const* repo) - : data_{data}, repo_{repo} {} + file_facade(cov::files::entry const* data) : data_{data} {} std::string_view name() const noexcept override { return "blob"sv; } std::string_view secondary_label() const noexcept override { @@ -51,14 +49,11 @@ namespace cov::placeholder { private: cov::files::entry const* data_{}; - cov::repository const* repo_{}; }; class files_facade : public object_facade { public: - files_facade(ref_ptr const& data, - cov::repository const* repo) - : data_{data}, repo_{repo} {} + files_facade(ref_ptr const& data) : data_{data} {} std::string_view name() const noexcept override { return "files"sv; @@ -70,7 +65,6 @@ namespace cov::placeholder { private: ref_ptr data_{}; - cov::repository const* repo_{}; }; class build_facade : public object_facade { @@ -380,13 +374,13 @@ namespace cov::placeholder { std::unique_ptr object_facade::present_files( ref_ptr const& data, - cov::repository const* repo) { - return std::make_unique(data, repo); + cov::repository const*) { + return std::make_unique(data); } std::unique_ptr object_facade::present_file( cov::files::entry const* data, - cov::repository const* repo) { - return std::make_unique(data, repo); + cov::repository const*) { + return std::make_unique(data); } } // namespace cov::placeholder diff --git a/libs/cov-api/src/cov/io/function_coverage.cc b/libs/cov-api/src/cov/io/function_coverage.cc index a5db69bd..9f43636e 100644 --- a/libs/cov-api/src/cov/io/function_coverage.cc +++ b/libs/cov-api/src/cov/io/function_coverage.cc @@ -183,9 +183,6 @@ namespace cov::io::handlers { return true; } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif } // namespace cov::io::handlers namespace cov { diff --git a/libs/cov-api/tests/cov/diff-test.cc b/libs/cov-api/tests/cov/diff-test.cc index 94674de6..dc6113b7 100644 --- a/libs/cov-api/tests/cov/diff-test.cc +++ b/libs/cov-api/tests/cov/diff-test.cc @@ -142,17 +142,17 @@ namespace cov::testing { ASSERT_FALSE(ec) << ec.message(); static constexpr quick_stat initial_files[] = { - {"main.cc"sv, {5, 1, 0, 0, 0, 0, 0}}, + {"main.cc"sv, {5, {1, 0}, {0, 0}, {0, 0}}}, }; static constexpr quick_stat middle_files[] = { - {"src/main.cc"sv, {5, 1, 0, 0, 0, 0, 0}}, - {"src/old-name.cc"sv, {6, 1, 0, 0, 0, 0, 0}}, + {"src/main.cc"sv, {5, {1, 0}, {0, 0}, {0, 0}}}, + {"src/old-name.cc"sv, {6, {1, 0}, {0, 0}, {0, 0}}}, }; static constexpr quick_stat current_files[] = { - {"src/main.cc"sv, {5, 1, 1, 0, 0, 0, 0}}, - {"src/greetings.cc"sv, {8, 3, 3, 0, 0, 0, 0}}, + {"src/main.cc"sv, {5, {1, 1}, {0, 0}, {0, 0}}}, + {"src/greetings.cc"sv, {8, {3, 3}, {0, 0}, {0, 0}}}, }; git::oid initial{}, middle{}, current{}; diff --git a/libs/cov-api/tests/cov/format/facade-test.cc b/libs/cov-api/tests/cov/format/facade-test.cc index 0bab408f..a6cc510d 100644 --- a/libs/cov-api/tests/cov/format/facade-test.cc +++ b/libs/cov-api/tests/cov/format/facade-test.cc @@ -339,7 +339,7 @@ namespace cov::placeholder::testing { ASSERT_FALSE(ec) << ec.message(); auto const report_id = "92b91e27801bbd1ee4e2cc456b81be767a03fbbf"_oid; - git::oid zero{}, build_id{}, files_id{}; + git::oid zero{}, build_id{}; io::v1::coverage_stats const stats{1250, {300, 299}, {1, 1}, {0, 0}}; diff --git a/libs/cov-rt/CMakeLists.txt b/libs/cov-rt/CMakeLists.txt index ea7c1993..ad396d84 100644 --- a/libs/cov-rt/CMakeLists.txt +++ b/libs/cov-rt/CMakeLists.txt @@ -5,7 +5,6 @@ set(SOURCES src/cvg_info.cc src/line_printer.cc src/module.cc - src/path_env.hh src/report_command.cc src/report.cc src/root_command.cc @@ -37,11 +36,6 @@ set(SOURCES include/cov/app/tools.hh ) -if (UNIX) - list(APPEND SOURCES src/posix.cc) -elseif(WIN32) - list(APPEND SOURCES src/win32.cc) -endif() source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) add_library(cov-rt STATIC ${SOURCES}) diff --git a/libs/cov-rt/include/cov/app/tools.hh b/libs/cov-rt/include/cov/app/tools.hh index 9852cb73..bea5c558 100644 --- a/libs/cov-rt/include/cov/app/tools.hh +++ b/libs/cov-rt/include/cov/app/tools.hh @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -48,22 +49,4 @@ namespace cov::app { git::config cfg_; std::span builtins_; }; - - namespace platform { - int run_tool(std::filesystem::path const& tooldir, - std::string_view tool, - args::arglist args); - - struct captured_output { - std::vector output{}; - std::vector error{}; - int return_code{}; - }; - - captured_output run_filter(std::filesystem::path const& filter_dir, - std::filesystem::path const& cwd, - std::string_view filter, - args::arglist args, - std::vector const& input); - } // namespace platform } // namespace cov::app diff --git a/libs/cov-rt/src/cvg_info.cc b/libs/cov-rt/src/cvg_info.cc index 6fd9ad34..16465a62 100644 --- a/libs/cov-rt/src/cvg_info.cc +++ b/libs/cov-rt/src/cvg_info.cc @@ -156,7 +156,7 @@ namespace cov::app { max_width -= std::min(max_width, widths.line_no_width); max_width -= std::min(max_width, margins); max_width = std::max(max_width, MAGIC); - // GCOV_EXCL_END + // GCOV_EXCL_STOP } auto name = fn.label; @@ -167,7 +167,7 @@ namespace cov::app { // GCOV_EXCL_START -- TODO: Add pty to test_driver backing.assign(name.substr(0, max_width - 3)); name = backing; - // GCOV_EXCL_END + // GCOV_EXCL_STOP } auto const count_column = fmt::format("{}x", fn.count); diff --git a/libs/cov-rt/src/line_printer.cc b/libs/cov-rt/src/line_printer.cc index 425bb3e1..019700a5 100644 --- a/libs/cov-rt/src/line_printer.cc +++ b/libs/cov-rt/src/line_printer.cc @@ -304,11 +304,11 @@ namespace cov::app::line_printer { } ctx.paint_color(); // EOL reset if (shortened) { - // GCOV_EXCL_START -- TODO: Add pty to test_driver + // LCOV_EXCL_START -- TODO: Add pty to test_driver if (use_color) ctx.result.append("\033[2;49;39m"sv); ctx.result.append("..."sv); if (use_color) ctx.result.append("\033[m"sv); - // GCOV_EXCL_END + // GCOV_EXCL_STOP } return ctx.result; diff --git a/libs/cov-rt/src/show.cc b/libs/cov-rt/src/show.cc index fe797f60..1214d81e 100644 --- a/libs/cov-rt/src/show.cc +++ b/libs/cov-rt/src/show.cc @@ -82,7 +82,7 @@ namespace cov::app::show { placeholder::color::faint_red); }, show_column::other, with_branches_missing}, - // GCOV_EXCL_END + // GCOV_EXCL_STOP column{"% Funcs"sv, [](environment const& env, cell_row& cells, diff --git a/libs/cov-rt/tests/tools-test.cc b/libs/cov-rt/tests/tools-test.cc index eafec06e..db62f40c 100644 --- a/libs/cov-rt/tests/tools-test.cc +++ b/libs/cov-rt/tests/tools-test.cc @@ -60,6 +60,7 @@ namespace cov::app::testing { { // add missing externals here... (this test will fail with every // new external added) + "collect"sv, }, actual); } diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 8435adb8..3fd791e8 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -27,6 +27,7 @@ _conan: Optional[conan] = None _platform_name, _platform_version, _platform_arch = uname() +_collect_version = (0, 21, 1) platform = _platform_name @@ -275,7 +276,7 @@ def configure_conan(config: dict): CONAN_PROFILE_GEN = "_profile-build_type" profile_gen = f"./{CONAN_DIR}/{CONAN_PROFILE_GEN}-{config['preset']}" - if config.get("--first-build", False): + if config.get("--first-build"): runner.refresh_build_dir("conan") if _conan is None: @@ -307,8 +308,8 @@ def configure_conan(config: dict): @step_call("CMake") def configure_cmake(config: dict): runner.refresh_build_dir(config["preset"]) - cov_COVERALLS = "ON" if config.get("coverage", False) else "OFF" - COV_SANITIZE = "ON" if config.get("sanitizer", False) else "OFF" + cov_COVERALLS = "ON" if config.get("coverage") else "OFF" + COV_SANITIZE = "ON" if config.get("sanitizer") else "OFF" COV_CUTDOWN_OS = "ON" if runner.CUTDOWN_OS else "OFF" runner.call( "cmake", @@ -324,10 +325,47 @@ def configure_cmake(config: dict): def build(config: dict): runner.call("cmake", "--build", "--preset", config["preset"], "--parallel") + @staticmethod + def get_bin(version: Tuple[int], config: dict): + ext = ".exe" if os.name == "nt" else "" + for dirname in [".local", "release", config["preset"]]: + path = f"build/{dirname}/bin/cov{ext}" + if not os.path.isfile(path): + continue + proc = subprocess.run([path, "--version"], shell=False, capture_output=True) + if proc.returncode: + continue + exe_version = tuple( + int(x) + for x in proc.stdout.strip() + .split(b" ")[-1] + .split(b"-")[0] + .decode("UTF-8") + .split(".") + ) + if exe_version >= version: + return path + return None + @staticmethod @step_call("Test") def test(config: dict): - if config.get("coverage", False): + has_coverage = config.get("coverage") + uses_occ = config.get("os") == "windows" + cov_exe = None + if has_coverage and not uses_occ: + cov_exe = steps.get_bin(_collect_version, config) + + if cov_exe is not None: + runner.call(cov_exe, "collect", "--clean") + runner.call( + cov_exe, "collect", "--observe", "ctest", "--preset", config["preset"] + ) + runner.call(cov_exe, "collect") + # todo: report coverage to github, somehow + return + + if has_coverage: runner.call( "cmake", "--build", @@ -346,8 +384,9 @@ def test(config: dict): _append_coverage(GITHUB_STEP_SUMMARY, json.load(f)) except KeyError: pass - else: - runner.call("ctest", "--preset", config["preset"]) + return + + runner.call("ctest", "--preset", config["preset"]) @staticmethod @step_call("Pack", lambda config: len(config.get("cpack_generator", [])) > 0) @@ -423,11 +462,16 @@ def _store_tests(config: dict): preset = config["preset"] runner.copy(f"build/{preset}/test-results", "build/artifacts/test-results") - if config.get("coverage", False): + if config.get("coverage"): output = f"build/artifacts/coveralls/{config['report_os']}-{config['report_compiler']}-{config['build_type']}.json" - print_args("cp", f"build/{preset}/coveralls.json", output) - if not runner.DRY_RUN: - copy_file(f"build/{preset}/coveralls.json", output) + if os.path.exists(f"build/{preset}/coveralls.json"): + print_args("cp", f"build/{preset}/coveralls.json", output) + if not runner.DRY_RUN: + copy_file(f"build/{preset}/coveralls.json", output) + else: + print_args("cp", f"build/{preset}/collected.json", output) + if not runner.DRY_RUN: + copy_file(f"build/{preset}/collected.json", output) @staticmethod @step_call( @@ -459,9 +503,14 @@ def dev_inst(config: dict): @step_call( "Report", flags=step_info.VERBOSE, - visible=lambda config: config.get("coverage", False) == True, + visible=lambda config: config.get("coverage") == True, ) def report(config: dict): + uses_occ = config.get("os") == "windows" + cov_exe = None + if not uses_occ: + cov_exe = steps.get_bin(_collect_version, config) + reporter = f"build/{config['preset']}/bin/cov" try: tag_process = subprocess.run([reporter, "tag"], stdout=subprocess.PIPE) @@ -474,15 +523,23 @@ def report(config: dict): except: tags = () version = get_version() - legacy_reporter = os.environ.get("LEGACY_COV") - report = f"build/{config['preset']}/coveralls.json" + report = f"build/{config['preset']}/collected.json" response = f"build/{config['preset']}/report_answers.txt" at_args = [] if os.path.isfile(response): at_args.append(f"@{response}") - runner.call(reporter, "report", "--filter", "coveralls", report, *at_args) - if legacy_reporter is not None: - runner.call(legacy_reporter, "import", "--in", report, "--amend") + if cov_exe is None: + coveralls = f"build/{config['preset']}/coveralls.json" + runner.call( + reporter, + "report", + "--out", + report, + "--filter", + "coveralls", + coveralls, + ) + runner.call(reporter, "report", "--filter", "strip-excludes", report, *at_args) if version.tag() in tags: runner.call( reporter, diff --git a/tools/flow/lib/runner.py b/tools/flow/lib/runner.py index 18865712..e9ff8f22 100644 --- a/tools/flow/lib/runner.py +++ b/tools/flow/lib/runner.py @@ -370,13 +370,21 @@ def refresh_build_dir(name): os.makedirs(fullname, exist_ok=True) @staticmethod - def call(*args): + def call(*args, **kwargs): print_args(*args) if runner.DRY_RUN: return + env_kwarg = kwargs.get("env", {}) + env = {**os.environ} + for key, value in env_kwarg.items(): + if value is None: + if key in env: + del env[key] + else: + env[key] = value found = shutil.which(args[0]) args = (found if found is not None else args[0], *args[1:]) - proc = subprocess.run(args, check=False) + proc = subprocess.run(args, check=False, env=env) if proc.returncode != 0: sys.exit(1) diff --git a/tools/flow/run.py b/tools/flow/run.py index fdba46ba..6a27c40b 100755 --- a/tools/flow/run.py +++ b/tools/flow/run.py @@ -309,4 +309,7 @@ def main(): if __name__ == "__main__": - main() + try: + main() + except KeyboardInterrupt: + sys.exit(1) From 0fbebb80bbfd176487d61aaf8fbb9d4a510e6856 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 14:07:43 +0200 Subject: [PATCH 04/39] fix: compile on windows + w/out warnings --- apps/filters/native/strip_excludes/excludes.cc | 3 ++- apps/filters/strip_excludes.cc | 4 ++-- libs/cov-api/src/cov/io/build.cc | 11 +---------- libs/cov-api/src/cov/io/files.cc | 1 + libs/cov-api/src/cov/io/function_coverage.cc | 1 + libs/cov-api/src/cov/io/line_coverage.cc | 11 +---------- libs/cov-api/src/cov/io/report.cc | 11 +---------- 7 files changed, 9 insertions(+), 33 deletions(-) diff --git a/apps/filters/native/strip_excludes/excludes.cc b/apps/filters/native/strip_excludes/excludes.cc index 3dc417cb..d032fddc 100644 --- a/apps/filters/native/strip_excludes/excludes.cc +++ b/apps/filters/native/strip_excludes/excludes.cc @@ -36,7 +36,8 @@ namespace cov::app::strip { template unsigned column_from(std::string_view text, Match const& matcher) { - auto const diff = matcher.get<0>().to_view().data() - text.data(); + auto const group0 = matcher.template get<0>().to_view(); + auto const diff = group0.data() - text.data(); decltype(diff) zero = 0; return static_cast(std::max(zero, diff) + 1); } diff --git a/apps/filters/strip_excludes.cc b/apps/filters/strip_excludes.cc index 3e60f9c0..4641156f 100644 --- a/apps/filters/strip_excludes.cc +++ b/apps/filters/strip_excludes.cc @@ -201,13 +201,13 @@ namespace cov::app::strip { line_counter == 1 ? "line"sv : "lines"sv); } if (fn_counter) { - if (first) fmt::print(stderr, ", "); + if (!first) fmt::print(stderr, ", "); first = false; fmt::print(stderr, "{} {}", fn_counter, fn_counter == 1 ? "function"sv : "functions"sv); } if (br_counter) { - if (first) fmt::print(stderr, ", "); + if (!first) fmt::print(stderr, ", "); first = false; fmt::print(stderr, "{} {}", br_counter, br_counter == 1 ? "branch"sv : "branches"sv); diff --git a/libs/cov-api/src/cov/io/build.cc b/libs/cov-api/src/cov/io/build.cc index 7dfdc79e..ec0f95eb 100644 --- a/libs/cov-api/src/cov/io/build.cc +++ b/libs/cov-api/src/cov/io/build.cc @@ -75,16 +75,10 @@ namespace cov::io::handlers { propset, build.stats); } -#if defined(__GNUC__) -// The warning is legit, since as_a<> can return nullptr, if there is no -// cov::build in type tree branch, but this should be called from within -// db_object::store, which is guarded by report::recognized -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnull-dereference" -#endif bool build::store(ref_ptr const& value, write_stream& out) const { auto const obj = as_a(static_cast(value.get())); + if (!obj) return false; auto stg = [obj] { strings_builder strings{}; strings.insert(obj->props_json()); @@ -117,9 +111,6 @@ namespace cov::io::handlers { return true; } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif } // namespace cov::io::handlers namespace cov { diff --git a/libs/cov-api/src/cov/io/files.cc b/libs/cov-api/src/cov/io/files.cc index 75a57e9a..d9c83af0 100644 --- a/libs/cov-api/src/cov/io/files.cc +++ b/libs/cov-api/src/cov/io/files.cc @@ -215,6 +215,7 @@ namespace cov::io::handlers { bool files::store(ref_ptr const& value, write_stream& out) const { auto const obj = as_a(static_cast(value.get())); + if (!obj) return false; auto entries = obj->entries(); auto only_lines = true; diff --git a/libs/cov-api/src/cov/io/function_coverage.cc b/libs/cov-api/src/cov/io/function_coverage.cc index 9f43636e..2405c3a8 100644 --- a/libs/cov-api/src/cov/io/function_coverage.cc +++ b/libs/cov-api/src/cov/io/function_coverage.cc @@ -134,6 +134,7 @@ namespace cov::io::handlers { write_stream& out) const { auto const obj = as_a( static_cast(value.get())); + if (!obj) return false; auto entries = obj->entries(); auto stg = [&] { diff --git a/libs/cov-api/src/cov/io/line_coverage.cc b/libs/cov-api/src/cov/io/line_coverage.cc index a6c5ff45..0d4724c0 100644 --- a/libs/cov-api/src/cov/io/line_coverage.cc +++ b/libs/cov-api/src/cov/io/line_coverage.cc @@ -34,17 +34,11 @@ namespace cov::io::handlers { return cov::line_coverage::create(std::move(result)); } -#if defined(__GNUC__) -// The warning is legit, since as_a<> can return nullptr, if there is no -// cov::line_coverage in type tree branch, but this should be called from within -// db_object::store, which is guarded by line_coverage::recognized -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnull-dereference" -#endif bool line_coverage::store(ref_ptr const& value, write_stream& out) const { auto const obj = as_a(static_cast(value.get())); + if (!obj) return false; auto const& items = obj->coverage(); v1::line_coverage hdr{.line_count = static_cast(items.size())}; @@ -52,9 +46,6 @@ namespace cov::io::handlers { if (!out.store(items)) return false; return true; } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif } // namespace cov::io::handlers namespace cov { diff --git a/libs/cov-api/src/cov/io/report.cc b/libs/cov-api/src/cov/io/report.cc index f2615c5a..cfa72ae7 100644 --- a/libs/cov-api/src/cov/io/report.cc +++ b/libs/cov-api/src/cov/io/report.cc @@ -229,16 +229,10 @@ namespace cov::io::handlers { header.added.to_seconds(), header.stats, std::move(builds)); } -#if defined(__GNUC__) -// The warning is legit, since as_a<> can return nullptr, if there is no -// cov::report in type tree branch, but this should be called from within -// db_object::store, which is guarded by report::recognized -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnull-dereference" -#endif bool report::store(ref_ptr const& value, write_stream& out) const { auto const obj = as_a(static_cast(value.get())); + if (!obj) return false; auto stg = [obj] { strings_builder strings{}; @@ -303,9 +297,6 @@ namespace cov::io::handlers { return true; } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif } // namespace cov::io::handlers namespace cov { From daf7acfec07788b0ba818dbf3b7810a4ec741d30 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 17:00:00 +0200 Subject: [PATCH 05/39] build: reduce code duplication --- apps/CMakeLists.txt | 4 +- tools/archives/__init__.py | 57 ++++++++++ tools/flow/lib/runner.py | 39 +------ tools/github-get-artifacts.py | 2 +- tools/github-get-latest-release.py | 50 +++++++++ tools/github/api.py | 105 +++++++++++++++++- .../json_tests}/driver/__init__.py | 0 .../json_tests}/driver/commands.py | 44 ++------ .../tests => tools/json_tests}/driver/test.py | 0 .../json_tests}/driver/testbed.py | 0 {apps/tests => tools/json_tests}/nullify.py | 6 +- .../json_tests/runner.py | 20 ++-- .../tests => tools/json_tests}/test_driver.py | 16 ++- 13 files changed, 248 insertions(+), 95 deletions(-) create mode 100644 tools/archives/__init__.py create mode 100755 tools/github-get-latest-release.py rename {apps/tests => tools/json_tests}/driver/__init__.py (100%) rename {apps/tests => tools/json_tests}/driver/commands.py (63%) rename {apps/tests => tools/json_tests}/driver/test.py (100%) rename {apps/tests => tools/json_tests}/driver/testbed.py (100%) rename {apps/tests => tools/json_tests}/nullify.py (86%) rename apps/tests/test_runner.py => tools/json_tests/runner.py (69%) rename {apps/tests => tools/json_tests}/test_driver.py (95%) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index ed684d6a..cb4beb31 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -212,7 +212,7 @@ if (COV_TESTING) add_test( NAME cov-exec--${TEST_SET} COMMAND "${Python3_EXECUTABLE}" - "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_runner.py" + "${PROJECT_SOURCE_DIR}/tools/json_tests/runner.py" --bin "${PROJECT_BINARY_DIR}" --tests "main-set/${TEST_SET}" --version "${PROJECT_VERSION}${PROJECT_VERSION_STABILITY}${PROJECT_VERSION_BUILD_META}" @@ -223,7 +223,7 @@ if (COV_TESTING) add_test( NAME cov-exec-pl COMMAND "${Python3_EXECUTABLE}" - "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_runner.py" + "${PROJECT_SOURCE_DIR}/tools/json_tests/runner.py" --bin "${PROJECT_BINARY_DIR}" --tests "messages-pl" --version "${PROJECT_VERSION}${PROJECT_VERSION_STABILITY}${PROJECT_VERSION_BUILD_META}" diff --git a/tools/archives/__init__.py b/tools/archives/__init__.py new file mode 100644 index 00000000..4c540a80 --- /dev/null +++ b/tools/archives/__init__.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# Copyright (c) 2023 Marcin Zdun +# This code is licensed under MIT license (see LICENSE for details) + +import zipfile +import tarfile +import os +from typing import Dict, Callable, Tuple, List + + +def _untar(src, dst): + with tarfile.open(src) as TAR: + + def is_within_directory(directory, target): + abs_directory = os.path.abspath(directory) + abs_target = os.path.abspath(target) + + prefix = os.path.commonprefix([abs_directory, abs_target]) + + return prefix == abs_directory + + for member in TAR.getmembers(): + member_path = os.path.join(dst, member.name) + if not is_within_directory(dst, member_path): + raise Exception(f"Attempted path traversal in Tar file: {member.name}") + + TAR.extractall(dst) + + +def _unzip(src, dst): + with zipfile.ZipFile(src) as ZIP: + ZIP.extractall(dst) + + +_tar = (_untar, ["tar", "-xf"]) + +Unpacker = Callable[[str, str], None] +UnpackInfo = Tuple[Unpacker, List[str]] + +ARCHIVES: Dict[str, UnpackInfo] = { + ".tar": _tar, + ".tar.gz": _tar, + ".zip": (_unzip, ["unzip"]), +} + + +def locate_unpack(archive: str) -> UnpackInfo: + reminder, ext = os.path.splitext(archive) + _, mid = os.path.splitext(reminder) + if mid == ".tar": + ext = ".tar" + return ARCHIVES[ext] + + +del _tar +del _unzip +del _untar diff --git a/tools/flow/lib/runner.py b/tools/flow/lib/runner.py index e9ff8f22..f4156e3f 100644 --- a/tools/flow/lib/runner.py +++ b/tools/flow/lib/runner.py @@ -15,37 +15,10 @@ from dataclasses import dataclass from typing import Callable, ClassVar, Dict, List, Optional, Tuple +__file_dir__ = os.path.dirname(__file__) +sys.path.append(os.path.dirname(os.path.dirname(__file_dir__))) -def _untar(src, dst): - with tarfile.open(src) as TAR: - - def is_within_directory(directory, target): - abs_directory = os.path.abspath(directory) - abs_target = os.path.abspath(target) - - prefix = os.path.commonprefix([abs_directory, abs_target]) - - return prefix == abs_directory - - for member in TAR.getmembers(): - member_path = os.path.join(dst, member.name) - if not is_within_directory(dst, member_path): - raise Exception(f"Attempted path traversal in Tar file: {member.name}") - - TAR.extractall(dst) - - -def _unzip(src, dst): - with zipfile.ZipFile(src) as ZIP: - ZIP.extractall(dst) - - -_tar = (_untar, ["tar", "-xf"]) -ARCHIVES: Dict[str, Tuple[Callable[[str, str], None], List[str]]] = { - ".tar": _tar, - ".tar.gz": _tar, - ".zip": (_unzip, ["unzip"]), -} +from archives import locate_unpack def copy_file(src, dst): @@ -403,11 +376,7 @@ def copy(src_dir: str, dst_dir: str, regex: str = ""): def extract(src_dir: str, dst_dir: str, package: str): archive = f"{src_dir}/{package}" - reminder, ext = os.path.splitext(archive) - _, mid = os.path.splitext(reminder) - if mid == ".tar": - ext = ".tar" - unpack, msg = ARCHIVES[ext] + unpack, msg = locate_unpack(archive) print_args(*msg, archive, dst_dir) if not runner.DRY_RUN: diff --git a/tools/github-get-artifacts.py b/tools/github-get-artifacts.py index e4b22ad1..30328f04 100755 --- a/tools/github-get-artifacts.py +++ b/tools/github-get-artifacts.py @@ -9,7 +9,7 @@ from github.cmake import get_version from github.runner import Environment -ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) GITHUB_ORG = "mzdun" parser = argparse.ArgumentParser(usage="Download artifacts from GitHub") diff --git a/tools/github-get-latest-release.py b/tools/github-get-latest-release.py new file mode 100755 index 00000000..24b1d2bd --- /dev/null +++ b/tools/github-get-latest-release.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Copyright (c) 2023 Marcin Zdun +# This code is licensed under MIT license (see LICENSE for details) + +import argparse +import os +import sys +import subprocess + +from archives import locate_unpack +from github.api import API +from github.cmake import get_version +from github.runner import Environment, print_args + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +GITHUB_ORG = "mzdun" + + +parser = argparse.ArgumentParser(usage="Download the latest release from GitHub") +parser.add_argument( + "--dry-run", + action="store_true", + required=False, + help="print commands, change nothing", +) + +args = parser.parse_args() +Environment.DRY_RUN = args.dry_run + +version_tag = get_version().tag() +repo_name = get_version().name.value +api = API(GITHUB_ORG, repo_name) + +proc = subprocess.run( + [sys.executable, os.path.join(ROOT, "packages", "system.py"), "platform"], + shell=False, + capture_output=True, +) +platform = None if proc.returncode != 0 else proc.stdout.strip().decode("UTF-8") + + +release = api.get_release(platform=platform) + +if release is None: + sys.exit(0) + +unpack, msg = locate_unpack(release) +print_args((*msg, release, "build/.local")) +if not Environment.DRY_RUN: + unpack(release, "build/.local") diff --git a/tools/github/api.py b/tools/github/api.py index 94613bdd..391f6e80 100644 --- a/tools/github/api.py +++ b/tools/github/api.py @@ -4,8 +4,10 @@ import json import os import subprocess +import sys import urllib.parse from typing import Any, List, Optional, Union +import hashlib from .changelog import ChangeLog, format_changelog, read_tag_date from .runner import Environment, capture, checked, checked_capture, print_args @@ -49,12 +51,14 @@ def gh( method: Optional[str] = None, server: Optional[str] = None, capture_output: bool = True, + **kwargs, ): + accept = kwargs.get("accept", "application/vnd.github+json") cmd = [ "gh", "api", "-H", - "Accept: application/vnd.github+json", + f"Accept: {accept}", "-H", "X-GitHub-Api-Version: 2022-11-28", ] @@ -88,6 +92,7 @@ def gh( method: Optional[str] = None, server: Optional[str] = None, capture_output: bool = True, + **kwargs, ): return gh( f"{self.root}{res}", @@ -95,6 +100,7 @@ def gh( method=method, server=server, capture_output=capture_output, + **kwargs, ) def json_from( @@ -252,3 +258,100 @@ def publish_release(self, release_id: int) -> Optional[str]: "make_latest=legacy", method="PATCH", ).get("html_url") + + def get_release( + self, tag: Optional[str] = None, platform: Optional[str] = None + ) -> Optional[str]: + try: + proc = checked_capture("git", "rev-parse", "--show-toplevel") + if proc is None: + return None + root = proc.stdout.decode("UTF-8").strip() + rel_dir = os.path.join(root, "build", "downloads", "releases") + os.makedirs(rel_dir, exist_ok=True) + + proc = self.gh("/releases/latest" if tag is None else f"/releases/tags/{tag}") + if proc is None: + return None + + data = json.loads(proc.stdout.decode("UTF-8")) + name = data.get("name") + version = name[1:] + assets = { + asset.get("name"): ( + asset.get("id"), + asset.get("browser_download_url"), + asset.get("content_type"), + ) + for asset in data.get("assets", []) + } + sha256sum = assets["sha256sum.txt"] + prefix = f"{self.repo}-{version}-" + if platform is not None: + prefix = f"{prefix}{platform}." + exts = [".tar.gz", ".zip"] + filtered = {} + for key, value in assets.items(): + if key[: len(prefix)] != prefix: + continue + cont = True + for ext in exts: + if key[-len(ext) :] == ext: + cont = False + break + if cont: + continue + filtered[key] = value + + if len(filtered) != 1: + return None + + for filename, asset in filtered.items(): + break + + proc = self.gh( + f"/releases/assets/{sha256sum[0]}", + accept="application/octet-stream", + ) + if proc is None: + return None + + sum_lines = proc.stdout.decode("UTF-8").rstrip().split("\n") + sums = {} + for line in sum_lines: + split = line.split(" ", 1) + if len(split) != 2: + continue + digest, file = split + binary = file[:1] == "*" + if binary: + file = file[1:] + sums[file] = (digest, binary) + archive_sum = sums[filename][0] + + proc = self.gh( + f"/releases/assets/{asset[0]}", + accept="application/octet-stream", + ) + if proc is None: + return None + + actual_sum = hashlib.sha256(proc.stdout).hexdigest() + if archive_sum.lower() != actual_sum.lower(): + print( + f"""SHA256 checksum mismatch for file {filename} +Expected: {archive_sum} +Actual: {actual_sum}""", + file=sys.stderr, + ) + return None + + result = os.path.join(rel_dir, filename) + with open(result, "wb") as archive: + archive.write(proc.stdout) + + return os.path.relpath(result, root) + + except subprocess.CalledProcessError as e: + sys.stderr.write(e.stderr.decode("UTF-8")) + sys.exit(e.returncode) diff --git a/apps/tests/driver/__init__.py b/tools/json_tests/driver/__init__.py similarity index 100% rename from apps/tests/driver/__init__.py rename to tools/json_tests/driver/__init__.py diff --git a/apps/tests/driver/commands.py b/tools/json_tests/driver/commands.py similarity index 63% rename from apps/tests/driver/commands.py rename to tools/json_tests/driver/commands.py index a908649f..06634b06 100644 --- a/apps/tests/driver/commands.py +++ b/tools/json_tests/driver/commands.py @@ -5,12 +5,16 @@ import stat import subprocess import sys -import tarfile -import zipfile from typing import Callable, Dict, List, Tuple from . import test +__file_dir__ = os.path.dirname(__file__) +sys.path.append(os.path.dirname(os.path.dirname(__file_dir__))) + +from archives import locate_unpack + + _file_cache = {} _rw_mask = stat.S_IWRITE | stat.S_IWGRP | stat.S_IWOTH _ro_mask = 0o777 ^ _rw_mask @@ -40,44 +44,10 @@ def _make_RW(test: test.Test, args: List[str]): os.chmod(filename, mode) -def _untar(test: test.Test, src, dst): - with tarfile.open(src) as TAR: - - def is_within_directory(directory, target): - abs_directory = os.path.abspath(directory) - abs_target = os.path.abspath(target) - - prefix = os.path.commonprefix([abs_directory, abs_target]) - - return prefix == abs_directory - - def safe_extract(tar, path=".", members=None, *, numeric_owner=False): - for member in tar.getmembers(): - member_path = os.path.join(path, member.name) - if not is_within_directory(path, member_path): - raise Exception("Attempted Path Traversal in Tar File") - - tar.extractall(path, members, numeric_owner=numeric_owner) - - safe_extract(TAR, test.path(dst)) - - -def _unzip(test: test.Test, src, dst): - with zipfile.ZipFile(src) as ZIP: - ZIP.extractall(test.path(dst)) - - -_ARCHIVES = {".tar": _untar, ".zip": _unzip} - - def _unpack(test: test.Test, args: List[str]): archive = args[0] dst = args[1] - reminder, ext = os.path.splitext(archive) - _, mid = os.path.splitext(reminder) - if mid == ".tar": - ext = ".tar" - _ARCHIVES[ext](test, archive, dst) + locate_unpack(archive)[0](archive, test.path(dst)) def _cat(test: test.Test, args: List[str]): diff --git a/apps/tests/driver/test.py b/tools/json_tests/driver/test.py similarity index 100% rename from apps/tests/driver/test.py rename to tools/json_tests/driver/test.py diff --git a/apps/tests/driver/testbed.py b/tools/json_tests/driver/testbed.py similarity index 100% rename from apps/tests/driver/testbed.py rename to tools/json_tests/driver/testbed.py diff --git a/apps/tests/nullify.py b/tools/json_tests/nullify.py similarity index 86% rename from apps/tests/nullify.py rename to tools/json_tests/nullify.py index 55f3e349..53901c25 100755 --- a/apps/tests/nullify.py +++ b/tools/json_tests/nullify.py @@ -8,7 +8,9 @@ from driver.test import Test -__dir__ = os.path.dirname(__file__) +__file_dir__ = os.path.dirname(__file__) +__root_dir__ = os.path.dirname(os.path.dirname(__file_dir__)) +__test_dir__ = os.path.join(__root_dir__, "apps", "tests") parser = argparse.ArgumentParser() parser.add_argument("--tests", required=True, metavar="DIR") @@ -51,7 +53,7 @@ def _load_tests(testsuite: List[str], run: List[str]): def __main__(): args = parser.parse_args() - args.tests = os.path.join(__dir__, args.tests) + args.tests = os.path.join(__test_dir__, args.tests) testsuite = _enum_tests(args) print("tests: ", args.tests) diff --git a/apps/tests/test_runner.py b/tools/json_tests/runner.py similarity index 69% rename from apps/tests/test_runner.py rename to tools/json_tests/runner.py index 2bbb711d..f6c8fc6a 100755 --- a/apps/tests/test_runner.py +++ b/tools/json_tests/runner.py @@ -7,7 +7,9 @@ import subprocess import sys -__dir__ = os.path.dirname(__file__) +__file_dir__ = os.path.dirname(__file__) +__root_dir__ = os.path.dirname(os.path.dirname(__file_dir__)) +__test_dir__ = os.path.join(__root_dir__, "apps", "tests") parser = argparse.ArgumentParser() parser.add_argument("--bin", required=True, metavar="BINDIR") @@ -26,13 +28,13 @@ if not os.path.isdir(args.bin) and os.path.isdir(f"./build/{args.bin}"): args.bin = f"./build/{args.bin}" -if not os.path.isdir(f"{__dir__}/{args.tests}") and os.path.isdir( - f"{__dir__}/main-set/{args.tests}" +if not os.path.isdir(f"{__test_dir__}/{args.tests}") and os.path.isdir( + f"{__test_dir__}/main-set/{args.tests}" ): args.tests = f"main-set/{args.tests}" if args.version is None: - tools = os.path.join(os.path.dirname(os.path.dirname(__dir__)), "tools") + tools = os.path.join(__root_dir__, "tools") print(tools) sys.path.append(tools) from github.cmake import get_version @@ -44,21 +46,23 @@ (f"--{key}", value) for key, value in { "target": f"{args.bin}/bin/cov{ext}", - "tests": f"{__dir__}/{args.tests}", - "data-dir": f"{__dir__}/data", + "tests": f"{__test_dir__}/{args.tests}", + "data-dir": f"{__test_dir__}/data", "version": args.version, - "install": f"{__dir__}/copy", + "install": f"{__test_dir__}/copy", "install-with": f"{args.bin}/elsewhere/libexec/cov/cov-echo{ext}", }.items() ] new_args.extend([("--run", run) for run in args.run]) +print(f"{__file_dir__}/test_driver.py", [item for arg in new_args for item in arg]) + sys.exit( subprocess.run( [ sys.executable, - f"{__dir__}/test_driver.py", + f"{__file_dir__}/test_driver.py", *(item for arg in new_args for item in arg), ], shell=False, diff --git a/apps/tests/test_driver.py b/tools/json_tests/test_driver.py similarity index 95% rename from apps/tests/test_driver.py rename to tools/json_tests/test_driver.py index 53a430cb..7d148d2d 100755 --- a/apps/tests/test_driver.py +++ b/tools/json_tests/test_driver.py @@ -18,11 +18,7 @@ if os.name == "nt": sys.stdout.reconfigure(encoding="utf-8") # type: ignore -try: - os.environ["RUN_LINEAR"] - RUN_LINEAR = True -except KeyError: - RUN_LINEAR = False +RUN_LINEAR = os.environ.get("RUN_LINEAR", 0) != 0 parser = argparse.ArgumentParser() parser.add_argument("--target", required=True, metavar="EXE") @@ -149,6 +145,7 @@ def _install(install: Optional[str], install_with: List[str], env: Env): root_dir = os.path.dirname(os.path.dirname(env.target)) filters_target = os.path.join(install, "additional-filters") + filters_source = os.path.join(os.path.dirname(install), "test-filters") _append("COV_FILTER_PATH", filters_target) _append("COV_PATH", os.path.join(os.path.abspath(root_dir), "dont-copy")) @@ -171,7 +168,6 @@ def _install(install: Optional[str], install_with: List[str], env: Env): dirs_exist_ok=True, ) - filters_source = os.path.join(os.path.dirname(__file__), "test-filters") for _, dirs, files in os.walk(filters_source): dirs[:] = [] for filename in files: @@ -257,9 +253,11 @@ def __main__(): shutil.rmtree(tempdir, ignore_errors=True) else: hw_concurrency = os.cpu_count() - with concurrent.futures.ThreadPoolExecutor( - min(61, max(1, hw_concurrency * 2)) - ) as executor: + try: + thread_count = int(os.environ.get('POOL_SIZE')) + except TypeError: + thread_count = min(61, max(1, hw_concurrency * 2)) + with concurrent.futures.ThreadPoolExecutor(thread_count) as executor: futures = [] for test, counter in independent_tests: futures.append(executor.submit(task, env, test, counter)) From 14b78bdbf5b37315b021639cb578020eb1664664 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 22:10:43 +0200 Subject: [PATCH 06/39] fix: alleviate some crash reasons (human-based) --- libs/cov-api/tests/cov/format/date-test.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/cov-api/tests/cov/format/date-test.cc b/libs/cov-api/tests/cov/format/date-test.cc index ddf3240f..6ecdbcf5 100644 --- a/libs/cov-api/tests/cov/format/date-test.cc +++ b/libs/cov-api/tests/cov/format/date-test.cc @@ -64,6 +64,7 @@ namespace cov::testing { {1250, {300, 299}, {0, 0}, {0, 0}}, {}); ASSERT_TRUE(report); + fmt::print("locale: {}\n", env.locale); auto facade = ph::object_facade::present_report(report, nullptr); auto actual = fmt.format(facade.get(), env); ASSERT_EQ(expected, actual); @@ -82,6 +83,12 @@ namespace cov::testing { static constexpr auto feb29 = sys_days{2000_y / feb / 29} + 12h + 34min + 56s; + // If you'll get locale::facet::_S_create_c_locale name not valid exceptions + // on some of those tests, on Ubuntu: + // ``` + // sudo locale-gen "pl_PL.UTF-8" "en_US.UTF-8" "en_GB.UTF-8" + // ``` + static date_test const tests[] = { #ifndef CUTDOWN_OS { From 39dbb51598beebe98ef256a7e58698ebbdb93785 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 22:07:32 +0200 Subject: [PATCH 07/39] chore: reorganize new code additions --- .covmodules | 1 + CMakeGraphVizOptions.cmake | 1 + CMakeLists.txt | 51 ++------ apps/CMakeLists.txt | 77 +----------- cmake/builtins.cmake | 57 --------- cmake/cov.cmake | 116 ++++++++++++++++++ extensions/CMakeLists.txt | 30 +++++ .../main.cc => extensions/cov_collect.cc | 0 .../filters/strip_excludes.cc | 4 +- extensions/libs/CMakeLists.txt | 5 + extensions/libs/collect-api/CMakeLists.txt | 22 ++++ .../libs/collect-api/src}/gnu.cc | 0 .../libs/collect-api/src}/llvm.cc | 0 .../libs/collect-api/src}/msvc.cc | 0 .../libs/collect-api/src}/queue.hh | 0 .../libs/collect-api/src}/report.cc | 0 .../libs/collect-api/src}/report.hh | 0 .../libs/collect-api/src}/task_watcher.cc | 0 .../libs/collect-api/src}/task_watcher.hh | 0 .../libs/collect-api/src}/thread_pool.cc | 0 .../libs/collect-api/src}/thread_pool.hh | 0 .../libs/collect-api/src}/toolkit.cc | 0 .../libs/collect-api/src}/toolkit.hh | 0 .../libs/collect-api/src}/walk.cc | 0 .../libs/collect-api/src}/walk.hh | 0 extensions/libs/excludes/CMakeLists.txt | 12 ++ .../libs/excludes/src}/excludes.cc | 0 .../libs/excludes/src}/excludes.hh | 0 .../libs/excludes/src}/parser.cc | 0 .../libs/excludes/src}/parser.hh | 0 extensions/libs/native/CMakeLists.txt | 14 +++ .../libs/native/include}/native/platform.hh | 0 .../libs/native/include}/native/str.hh | 0 .../libs/native/src}/platform.cc | 0 external/CMakeLists.txt | 5 + libs/CMakeLists.txt | 2 + libs/app/CMakeLists.txt | 13 +- libs/cov-api/CMakeLists.txt | 55 +++------ libs/cov-rt/CMakeLists.txt | 28 +---- libs/helpers/CMakeLists.txt | 2 + libs/helpers/testing-lib/CMakeLists.txt | 7 +- libs/hilite/CMakeLists.txt | 2 + libs/hilite/hilite-cxx/CMakeLists.txt | 7 +- libs/hilite/hilite/CMakeLists.txt | 7 +- libs/hilite/lighter/CMakeLists.txt | 34 ++--- packages/wix/cpack.cmake | 1 + tools/flow/lib/matrix.py | 6 +- 47 files changed, 280 insertions(+), 279 deletions(-) create mode 100644 cmake/cov.cmake create mode 100644 extensions/CMakeLists.txt rename apps/collect/main.cc => extensions/cov_collect.cc (100%) rename {apps => extensions}/filters/strip_excludes.cc (98%) create mode 100644 extensions/libs/CMakeLists.txt create mode 100644 extensions/libs/collect-api/CMakeLists.txt rename {apps/collect => extensions/libs/collect-api/src}/gnu.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/llvm.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/msvc.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/queue.hh (100%) rename {apps/collect => extensions/libs/collect-api/src}/report.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/report.hh (100%) rename {apps/collect => extensions/libs/collect-api/src}/task_watcher.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/task_watcher.hh (100%) rename {apps/collect => extensions/libs/collect-api/src}/thread_pool.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/thread_pool.hh (100%) rename {apps/collect => extensions/libs/collect-api/src}/toolkit.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/toolkit.hh (100%) rename {apps/collect => extensions/libs/collect-api/src}/walk.cc (100%) rename {apps/collect => extensions/libs/collect-api/src}/walk.hh (100%) create mode 100644 extensions/libs/excludes/CMakeLists.txt rename {apps/filters/native/strip_excludes => extensions/libs/excludes/src}/excludes.cc (100%) rename {apps/filters/native/strip_excludes => extensions/libs/excludes/src}/excludes.hh (100%) rename {apps/filters/native/strip_excludes => extensions/libs/excludes/src}/parser.cc (100%) rename {apps/filters/native/strip_excludes => extensions/libs/excludes/src}/parser.hh (100%) create mode 100644 extensions/libs/native/CMakeLists.txt rename {apps/filters => extensions/libs/native/include}/native/platform.hh (100%) rename {apps/filters => extensions/libs/native/include}/native/str.hh (100%) rename {apps/filters/native => extensions/libs/native/src}/platform.cc (100%) diff --git a/.covmodules b/.covmodules index f4a5986f..d104dfa6 100644 --- a/.covmodules +++ b/.covmodules @@ -13,6 +13,7 @@ path = apps/builtins/ [module "app/ext"] path = apps/collect + path = libs/collect-api [module "app/filters"] path = apps/filters [module "hilite/lighter"] diff --git a/CMakeGraphVizOptions.cmake b/CMakeGraphVizOptions.cmake index b5cf614f..28063e1f 100644 --- a/CMakeGraphVizOptions.cmake +++ b/CMakeGraphVizOptions.cmake @@ -6,4 +6,5 @@ set(GRAPHVIZ_IGNORE_TARGETS "CONAN_LIB::.*" ".*_DEPS_TARGET" ".*-test" cov-echo + cov-pwd ) diff --git a/CMakeLists.txt b/CMakeLists.txt index cda0befa..071908c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ if (COV_TESTING) libs/hilite/lighter libs/app libs/cov-rt + libs/collect-api ) list(APPEND INCLUDED_IN_COVERAGE ${module}/include ${module}/src) endforeach() @@ -179,54 +180,16 @@ set(CORE_ROOT_DIR "../..") message(STATUS "Sanitizer: ${COV_SANITIZE}") +include(cov) + add_subdirectory(external) add_subdirectory(libs) +add_subdirectory(extensions) add_subdirectory(apps) - -if (CMAKE_GENERATOR MATCHES "Visual Studio" AND TARGET cov_coveralls_test) - add_dependencies(cov_coveralls_test - git2-test git2-stress-test - cov-test cov-stress-test - lighter-test lighter-stress-test - cov - ) -endif() - -if (MSVC_VERSION GREATER_EQUAL 1936 AND MSVC_IDE) - foreach (TGT - cov - cov-rt - json - app_main - app - cov-api - date-tz - lighter - hilite-cxx - hilite-py - hilite-ts - hilite - testing-lib - cov-echo - git2-test - git2-stress-test - cov-test - cov-stress-test - cov-rt-test - cov-rt-stress-test - lighter-test - lighter-stress-test - date-tz - json - strip-excludes - cov-collect - ) - if(TARGET ${TGT}) - set_target_properties(${TGT} PROPERTIES VS_USER_PROPS "${PROJECT_SOURCE_DIR}/cmake/VS17.NoModules.props") - endif() - endforeach() -endif() +message(STATUS "COV_TOOLS: ${COV_TOOLS}") +message(STATUS "COV_LIBS: ${COV_LIBS}") +message(STATUS "VS_MODS: ${VS_MODS}") execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/packages/system.py props OUTPUT_VARIABLE COV_PROPERTIES diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index cb4beb31..643d8a15 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -17,10 +17,6 @@ set(REPORT_FILTERS coveralls ) -set(NATIVE_FILTERS - strip-excludes -) - set(SOURCES cov/cov.cc ) @@ -78,13 +74,11 @@ if (WIN32) endif() add_cov_tool(cov ${SOURCES}) -target_compile_options(cov PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(cov PRIVATE ${ADDITIONAL_LINK_FLAGS}) target_include_directories(cov PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/gen ) -target_link_libraries(cov PRIVATE cov-rt) +target_link_libraries(cov PRIVATE cov-rt app_main) set_target_properties(cov PROPERTIES FOLDER apps) ######################################################## @@ -101,67 +95,10 @@ foreach(NAME ${REPORT_FILTERS}) ) endforeach() -foreach(NAME ${NATIVE_FILTERS}) - string(REPLACE "-" "_" SAFE_NAME "${NAME}") - add_cov_tool(${NAME} - filters/${SAFE_NAME}.cc - filters/native/platform.cc - filters/native/platform.hh) - target_compile_options(${NAME} PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(${NAME} PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_include_directories(${NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/filters - ${CMAKE_CURRENT_BINARY_DIR}/gen - ) - set_target_properties(${NAME} PROPERTIES FOLDER apps) - - set_target_properties(${NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" - ) - - foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) - set_target_properties(${NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" - ) - endforeach() -endforeach() - -target_link_libraries(strip-excludes PRIVATE ctre::ctre) -target_sources(strip-excludes PRIVATE - filters/native/strip_excludes/parser.cc - filters/native/strip_excludes/parser.hh - filters/native/strip_excludes/excludes.cc - filters/native/strip_excludes/excludes.hh -) - ######################################################## # add_cov_ext(serve) -add_cov_ext(collect) -target_include_directories(cov-collect PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/collect - ${CMAKE_CURRENT_SOURCE_DIR}/filters -) -target_link_libraries(cov-collect PRIVATE ctre::ctre) -target_sources(cov-collect PRIVATE - collect/gnu.cc - collect/llvm.cc - collect/msvc.cc - collect/queue.hh - collect/report.cc - collect/report.hh - collect/toolkit.cc - collect/toolkit.hh - collect/task_watcher.cc - collect/task_watcher.hh - collect/thread_pool.cc - collect/thread_pool.hh - collect/walk.cc - collect/walk.hh -) - print_cov_ext() ######################################################## @@ -170,15 +107,11 @@ if (COV_TESTING) enable_testing() add_cov_tool(cov-echo tests/cov-echo.cc) - target_compile_options(cov-echo PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-echo PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_link_libraries(cov-echo PRIVATE fmt::fmt mbits::args) + target_link_libraries(cov-echo PRIVATE app_main fmt::fmt mbits::args) set_target_properties(cov-echo PROPERTIES FOLDER tests/spawn) add_cov_tool(cov-pwd tests/cov-pwd.cc) - target_compile_options(cov-pwd PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-pwd PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_link_libraries(cov-pwd PRIVATE fmt::fmt mbits::args) + target_link_libraries(cov-pwd PRIVATE app_main fmt::fmt mbits::args) set_target_properties(cov-pwd PROPERTIES FOLDER tests/spawn) set_target_properties(cov-echo PROPERTIES @@ -232,7 +165,7 @@ if (COV_TESTING) if (CMAKE_GENERATOR MATCHES "Visual Studio" AND TARGET cov_coveralls_test) add_dependencies(cov_coveralls_test - cov-echo + cov cov-echo cov-pwd ) endif() endif() @@ -263,3 +196,5 @@ cpack_add_component_group(apps DISPLAY_NAME "Executables" EXPANDED ) + +set_parent_scope() diff --git a/cmake/builtins.cmake b/cmake/builtins.cmake index 6e6056da..1418444e 100644 --- a/cmake/builtins.cmake +++ b/cmake/builtins.cmake @@ -37,60 +37,3 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gen/cov/builtins.hh CONTENT ${__content} ) - -function(add_cov_tool TARGET) - cmake_parse_arguments(PARSE_ARGV 1 COV "" "" "") - add_executable(${TARGET} ${COV_UNPARSED_ARGUMENTS}) - target_link_libraries(${TARGET} PRIVATE app_main) - if (WIN32) - target_link_options(${TARGET} PRIVATE /ENTRY:wmainCRTStartup) - endif() -endfunction() - -set(CORE_EXT) - -function(setup_cov_ext COV_TOOL) - set(__CORE ${CORE_EXT} ${COV_TOOL}) - set(CORE_EXT ${__CORE} PARENT_SCOPE) - - set_target_properties(cov-${COV_TOOL} PROPERTIES FOLDER apps/core) - target_link_options(cov-${COV_TOOL} PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_compile_options(cov-${COV_TOOL} PRIVATE ${ADDITIONAL_WALL_FLAGS}) - - set_target_properties(cov-${COV_TOOL} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CORE_DIR}" - ) - - foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) - set_target_properties(cov-${COV_TOOL} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/${CORE_DIR}" - ) - endforeach() -endfunction() - -macro(add_cov_ext COV_TOOL) - string(REPLACE "-" "_" __COV_TOOL_SAFE_NAME "${COV_TOOL}") - if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cov_${__COV_TOOL_SAFE_NAME}.cc) - set(${COV_TOOL}_CODE cov_${__COV_TOOL_SAFE_NAME}.cc) - elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/main.cc) - set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/main.cc) - elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) - set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) - else() - message(FATAL_ERROR "Cannot find code for ${COV_TOOL}'s tool()") - endif() - add_cov_tool(cov-${COV_TOOL} ${${COV_TOOL}_CODE}) - source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES cov-${COV_TOOL}.cc) - - setup_cov_ext(${COV_TOOL}) - install(TARGETS cov-${COV_TOOL} - RUNTIME DESTINATION ${CORE_DIR} - COMPONENT tools - ) -endmacro() - -function(print_cov_ext) - set(__CORE ${CORE_EXT}) - string(REPLACE ";" ", " CORE_LIST "${CORE_EXT}") - message(STATUS "Core extensions: ${CORE_LIST}") -endfunction() diff --git a/cmake/cov.cmake b/cmake/cov.cmake new file mode 100644 index 00000000..699a34aa --- /dev/null +++ b/cmake/cov.cmake @@ -0,0 +1,116 @@ +function(fix_vs_modules TARGET) + set(__TOOLS ${VS_MODS} ${TARGET}) + set(VS_MODS ${__TOOLS} PARENT_SCOPE) + + if (MSVC_VERSION GREATER_EQUAL 1936 AND MSVC_IDE) + set_target_properties(${TARGET} PROPERTIES VS_USER_PROPS "${PROJECT_SOURCE_DIR}/cmake/VS17.NoModules.props") + endif() +endfunction() + +set(COV_LIBS) +set(COV_TOOLS) +set(VS_MODS) + +function(add_cov_tool TARGET) + set(__TOOLS ${COV_TOOLS} ${TARGET}) + set(COV_TOOLS ${__TOOLS} PARENT_SCOPE) + + cmake_parse_arguments(PARSE_ARGV 1 COV "" "" "") + add_executable(${TARGET} ${COV_UNPARSED_ARGUMENTS}) + target_compile_options(${TARGET} PRIVATE ${ADDITIONAL_WALL_FLAGS}) + target_link_options(${TARGET} PRIVATE ${ADDITIONAL_LINK_FLAGS}) + if (WIN32) + target_link_options(${TARGET} PRIVATE /ENTRY:wmainCRTStartup) + fix_vs_modules(${TARGET}) + set(VS_MODS ${VS_MODS} PARENT_SCOPE) + endif() +endfunction() + +function(add_cov_library TARGET) + set(__LIBS ${COV_LIBS} ${TARGET}) + set(COV_LIBS ${__LIBS} PARENT_SCOPE) + + cmake_parse_arguments(PARSE_ARGV 1 COV "" "" "") + add_library(${TARGET} STATIC ${COV_UNPARSED_ARGUMENTS}) + target_compile_options(${TARGET} PRIVATE ${ADDITIONAL_WALL_FLAGS}) + target_link_options(${TARGET} PRIVATE ${ADDITIONAL_LINK_FLAGS}) + fix_vs_modules(${TARGET}) + set(VS_MODS ${VS_MODS} PARENT_SCOPE) + if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include") + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include) + elseif (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src") + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src) + endif() +endfunction() + +set(CORE_EXT) + +function(setup_cov_ext COV_TOOL) + set(__CORE ${CORE_EXT} ${COV_TOOL}) + set(CORE_EXT ${__CORE} PARENT_SCOPE) + + set_target_properties(cov-${COV_TOOL} PROPERTIES FOLDER apps/core) + target_link_options(cov-${COV_TOOL} PRIVATE ${ADDITIONAL_LINK_FLAGS}) + target_compile_options(cov-${COV_TOOL} PRIVATE ${ADDITIONAL_WALL_FLAGS}) + + set_target_properties(cov-${COV_TOOL} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CORE_DIR}" + ) + + foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set_target_properties(cov-${COV_TOOL} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/${CORE_DIR}" + ) + endforeach() +endfunction() + +macro(add_cov_ext COV_TOOL) + string(REPLACE "-" "_" __COV_TOOL_SAFE_NAME "${COV_TOOL}") + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cov_${__COV_TOOL_SAFE_NAME}.cc) + set(${COV_TOOL}_CODE cov_${__COV_TOOL_SAFE_NAME}.cc) + elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/main.cc) + set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/main.cc) + elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) + set(${COV_TOOL}_CODE ${__COV_TOOL_SAFE_NAME}/${__COV_TOOL_SAFE_NAME}.cc) + else() + message(FATAL_ERROR "Cannot find code for ${COV_TOOL}'s tool() function") + endif() + add_cov_tool(cov-${COV_TOOL} ${${COV_TOOL}_CODE}) + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${${COV_TOOL}_CODE}) + + setup_cov_ext(${COV_TOOL}) + install(TARGETS cov-${COV_TOOL} + RUNTIME DESTINATION ${CORE_DIR} + COMPONENT tools + ) +endmacro() + +function(print_cov_ext) + set(__CORE ${CORE_EXT}) + string(REPLACE ";" ", " CORE_LIST "${CORE_EXT}") + message(STATUS "Core extensions: ${CORE_LIST}") +endfunction() + +function(add_cov_test TARGET) + cmake_parse_arguments(PARSE_ARGV 1 COV "" "" "") + add_executable(${TARGET}-test ${COV_UNPARSED_ARGUMENTS}) + set_target_properties(${TARGET}-test PROPERTIES FOLDER tests) + target_compile_options(${TARGET}-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) + target_link_options(${TARGET}-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) + target_include_directories(${TARGET}-test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/tests + ${CMAKE_CURRENT_BINARY_DIR}) + fix_vs_modules(${TARGET}-test) + set(VS_MODS ${VS_MODS} PARENT_SCOPE) +endfunction() + +macro(set_parent_scope) + set(CORE_EXT ${CORE_EXT} PARENT_SCOPE) + set(COV_LIBS ${COV_LIBS} PARENT_SCOPE) + set(COV_TOOLS ${COV_TOOLS} PARENT_SCOPE) + set(VS_MODS ${VS_MODS} PARENT_SCOPE) +endmacro() diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt new file mode 100644 index 00000000..9a99591f --- /dev/null +++ b/extensions/CMakeLists.txt @@ -0,0 +1,30 @@ +add_subdirectory(libs) + +set(NATIVE_FILTERS + strip-excludes +) + +set(NATIVE_FILTERS ${NATIVE_FILTERS} PARENT_SCOPE) + +foreach(NAME ${NATIVE_FILTERS}) + string(REPLACE "-" "_" SAFE_NAME "${NAME}") + add_cov_tool(${NAME} filters/${SAFE_NAME}.cc) + set_target_properties(${NAME} PROPERTIES FOLDER apps) + + set_target_properties(${NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" + ) + + foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set_target_properties(${NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/${SHARE_DIR}/filters" + ) + endforeach() +endforeach() + +target_link_libraries(strip-excludes PRIVATE excludes) + +add_cov_ext(collect) +target_link_libraries(cov-collect PRIVATE collect-api) + +set_parent_scope() diff --git a/apps/collect/main.cc b/extensions/cov_collect.cc similarity index 100% rename from apps/collect/main.cc rename to extensions/cov_collect.cc diff --git a/apps/filters/strip_excludes.cc b/extensions/filters/strip_excludes.cc similarity index 98% rename from apps/filters/strip_excludes.cc rename to extensions/filters/strip_excludes.cc index 4641156f..7620ac14 100644 --- a/apps/filters/strip_excludes.cc +++ b/extensions/filters/strip_excludes.cc @@ -11,12 +11,12 @@ #include #include #include +#include #include #include #include -#include -#include #include +#include #include #include #include diff --git a/extensions/libs/CMakeLists.txt b/extensions/libs/CMakeLists.txt new file mode 100644 index 00000000..b3bf543c --- /dev/null +++ b/extensions/libs/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(native) +add_subdirectory(collect-api) +add_subdirectory(excludes) + +set_parent_scope() diff --git a/extensions/libs/collect-api/CMakeLists.txt b/extensions/libs/collect-api/CMakeLists.txt new file mode 100644 index 00000000..62d91718 --- /dev/null +++ b/extensions/libs/collect-api/CMakeLists.txt @@ -0,0 +1,22 @@ +set(SOURCES + src/gnu.cc + src/llvm.cc + src/msvc.cc + src/queue.hh + src/report.cc + src/report.hh + src/toolkit.cc + src/toolkit.hh + src/task_watcher.cc + src/task_watcher.hh + src/thread_pool.cc + src/thread_pool.hh + src/walk.cc + src/walk.hh +) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) + +add_cov_library(collect-api ${SOURCES}) +target_link_libraries(collect-api PUBLIC ext_native) + +set_parent_scope() diff --git a/apps/collect/gnu.cc b/extensions/libs/collect-api/src/gnu.cc similarity index 100% rename from apps/collect/gnu.cc rename to extensions/libs/collect-api/src/gnu.cc diff --git a/apps/collect/llvm.cc b/extensions/libs/collect-api/src/llvm.cc similarity index 100% rename from apps/collect/llvm.cc rename to extensions/libs/collect-api/src/llvm.cc diff --git a/apps/collect/msvc.cc b/extensions/libs/collect-api/src/msvc.cc similarity index 100% rename from apps/collect/msvc.cc rename to extensions/libs/collect-api/src/msvc.cc diff --git a/apps/collect/queue.hh b/extensions/libs/collect-api/src/queue.hh similarity index 100% rename from apps/collect/queue.hh rename to extensions/libs/collect-api/src/queue.hh diff --git a/apps/collect/report.cc b/extensions/libs/collect-api/src/report.cc similarity index 100% rename from apps/collect/report.cc rename to extensions/libs/collect-api/src/report.cc diff --git a/apps/collect/report.hh b/extensions/libs/collect-api/src/report.hh similarity index 100% rename from apps/collect/report.hh rename to extensions/libs/collect-api/src/report.hh diff --git a/apps/collect/task_watcher.cc b/extensions/libs/collect-api/src/task_watcher.cc similarity index 100% rename from apps/collect/task_watcher.cc rename to extensions/libs/collect-api/src/task_watcher.cc diff --git a/apps/collect/task_watcher.hh b/extensions/libs/collect-api/src/task_watcher.hh similarity index 100% rename from apps/collect/task_watcher.hh rename to extensions/libs/collect-api/src/task_watcher.hh diff --git a/apps/collect/thread_pool.cc b/extensions/libs/collect-api/src/thread_pool.cc similarity index 100% rename from apps/collect/thread_pool.cc rename to extensions/libs/collect-api/src/thread_pool.cc diff --git a/apps/collect/thread_pool.hh b/extensions/libs/collect-api/src/thread_pool.hh similarity index 100% rename from apps/collect/thread_pool.hh rename to extensions/libs/collect-api/src/thread_pool.hh diff --git a/apps/collect/toolkit.cc b/extensions/libs/collect-api/src/toolkit.cc similarity index 100% rename from apps/collect/toolkit.cc rename to extensions/libs/collect-api/src/toolkit.cc diff --git a/apps/collect/toolkit.hh b/extensions/libs/collect-api/src/toolkit.hh similarity index 100% rename from apps/collect/toolkit.hh rename to extensions/libs/collect-api/src/toolkit.hh diff --git a/apps/collect/walk.cc b/extensions/libs/collect-api/src/walk.cc similarity index 100% rename from apps/collect/walk.cc rename to extensions/libs/collect-api/src/walk.cc diff --git a/apps/collect/walk.hh b/extensions/libs/collect-api/src/walk.hh similarity index 100% rename from apps/collect/walk.hh rename to extensions/libs/collect-api/src/walk.hh diff --git a/extensions/libs/excludes/CMakeLists.txt b/extensions/libs/excludes/CMakeLists.txt new file mode 100644 index 00000000..5fe36f11 --- /dev/null +++ b/extensions/libs/excludes/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SOURCES + src/excludes.cc + src/excludes.hh + src/parser.cc + src/parser.hh +) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) + +add_cov_library(excludes ${SOURCES}) +target_link_libraries(excludes PUBLIC ext_native) + +set_parent_scope() diff --git a/apps/filters/native/strip_excludes/excludes.cc b/extensions/libs/excludes/src/excludes.cc similarity index 100% rename from apps/filters/native/strip_excludes/excludes.cc rename to extensions/libs/excludes/src/excludes.cc diff --git a/apps/filters/native/strip_excludes/excludes.hh b/extensions/libs/excludes/src/excludes.hh similarity index 100% rename from apps/filters/native/strip_excludes/excludes.hh rename to extensions/libs/excludes/src/excludes.hh diff --git a/apps/filters/native/strip_excludes/parser.cc b/extensions/libs/excludes/src/parser.cc similarity index 100% rename from apps/filters/native/strip_excludes/parser.cc rename to extensions/libs/excludes/src/parser.cc diff --git a/apps/filters/native/strip_excludes/parser.hh b/extensions/libs/excludes/src/parser.hh similarity index 100% rename from apps/filters/native/strip_excludes/parser.hh rename to extensions/libs/excludes/src/parser.hh diff --git a/extensions/libs/native/CMakeLists.txt b/extensions/libs/native/CMakeLists.txt new file mode 100644 index 00000000..769adc0e --- /dev/null +++ b/extensions/libs/native/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SOURCES + src/platform.cc + include/native/platform.hh + include/native/str.hh +) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) + +add_cov_library(ext_native ${SOURCES}) +target_include_directories(ext_native PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/include/native +) +target_link_libraries(ext_native PUBLIC ctre::ctre app_main) + +set_parent_scope() diff --git a/apps/filters/native/platform.hh b/extensions/libs/native/include/native/platform.hh similarity index 100% rename from apps/filters/native/platform.hh rename to extensions/libs/native/include/native/platform.hh diff --git a/apps/filters/native/str.hh b/extensions/libs/native/include/native/str.hh similarity index 100% rename from apps/filters/native/str.hh rename to extensions/libs/native/include/native/str.hh diff --git a/apps/filters/native/platform.cc b/extensions/libs/native/src/platform.cc similarity index 100% rename from apps/filters/native/platform.cc rename to extensions/libs/native/src/platform.cc diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index f813e044..6ccc80fa 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -7,3 +7,8 @@ add_subdirectory(date) add_subdirectory(json) set_target_properties(json PROPERTIES FOLDER libs) + +fix_vs_modules(date-tz) +fix_vs_modules(json) + +set_parent_scope() diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 510d5116..5535bf47 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -8,3 +8,5 @@ add_subdirectory(hilite) add_subdirectory(cov-api) add_subdirectory(app) add_subdirectory(cov-rt) + +set_parent_scope() diff --git a/libs/app/CMakeLists.txt b/libs/app/CMakeLists.txt index 6990e793..b2bd2bdf 100644 --- a/libs/app/CMakeLists.txt +++ b/libs/app/CMakeLists.txt @@ -64,17 +64,10 @@ source_group(TREE ${CMAKE_CURRENT_BINARY_DIR} FILES ${GEN_SOURCES} PREFIX gen) source_group(TREE "${PROJECT_BINARY_DIR}/${SHARE_DIR}" FILES ${SHARE_SOURCES} PREFIX gen/share) source_group(TREE ${DATA_DIR} FILES ${DATA_SOURCES} PREFIX data) -add_library(app STATIC ${SOURCES} ${GEN_SOURCES} ${SHARE_SOURCES} ${DATA_SOURCES}) -target_compile_options(app PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(app PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(app PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include) +add_cov_library(app ${SOURCES} ${GEN_SOURCES} ${SHARE_SOURCES} ${DATA_SOURCES}) target_link_libraries(app PUBLIC cov-api lighter mbits::liblngs mbits::args) -add_library(app_main STATIC src/main.cc) -target_compile_options(app_main PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(app_main PRIVATE ${ADDITIONAL_LINK_FLAGS}) +add_cov_library(app_main src/main.cc) target_link_libraries(app_main PUBLIC app) if (WIN32) @@ -153,3 +146,5 @@ cpack_add_component(libapp DISPLAY_NAME "libapp" GROUP devel ) + +set_parent_scope() diff --git a/libs/cov-api/CMakeLists.txt b/libs/cov-api/CMakeLists.txt index fd3c4bef..d14f08ae 100644 --- a/libs/cov-api/CMakeLists.txt +++ b/libs/cov-api/CMakeLists.txt @@ -106,12 +106,7 @@ set(COV_SOURCES ) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${GIT2_SOURCES} ${COV_SOURCES}) -add_library(cov-api STATIC ${GIT2_SOURCES} ${COV_SOURCES}) -target_compile_options(cov-api PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(cov-api PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(cov-api PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include) +add_cov_library(cov-api ${GIT2_SOURCES} ${COV_SOURCES}) target_link_libraries(cov-api PUBLIC libgit2::libgit2 fmt::fmt date::date-tz mbits::args json PRIVATE hilite openssl::openssl) set_target_properties(cov-api PROPERTIES FOLDER libs) @@ -139,45 +134,18 @@ if (COV_TESTING) ${COV_TEST_SRCS_CXX} ${COV_STRESS_TEST_SRCS_CC}) - add_executable(git2-test ${GIT2_TEST_SRCS_CC} ${GIT2_TEST_SRCS_CPP} ${GIT2_TEST_SRCS_CXX}) - add_executable(git2-stress-test ${GIT2_STRESS_TEST_SRCS_CC} tests/git2-c++/setup.cc) - add_executable(cov-test ${COV_TEST_SRCS_CC} ${COV_TEST_SRCS_CPP} ${COV_TEST_SRCS_CXX}) - add_executable(cov-stress-test ${COV_STRESS_TEST_SRCS_CC} tests/cov/setup.cc tests/git2-c++/stress/new.cc) + add_cov_test(git2 ${GIT2_TEST_SRCS_CC} ${GIT2_TEST_SRCS_CPP} ${GIT2_TEST_SRCS_CXX}) + add_cov_test(git2-stress ${GIT2_STRESS_TEST_SRCS_CC} tests/git2-c++/setup.cc) + add_cov_test(cov ${COV_TEST_SRCS_CC} ${COV_TEST_SRCS_CPP} ${COV_TEST_SRCS_CXX}) + add_cov_test(cov-stress ${COV_STRESS_TEST_SRCS_CC} tests/cov/setup.cc tests/git2-c++/stress/new.cc) - set_target_properties(git2-test git2-stress-test cov-test cov-stress-test PROPERTIES FOLDER tests) - - target_compile_options(git2-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(git2-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) target_link_libraries(git2-test PRIVATE cov-api testing-lib) - target_include_directories(git2-test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_BINARY_DIR}) - - target_compile_options(git2-stress-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(git2-stress-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) target_link_libraries(git2-stress-test PRIVATE cov-api testing-lib) - target_include_directories(git2-stress-test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_BINARY_DIR}) - - target_compile_options(cov-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_link_libraries(cov-test PRIVATE cov-api testing-lib mbits::args) - target_include_directories(cov-test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_BINARY_DIR}) - - target_compile_options(cov-stress-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-stress-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) + target_link_libraries(cov-test PRIVATE cov-api mbits::args testing-lib) target_link_libraries(cov-stress-test PRIVATE cov-api testing-lib) target_include_directories(cov-stress-test PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_SOURCE_DIR}/../cov-api/tests/git2-c++/stress - ${CMAKE_CURRENT_BINARY_DIR}) + ${CMAKE_CURRENT_SOURCE_DIR}/tests/git2-c++/stress) if (COV_CUTDOWN_OS) message(STATUS "cov-api tests: removing some tests on cutdown OS") @@ -191,6 +159,13 @@ if (COV_TESTING) add_test(NAME git2-stress COMMAND git2-stress-test "--gtest_output=xml:${TEST_REPORT_DIR}/libgit2-c++-stress/${TEST_REPORT_FILE}") add_test(NAME cov COMMAND cov-test "--gtest_output=xml:${TEST_REPORT_DIR}/libcov/${TEST_REPORT_FILE}") add_test(NAME cov-stress COMMAND cov-stress-test "--gtest_output=xml:${TEST_REPORT_DIR}/libcov-stress/${TEST_REPORT_FILE}") + + if (CMAKE_GENERATOR MATCHES "Visual Studio" AND TARGET cov_coveralls_test) + add_dependencies(cov_coveralls_test + git2-test git2-stress-test + cov-test cov-stress-test + ) + endif() endif() install( @@ -209,3 +184,5 @@ cpack_add_component(libcov DEPENDS lighter GROUP devel ) + +set_parent_scope() diff --git a/libs/cov-rt/CMakeLists.txt b/libs/cov-rt/CMakeLists.txt index ad396d84..694accb9 100644 --- a/libs/cov-rt/CMakeLists.txt +++ b/libs/cov-rt/CMakeLists.txt @@ -38,12 +38,7 @@ set(SOURCES source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) -add_library(cov-rt STATIC ${SOURCES}) -target_compile_options(cov-rt PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(cov-rt PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(cov-rt PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include) +add_cov_library(cov-rt ${SOURCES}) target_link_libraries(cov-rt PUBLIC app) set_target_properties(cov-rt PROPERTIES FOLDER libs) @@ -70,27 +65,14 @@ if (COV_TESTING) ${STRESS_TEST_SRCS_CC} ) - add_executable(cov-rt-test ${TEST_SRCS_CC} ${TEST_SRCS_CPP} ${TEST_SRCS_CXX}) - add_executable(cov-rt-stress-test ${STRESS_TEST_SRCS_CC} tests/setup.cc ../cov-api/tests/git2-c++/stress/new.cc) + add_cov_test(cov-rt ${TEST_SRCS_CC} ${TEST_SRCS_CPP} ${TEST_SRCS_CXX}) + add_cov_test(cov-rt-stress ${STRESS_TEST_SRCS_CC} tests/setup.cc ../cov-api/tests/git2-c++/stress/new.cc) - set_target_properties(cov-rt-test cov-rt-stress-test PROPERTIES FOLDER tests) - - target_compile_options(cov-rt-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-rt-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) target_link_libraries(cov-rt-test PRIVATE cov-rt testing-lib) - target_include_directories(cov-rt-test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_BINARY_DIR}) - - target_compile_options(cov-rt-stress-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(cov-rt-stress-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) target_link_libraries(cov-rt-stress-test PRIVATE cov-rt testing-lib) target_include_directories(cov-rt-stress-test PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_SOURCE_DIR}/../cov-api/tests/git2-c++/stress - ${CMAKE_CURRENT_BINARY_DIR}) + ${CMAKE_CURRENT_SOURCE_DIR}/../cov-api/tests/git2-c++/stress) add_test(NAME cov-rt COMMAND cov-rt-test "--gtest_output=xml:${TEST_REPORT_DIR}/libcov-rt/${TEST_REPORT_FILE}") add_test(NAME cov-rt-stress COMMAND cov-rt-stress-test "--gtest_output=xml:${TEST_REPORT_DIR}/libcov-rt-stress/${TEST_REPORT_FILE}") @@ -117,3 +99,5 @@ cpack_add_component(librt DISPLAY_NAME "libcov-rt" GROUP devel ) + +set_parent_scope() diff --git a/libs/helpers/CMakeLists.txt b/libs/helpers/CMakeLists.txt index b2966f48..5f2d29de 100644 --- a/libs/helpers/CMakeLists.txt +++ b/libs/helpers/CMakeLists.txt @@ -1 +1,3 @@ add_subdirectory(testing-lib) + +set_parent_scope() diff --git a/libs/helpers/testing-lib/CMakeLists.txt b/libs/helpers/testing-lib/CMakeLists.txt index 9cc44cae..03fe6cf7 100644 --- a/libs/helpers/testing-lib/CMakeLists.txt +++ b/libs/helpers/testing-lib/CMakeLists.txt @@ -7,10 +7,9 @@ if (COV_TESTING) ) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) - add_library(testing-lib STATIC ${SOURCES}) - target_compile_options(testing-lib PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(testing-lib PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_include_directories(testing-lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + add_cov_library(testing-lib ${SOURCES}) target_link_libraries(testing-lib PUBLIC GTest::gmock_main fmt::fmt) set_target_properties(testing-lib PROPERTIES FOLDER tests/libs) endif() + +set_parent_scope() diff --git a/libs/hilite/CMakeLists.txt b/libs/hilite/CMakeLists.txt index 97cae336..314a4cfb 100644 --- a/libs/hilite/CMakeLists.txt +++ b/libs/hilite/CMakeLists.txt @@ -8,3 +8,5 @@ add_subdirectory(hilite-cxx) add_subdirectory(hilite-py3) add_subdirectory(hilite-ts) add_subdirectory(lighter) + +set_parent_scope() diff --git a/libs/hilite/hilite-cxx/CMakeLists.txt b/libs/hilite/hilite-cxx/CMakeLists.txt index 59d206b2..f830c327 100644 --- a/libs/hilite/hilite-cxx/CMakeLists.txt +++ b/libs/hilite/hilite-cxx/CMakeLists.txt @@ -4,10 +4,7 @@ set(SOURCES ) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) -add_library(hilite-cxx STATIC ${SOURCES}) -target_compile_options(hilite-cxx PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(hilite-cxx PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(hilite-cxx PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +add_cov_library(hilite-cxx ${SOURCES}) target_link_libraries(hilite-cxx PUBLIC hilite) set_target_properties(hilite-cxx PROPERTIES FOLDER libs/hilite) @@ -28,3 +25,5 @@ cpack_add_component(hilite_cxx GROUP devel HIDDEN ) + +set_parent_scope() diff --git a/libs/hilite/hilite/CMakeLists.txt b/libs/hilite/hilite/CMakeLists.txt index 0a608892..37980c54 100644 --- a/libs/hilite/hilite/CMakeLists.txt +++ b/libs/hilite/hilite/CMakeLists.txt @@ -24,10 +24,7 @@ set(SOURCES ) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) -add_library(hilite STATIC ${SOURCES}) -target_compile_options(hilite PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(hilite PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(hilite PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +add_cov_library(hilite ${SOURCES}) set_target_properties(hilite PROPERTIES FOLDER libs/hilite) install( @@ -45,3 +42,5 @@ cpack_add_component(hilite DISPLAY_NAME "libhilite" GROUP devel ) + +set_parent_scope() diff --git a/libs/hilite/lighter/CMakeLists.txt b/libs/hilite/lighter/CMakeLists.txt index 0f0d0d55..96b28168 100644 --- a/libs/hilite/lighter/CMakeLists.txt +++ b/libs/hilite/lighter/CMakeLists.txt @@ -18,10 +18,7 @@ string(REPLACE ";" ", " DEP_LIST "${DEPS}") endif() -add_library(lighter STATIC ${SOURCES}) -target_compile_options(lighter PRIVATE ${ADDITIONAL_WALL_FLAGS}) -target_link_options(lighter PRIVATE ${ADDITIONAL_LINK_FLAGS}) -target_include_directories(lighter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +add_cov_library(lighter ${SOURCES}) target_link_libraries(lighter PUBLIC ${DEPS}) set_target_properties(lighter PROPERTIES FOLDER libs/hilite) @@ -38,31 +35,24 @@ if (COV_TESTING) ${TEST_SRCS_CXX} ${STRESS_TEST_SRCS_CC}) - add_executable(lighter-test ${TEST_SRCS_CC} ${TEST_SRCS_CPP} ${TEST_SRCS_CXX}) - add_executable(lighter-stress-test ${STRESS_TEST_SRCS_CC} + add_cov_test(lighter ${TEST_SRCS_CC} ${TEST_SRCS_CPP} ${TEST_SRCS_CXX}) + add_cov_test(lighter-stress ${STRESS_TEST_SRCS_CC} ../../cov-api/tests/git2-c++/stress/new.cc) - set_target_properties(lighter-test lighter-stress-test PROPERTIES FOLDER tests) - - target_compile_options(lighter-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(lighter-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) - target_link_libraries(lighter-test lighter GTest::gmock_main fmt::fmt) - target_include_directories(lighter-test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_BINARY_DIR}) - - target_compile_options(lighter-stress-test PRIVATE ${ADDITIONAL_WALL_FLAGS}) - target_link_options(lighter-stress-test PRIVATE ${ADDITIONAL_LINK_FLAGS}) + target_link_libraries(lighter-test PRIVATE lighter GTest::gmock_main fmt::fmt) target_link_libraries(lighter-stress-test PRIVATE lighter GTest::gmock_main) target_include_directories(lighter-stress-test PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ${CMAKE_CURRENT_SOURCE_DIR}/../../cov-api/tests/git2-c++/stress - ${CMAKE_CURRENT_BINARY_DIR}) + ${CMAKE_CURRENT_SOURCE_DIR}/../../cov-api/tests/git2-c++/stress) add_test(NAME lighter COMMAND lighter-test "--gtest_output=xml:${TEST_REPORT_DIR}/liblighter/${TEST_REPORT_FILE}") add_test(NAME lighter-stress COMMAND lighter-stress-test "--gtest_output=xml:${TEST_REPORT_DIR}/liblighter-stress/${TEST_REPORT_FILE}") + + if (CMAKE_GENERATOR MATCHES "Visual Studio" AND TARGET cov_coveralls_test) + add_dependencies(cov_coveralls_test + lighter-test lighter-stress-test + ) + endif() endif() install( @@ -88,3 +78,5 @@ cpack_add_component(lighter DEPENDS ${_DEPS} GROUP devel ) + +set_parent_scope() diff --git a/packages/wix/cpack.cmake b/packages/wix/cpack.cmake index ec0a7936..e3bb7d1d 100644 --- a/packages/wix/cpack.cmake +++ b/packages/wix/cpack.cmake @@ -7,6 +7,7 @@ list(REMOVE_ITEM CPACK_COMPONENTS_ALL hilite hilite_cxx lighter + libexts ) foreach(COMP ${CPACK_COMPONENTS_ALL}) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 3fd791e8..4f228336 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -353,13 +353,15 @@ def test(config: dict): has_coverage = config.get("coverage") uses_occ = config.get("os") == "windows" cov_exe = None + env = {} + if not uses_occ: env["POOL_SIZE"] = "1" if has_coverage and not uses_occ: cov_exe = steps.get_bin(_collect_version, config) if cov_exe is not None: runner.call(cov_exe, "collect", "--clean") runner.call( - cov_exe, "collect", "--observe", "ctest", "--preset", config["preset"] + cov_exe, "collect", "--observe", "ctest", "--preset", config["preset"], env=env ) runner.call(cov_exe, "collect") # todo: report coverage to github, somehow @@ -372,7 +374,7 @@ def test(config: dict): "--preset", config["preset"], "--target", - "cov_coveralls", + "cov_coveralls", env=env, ) if runner.GITHUB_ANNOTATE: From 8a362c9639bd6a382f004a58a009d272e179de7f Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 22:34:35 +0200 Subject: [PATCH 08/39] ci: run language tests on Ubuntu --- .github/workflows/build.yml | 1 + libs/cov-api/tests/cov/format/date-test.cc | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 275cb542..cd249f1f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,6 +73,7 @@ jobs: sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 90 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-12 90 sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 90 + sudo locale-gen pl_PL.UTF-8 en_US.UTF-8 en_GB.UTF-8 - name: Set up Clang if: ${{ matrix.clang }} diff --git a/libs/cov-api/tests/cov/format/date-test.cc b/libs/cov-api/tests/cov/format/date-test.cc index 6ecdbcf5..f661dcf0 100644 --- a/libs/cov-api/tests/cov/format/date-test.cc +++ b/libs/cov-api/tests/cov/format/date-test.cc @@ -90,7 +90,7 @@ namespace cov::testing { // ``` static date_test const tests[] = { -#ifndef CUTDOWN_OS +#if !defined(_WIN32) || !defined(CUTDOWN_OS) { "Date in Poland/Polish"sv, "%rd"sv, @@ -115,7 +115,7 @@ namespace cov::testing { .time_zone = "Europe/Warsaw"sv, .locale = "en_GB.UTF-8"sv}, }, -#endif // CUTDOWN_OS +#endif // !_WIN32 || !CUTDOWN_OS { "Date in Poland/US English"sv, "%rd"sv, @@ -128,7 +128,7 @@ namespace cov::testing { .time_zone = "Europe/Warsaw"sv, .locale = "en_US.UTF-8"sv}, }, -#ifndef CUTDOWN_OS +#if !defined(_WIN32) || !defined(CUTDOWN_OS) { "Date in Labrador/Polish"sv, "%rd"sv, @@ -153,7 +153,7 @@ namespace cov::testing { .time_zone = "America/St_Johns"sv, .locale = "en_GB.UTF-8"sv}, }, -#endif // CUTDOWN_OS +#endif // !_WIN32 || !CUTDOWN_OS { "Date in Labrador/US English"sv, "%rd"sv, From 062741eec8e7da2c32a32c0974b785f5c3bcbc0e Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Fri, 28 Jul 2023 22:53:13 +0200 Subject: [PATCH 09/39] fixup! chore: reorganize new code additions --- tools/flow/lib/matrix.py | 6 ++---- tools/json_tests/test_driver.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 4f228336..3fd791e8 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -353,15 +353,13 @@ def test(config: dict): has_coverage = config.get("coverage") uses_occ = config.get("os") == "windows" cov_exe = None - env = {} - if not uses_occ: env["POOL_SIZE"] = "1" if has_coverage and not uses_occ: cov_exe = steps.get_bin(_collect_version, config) if cov_exe is not None: runner.call(cov_exe, "collect", "--clean") runner.call( - cov_exe, "collect", "--observe", "ctest", "--preset", config["preset"], env=env + cov_exe, "collect", "--observe", "ctest", "--preset", config["preset"] ) runner.call(cov_exe, "collect") # todo: report coverage to github, somehow @@ -374,7 +372,7 @@ def test(config: dict): "--preset", config["preset"], "--target", - "cov_coveralls", env=env, + "cov_coveralls", ) if runner.GITHUB_ANNOTATE: diff --git a/tools/json_tests/test_driver.py b/tools/json_tests/test_driver.py index 7d148d2d..71a2d415 100755 --- a/tools/json_tests/test_driver.py +++ b/tools/json_tests/test_driver.py @@ -254,7 +254,7 @@ def __main__(): else: hw_concurrency = os.cpu_count() try: - thread_count = int(os.environ.get('POOL_SIZE')) + thread_count = int(os.environ.get("POOL_SIZE")) except TypeError: thread_count = min(61, max(1, hw_concurrency * 2)) with concurrent.futures.ThreadPoolExecutor(thread_count) as executor: From abc2676f2388dff585d9ab1f1b9bcf14a83334f2 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 11:31:08 +0200 Subject: [PATCH 10/39] build: add signing tools for Windows --- .gitignore | 2 + tools/github-get-latest-release.py | 2 +- tools/win32/refresh-cert.ps1 | 25 ++++++ tools/win32/refresh-cert.py | 53 +++++++++++++ tools/win32/sign.py | 122 +++++++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 tools/win32/refresh-cert.ps1 create mode 100644 tools/win32/refresh-cert.py create mode 100644 tools/win32/sign.py diff --git a/.gitignore b/.gitignore index 172b62e2..fe7d6fae 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ build/ web.log super-linter.log *.profraw +signature.key +temp.pfx diff --git a/tools/github-get-latest-release.py b/tools/github-get-latest-release.py index 24b1d2bd..4f9013ba 100755 --- a/tools/github-get-latest-release.py +++ b/tools/github-get-latest-release.py @@ -45,6 +45,6 @@ sys.exit(0) unpack, msg = locate_unpack(release) -print_args((*msg, release, "build/.local")) +print_args((*msg, release.replace(os.path.sep, "/"), "build/.local")) if not Environment.DRY_RUN: unpack(release, "build/.local") diff --git a/tools/win32/refresh-cert.ps1 b/tools/win32/refresh-cert.ps1 new file mode 100644 index 00000000..dd8f778e --- /dev/null +++ b/tools/win32/refresh-cert.ps1 @@ -0,0 +1,25 @@ +param( + [string]$password, + [string]$filename +) + +$params = @{ + Type = 'Custom' + Container = 'test*' + Subject = 'CN=Marcin Zdun, O=midnightBITS, L=Warszawa, C=PL' + TextExtension = @( + '2.5.29.37={text}1.3.6.1.5.5.7.3.3', + '2.5.29.17={text}email=mzdun@midnightbits.com' ) + KeyUsage = 'DigitalSignature' + KeyAlgorithm = 'RSA' + KeyLength = 2048 + NotAfter = (Get-Date).AddMonths(12) + CertStoreLocation = 'Cert:\CurrentUser\My' +} +$cert = New-SelfSignedCertificate @params + +$pwd = ConvertTo-SecureString -String $password -Force -AsPlainText + +$file = Export-PfxCertificate -Cert $cert -FilePath $filename -Password $pwd + +Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -match $cert.Thumbprint} | Remove-Item diff --git a/tools/win32/refresh-cert.py b/tools/win32/refresh-cert.py new file mode 100644 index 00000000..e991adbc --- /dev/null +++ b/tools/win32/refresh-cert.py @@ -0,0 +1,53 @@ +# Copyright (c) 2023 Marcin Zdun +# This code is licensed under MIT license (see LICENSE for details) + +import base64 +import json +import os +import random +import string +import subprocess +import sys + +__dir_name__ = os.path.dirname(__file__) +__root_dir__ = os.path.dirname(os.path.dirname(__dir_name__)) + + +def run(*args: str): + proc = subprocess.run(args, shell=False, capture_output=False) + if proc.returncode != 0: + sys.exit(1) + + +letters = string.ascii_letters + string.digits + string.punctuation +weights = ( + ([7] * len(string.ascii_letters)) + + ([5] * len(string.digits)) + + ([2] * len(string.punctuation)) +) +token = "".join(random.choices(letters, weights, k=50)) + +run( + "pwsh", + os.path.join(__dir_name__, "refresh-cert.ps1"), + "-password", + token, + "-filename", + "certificate.pfx", +) + + +def load_binary(filename: str): + with open(filename, "rb") as cert: + return base64.b64encode(cert.read()).decode("UTF-8") + + +data = { + "token": base64.b64encode(token.encode("UTF-8")).decode("UTF-8"), + "secret": load_binary("certificate.pfx"), +} + +os.remove("certificate.pfx") + +with open("signature.key", "w", encoding="UTF-8") as signature: + json.dump(data, signature) diff --git a/tools/win32/sign.py b/tools/win32/sign.py new file mode 100644 index 00000000..87207a8e --- /dev/null +++ b/tools/win32/sign.py @@ -0,0 +1,122 @@ +# Copyright (c) 2023 Marcin Zdun +# This code is licensed under MIT license (see LICENSE for details) + +import base64 +import json +import os +import platform +import subprocess +import sys +import winreg +from typing import List, NamedTuple, Optional, Tuple + +__dir_name__ = os.path.dirname(__file__) +__root_dir__ = os.path.dirname(os.path.dirname(__dir_name__)) + +ENV_KEY = "SIGNATURE_KEY_SECRET" + +Version = Tuple[int, int, int] + +machine = {"ARM64": "arm64", "AMD64": "x64", "X86": "x86"}.get( + platform.machine(), "x86" +) + + +def find_sign_tool() -> Optional[str]: + with winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows Kits\Installed Roots" + ) as kits: + try: + kits_root = winreg.QueryValueEx(kits, "KitsRoot10")[0] + except FileNotFoundError: + return None + + versions: List[Tuple[Version, str]] = [] + try: + index = 0 + while True: + ver_str = winreg.EnumKey(kits, index) + ver = tuple(int(chunk) for chunk in ver_str.split(".")) + index += 1 + versions.append((ver, ver_str)) + except OSError: + pass + versions.sort() + versions.reverse() + for _, version in versions: + # C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe + sign_tool = os.path.join(kits_root, "bin", version, machine, "signtool.exe") + if os.path.isfile(sign_tool): + return sign_tool + return None + + +def get_key_(): + env = os.environ.get(ENV_KEY) + if env is not None: + return env + filename = os.path.join(os.path.expanduser("~"), "signature.key") + if os.path.isfile(filename): + with open(filename, encoding="UTF-8") as file: + return file.read().strip() + filename = os.path.join(__root_dir__, "signature.key") + if os.path.isfile(filename): + with open(filename, encoding="UTF-8") as file: + return file.read().strip() + + return None + + +class Key(NamedTuple): + token: str + secret: bytes + + +def get_key() -> Optional[Key]: + key = get_key_() + if key is None: + return None + obj = json.loads(key) + token = obj.get("token") + secret = obj.get("secret") + return Key( + base64.b64decode(token).decode("UTF-8") if token is not None else None, + base64.b64decode(secret) if secret is not None else None, + ) + + +key = get_key() + +if key is None or key.token is None or key.secret is None: + print("The key is missing", file=sys.stderr) + sys.exit(1) + +sign_tool = find_sign_tool() +if sign_tool is None: + print("signtool.exe is missing", file=sys.stderr) + sys.exit(1) + +with open("temp.pfx", "wb") as pfx: + pfx.write(key.secret) +args = [ + sign_tool, + "sign", + # "/v", + # "/debug", + "/f", + "temp.pfx", + "/p", + key.token, + "/tr", + "http://timestamp.digicert.com", + "/fd", + "sha256", + "/td", + "sha256", + *sys.argv[1:], +] +try: + if subprocess.run(args, shell=False): + sys.exit(1) +finally: + os.remove("temp.pfx") From d4a94c48f4e598081588ca300ab354f5eb2ee11d Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 14:17:49 +0200 Subject: [PATCH 11/39] feat(win32): add icons for native plugins --- apps/CMakeLists.txt | 8 +-- cmake/cov.cmake | 16 ++++++ data/icons/.gitignore | 1 + data/icons/plugin.ico | Bin 0 -> 58941 bytes extensions/CMakeLists.txt | 2 + tools/win32/icon.ps1 | 35 ++++++++++-- tools/{ => win32}/icon.py | 108 +++++++++++++++++++++++++++++++++++--- 7 files changed, 151 insertions(+), 19 deletions(-) create mode 100644 data/icons/plugin.ico rename tools/{ => win32}/icon.py (72%) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 643d8a15..fbdda9b4 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -37,12 +37,6 @@ include(builtins) string(REPLACE ";" ", " REPORT_FILTER_LIST "${REPORT_FILTERS};${NATIVE_FILTERS}") message(STATUS "Filters: ${REPORT_FILTER_LIST}") -if (WIN32) - list(APPEND SOURCES - win32/cov.rc - ) -endif() - source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) source_group(TREE ${CMAKE_CURRENT_BINARY_DIR} FILES ${CMAKE_CURRENT_BINARY_DIR}/gen/cov/builtins.hh ${CMAKE_CURRENT_BINARY_DIR}/gen/cov/versioninfo.rc) @@ -69,11 +63,11 @@ if (WIN32) list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/gen/cov/versioninfo.rc" - "${CMAKE_SOURCE_DIR}/data/icons/win32.ico" ) endif() add_cov_tool(cov ${SOURCES}) +add_win32_icon(cov "win32.ico") target_include_directories(cov PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/gen diff --git a/cmake/cov.cmake b/cmake/cov.cmake index 699a34aa..add79d06 100644 --- a/cmake/cov.cmake +++ b/cmake/cov.cmake @@ -108,6 +108,22 @@ function(add_cov_test TARGET) set(VS_MODS ${VS_MODS} PARENT_SCOPE) endfunction() +function(add_win32_icon TARGET NAME) + set(RESNAME "${PROJECT_SOURCE_DIR}/data/icons/${NAME}") + set(RC "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.dir/icon.rc") + set(__content "// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) +// This file was autogenerated. Do not edit. + +LANGUAGE 9, 1 + +100 ICON \"${RESNAME}\" +") + + file(GENERATE OUTPUT ${RC} CONTENT ${__content}) + target_sources(${TARGET} PRIVATE "${RC}" "${RESNAME}") +endfunction() + macro(set_parent_scope) set(CORE_EXT ${CORE_EXT} PARENT_SCOPE) set(COV_LIBS ${COV_LIBS} PARENT_SCOPE) diff --git a/data/icons/.gitignore b/data/icons/.gitignore index 3a5e4374..4a2c700d 100644 --- a/data/icons/.gitignore +++ b/data/icons/.gitignore @@ -1,2 +1,3 @@ *.png appicon-win32* +plugin-win32* diff --git a/data/icons/plugin.ico b/data/icons/plugin.ico new file mode 100644 index 0000000000000000000000000000000000000000..f76b0367d2d742dc0a3b3209b4827cfc0aeb4f00 GIT binary patch literal 58941 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 r& path: return p +class puzzle_side: + def __init__(self, width: number): + self.width = width + + init_stub = 1 + init_edge = 4 + init_radius = 3 + + scale = width / (2 * (init_edge + init_radius)) + + self.stub = init_stub * scale + self.edge = init_edge * scale + self.radius = init_radius * scale + + def draw(self, p: path, horiz: bool, innie: bool, returning: bool, last=False): + sign = -1 if returning else 1 + stub_sign = -sign if (innie ^ horiz) else sign + main = p.h if horiz else p.v + across = p.v if horiz else p.h + + reach = sign * 2 * self.radius + endpoint = pt(reach, 0) if horiz else pt(0, reach) + + main(sign * self.edge) + across(stub_sign * self.stub) + # main(reach) + p.a(endpoint, self.radius, sweep=not innie) + across(-stub_sign * self.stub) + if not last: + main(sign * self.edge) + + +def trace_puzzle() -> path: + width, _, top, mid = shield_calc() + puzzle_width = width / 2 + + side = puzzle_side(puzzle_width) + + p = path() + p.M(pt(-puzzle_width / 2, top + mid - puzzle_width / 3)) + + side.draw(p, horiz=True, innie=False, returning=False) + side.draw(p, horiz=False, innie=True, returning=False) + side.draw(p, horiz=True, innie=False, returning=True) + side.draw(p, horiz=False, innie=True, returning=True, last=True) + + p.z() + return p + + def trace_glyphs(): - return (trace_shield(), trace_shadow(), trace_fail(), trace_mark()) + return (trace_shield(), trace_shadow(), trace_fail(), trace_mark(), trace_puzzle()) class Shield: def __init__(self): - shield_glyph, shadow, fail, mark = trace_glyphs() + shield_glyph, shadow, fail, mark, puzzle = trace_glyphs() self.shield_glyph = shield_glyph self.shadow = shadow self.fail_glyph = fail self.mark_glyph = mark + self.puzzle = puzzle def _favicon(self, symbol: path, shield_color: str, symbol_color: str): width, height, _, _ = shield_calc() @@ -278,11 +343,32 @@ def appicon_cov(self): def appicon_win32(self): return self._appicon(self.mark_glyph, "#b9e7fc", "#1f88e5", False) + def plugin_win32(self): + shield_color = "#b9e7fc" + symbol_color = "#1f88e5" + height = shield_calc()[1] + result = svg_group(pt(ICON_HEIGHT / 2, ICON_HEIGHT - height)) + result.paths = [ + svg_path(self.shield_glyph, style("fill", shield_color)), + svg_path( + self.puzzle, + style("stroke", symbol_color), + style("fill", symbol_color, opacity=".6"), + ), + svg_path( + self.shadow, + style("fill", "#000"), + style("opacity", ".2"), + ), + svg_path(self.shield_glyph, style("stroke", symbol_color, width="2")), + ] + return svg_root(ICON_HEIGHT, result, px_size=1024) + def appicon_win32_mask(self): height = shield_calc()[1] result = svg_group(pt(ICON_HEIGHT / 2, ICON_HEIGHT - height)) result.paths = [ - f'', + f'', svg_path(self.shield_glyph, style("fill", "#fff")), ] return svg_root(ICON_HEIGHT, result, px_size=1024) @@ -311,12 +397,13 @@ def favicon_outline(self): shield = Shield() -__dir__ = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "..", "data", "icons" -) +__dir_name__ = os.path.dirname(__file__) +__root_dir__ = os.path.dirname(os.path.dirname(__dir_name__)) +__icons__ = os.path.join(__root_dir__, "data", "icons") + for icon in ["good", "bad", "passing", "outline"]: pathname = f"favicon-{icon}.svg" - with open(os.path.join(__dir__, pathname), "wb") as f: + with open(os.path.join(__icons__, pathname), "wb") as f: svg = str(getattr(shield, f"favicon_{icon}")()) f.write(svg.encode("UTF-8")) f.write(b"\n") @@ -326,7 +413,12 @@ def favicon_outline(self): pathname = {"cov": "appicon.svg"}[icon] except KeyError: pathname = f"appicon-{icon.replace('_', '-')}.svg" - with open(os.path.join(__dir__, pathname), "wb") as f: + with open(os.path.join(__icons__, pathname), "wb") as f: svg = str(getattr(shield, f"appicon_{icon}")()) f.write(svg.encode("UTF-8")) f.write(b"\n") + +with open(os.path.join(__icons__, "plugin-win32.svg"), "wb") as f: + svg = str(shield.plugin_win32()) + f.write(svg.encode("UTF-8")) + f.write(b"\n") From d0dfcd379a5073e66ab434a4d4277b5deee83024 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 16:09:03 +0200 Subject: [PATCH 12/39] build: attach sign.py to flow --- tools/flow/lib/matrix.py | 44 ++++++++++++++++++++++++++++++++++++++++ tools/flow/run.py | 12 ++++++++++- tools/win32/sign.py | 10 ++++----- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 3fd791e8..0dba5218 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -388,6 +388,27 @@ def test(config: dict): runner.call("ctest", "--preset", config["preset"]) + @staticmethod + @step_call("Sign", lambda config: config.get("os") == "windows") + def sign(config: dict): + files_to_sign: List[str] = [] + for root in [ + "bin", + "share", + os.path.join("libexec", "cov"), + ]: + for root_dir, _, files in os.walk( + os.path.join("build", config["preset"], root) + ): + for filename in files: + stem, ext = os.path.splitext(filename) + if stem[-5:] == "-test" or ext.lower() not in [".exe", ".dll"]: + continue + files_to_sign.append( + os.path.join(root_dir, filename).replace("\\", "/") + ) + runner.call("python", "tools/win32/sign.py", *files_to_sign) + @staticmethod @step_call("Pack", lambda config: len(config.get("cpack_generator", [])) > 0) def pack(config: dict): @@ -399,6 +420,27 @@ def pack(config: dict): ";".join(config.get("cpack_generator", [])), ) + @staticmethod + @step_call( + "SignPackages", + lambda config: config.get("os") == "windows" + and len(config.get("cpack_generator", [])) > 0, + ) + def sign_packages(config: dict): + files_to_sign: List[str] = [] + for root_dir, dirs, files in os.walk( + os.path.join("build", config["preset"], "packages") + ): + dirs[:] = [] + for filename in files: + _, ext = os.path.splitext(filename) + if ext.lower() != ".msi": + continue + files_to_sign.append( + os.path.join(root_dir, filename).replace("\\", "/") + ) + runner.call("python", "tools/win32/sign.py", *files_to_sign) + @staticmethod @step_call("Store") def store(config: dict): @@ -557,7 +599,9 @@ def build_steps(): steps.build, steps.test, steps.report, + steps.sign, steps.pack, + steps.sign_packages, steps.store, steps.store_packages, steps.store_tests, diff --git a/tools/flow/run.py b/tools/flow/run.py index 6a27c40b..4d5a617c 100755 --- a/tools/flow/run.py +++ b/tools/flow/run.py @@ -15,7 +15,17 @@ DEF_STEPS = { "config": ["Conan", "CMake"], "build": ["Build"], - "verify": ["Build", "Test", "Report", "Pack", "Store", "BinInst", "DevInst"], + "verify": [ + "Build", + "Test", + "Report", + "Sign", + "Pack", + "SignPackages", + "Store", + "BinInst", + "DevInst", + ], "report": ["Build", "Test", "Report"], } cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0] diff --git a/tools/win32/sign.py b/tools/win32/sign.py index 87207a8e..66bd88b8 100644 --- a/tools/win32/sign.py +++ b/tools/win32/sign.py @@ -88,13 +88,13 @@ def get_key() -> Optional[Key]: key = get_key() if key is None or key.token is None or key.secret is None: - print("The key is missing", file=sys.stderr) - sys.exit(1) + print("sign.py: the key is missing", file=sys.stderr) + sys.exit(0) sign_tool = find_sign_tool() if sign_tool is None: - print("signtool.exe is missing", file=sys.stderr) - sys.exit(1) + print("sign.py: signtool.exe not found", file=sys.stderr) + sys.exit(0) with open("temp.pfx", "wb") as pfx: pfx.write(key.secret) @@ -116,7 +116,7 @@ def get_key() -> Optional[Key]: *sys.argv[1:], ] try: - if subprocess.run(args, shell=False): + if subprocess.run(args, shell=False).returncode: sys.exit(1) finally: os.remove("temp.pfx") From ec78e396518b07eaf86d16bf1b540b929be729bd Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 16:51:56 +0200 Subject: [PATCH 13/39] ci: plug signing and collection into the workflow --- .github/workflows/build.yml | 5 ++++- docs/building.md | 2 ++ tools/{github-get-latest-release.py => download-latest.py} | 4 ++-- tools/flow/lib/matrix.py | 4 ++-- tools/flow/lib/runner.py | 1 + tools/flow/run.py | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) rename tools/{github-get-latest-release.py => download-latest.py} (91%) mode change 100755 => 100644 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd249f1f..86afc8c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -117,6 +117,9 @@ jobs: uses: KungFuDonkey/Install-OpenCppCoverage@v1 if: ${{ matrix.windows && matrix.build_type == 'Debug' }} + - name: Get latest archive from GitHub + run: python ./tools/download-latest.py + # ######## ######## ####### ## ######## ###### ######## # ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ## ## ## ## @@ -137,7 +140,7 @@ jobs: - name: Pack id: artifacts if: ${{ fromJson(needs.M.outputs.RELEASE) }} - run: ${{ env.FLOW_COMMAND }} -s Pack,StorePackages + run: ${{ env.FLOW_COMMAND }} -s Sign,Pack,SignPackages,StorePackages # ## ## ######## ## ####### ### ######## # ## ## ## ## ## ## ## ## ## ## ## diff --git a/docs/building.md b/docs/building.md index e8526c15..235fb066 100644 --- a/docs/building.md +++ b/docs/building.md @@ -29,7 +29,9 @@ Currently, there are few specialized flows: **config**, **build**, **report** an |**Build**|Builds the project.|✓||✓|✓|✓| |**Test**|Either directly calls `ctest`, or builds the self-coverage gathering target.|✓|||✓|✓| |**Report**|Puts the latest coverage into local instance of **cov**.||||✓|✓| +|**Sign**|On Windows, signs installable binaries|✓||||✓| |**Pack**|Creates archives and installers|✓||||✓| +|**SignPackages**|On Windows, signs the MSI package|✓||||✓| |**Store**|Copies packages from **Pack** to `./build/artifacts`.|✓||||✓| |**BinInst**|Extracts the ZIP/TAR.GZ to `./build/.local/`. Adding `./build/.local/bin` to $PATH should help with running latest build from the get-go.|||||✓| |**DevInst**|Extracts the ZIP/TAR.GZ to `./build/.user/`.|||||✓| diff --git a/tools/github-get-latest-release.py b/tools/download-latest.py old mode 100755 new mode 100644 similarity index 91% rename from tools/github-get-latest-release.py rename to tools/download-latest.py index 4f9013ba..b41c9be1 --- a/tools/github-get-latest-release.py +++ b/tools/download-latest.py @@ -45,6 +45,6 @@ sys.exit(0) unpack, msg = locate_unpack(release) -print_args((*msg, release.replace(os.path.sep, "/"), "build/.local")) +print_args((*msg, release.replace(os.path.sep, "/"), "build/latest")) if not Environment.DRY_RUN: - unpack(release, "build/.local") + unpack(release, "build/latest") diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 0dba5218..c6ad1bd4 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -27,7 +27,7 @@ _conan: Optional[conan] = None _platform_name, _platform_version, _platform_arch = uname() -_collect_version = (0, 21, 1) +_collect_version = (0, 22, 0) platform = _platform_name @@ -328,7 +328,7 @@ def build(config: dict): @staticmethod def get_bin(version: Tuple[int], config: dict): ext = ".exe" if os.name == "nt" else "" - for dirname in [".local", "release", config["preset"]]: + for dirname in ["latest", "release", config["preset"]]: path = f"build/{dirname}/bin/cov{ext}" if not os.path.isfile(path): continue diff --git a/tools/flow/lib/runner.py b/tools/flow/lib/runner.py index f4156e3f..5603111f 100644 --- a/tools/flow/lib/runner.py +++ b/tools/flow/lib/runner.py @@ -267,6 +267,7 @@ class runner: DRY_RUN = False CUTDOWN_OS = False GITHUB_ANNOTATE = False + OFFICIAL = False @staticmethod def run_steps(config: dict, keys: list, steps: List[callable]): diff --git a/tools/flow/run.py b/tools/flow/run.py index 4d5a617c..3af0c562 100755 --- a/tools/flow/run.py +++ b/tools/flow/run.py @@ -275,6 +275,7 @@ def main(): runner.runner.DRY_RUN = args.dry_run runner.runner.CUTDOWN_OS = args.cutdown_os runner.runner.GITHUB_ANNOTATE = args.github + runner.runner.OFFICIAL = args.official root = os.path.join(os.path.dirname(__file__), "..", "..", ".github", "workflows") paths = [os.path.join(root, "flow.json")] if args.official: From 42e4979a235bec1e27e66711038aef194d9d6707 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 19:27:44 +0200 Subject: [PATCH 14/39] ci: clean up reportable dirs/modules --- .covmodules | 11 ++++++----- CMakeLists.txt | 12 +++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.covmodules b/.covmodules index d104dfa6..c766c029 100644 --- a/.covmodules +++ b/.covmodules @@ -11,11 +11,12 @@ [module "app/main"] path = apps/cov/ path = apps/builtins/ -[module "app/ext"] - path = apps/collect - path = libs/collect-api -[module "app/filters"] - path = apps/filters +[module "ext/filters"] + path = extensions/filters +[module "ext/libs"] + path = extensions/libs +[module "ext"] + path = extensions [module "hilite/lighter"] path = libs/hilite/hilite path = libs/hilite/lighter diff --git a/CMakeLists.txt b/CMakeLists.txt index 071908c6..8d3dd589 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,15 +57,13 @@ if (COV_TESTING) set(COVERALLS_PREFIX cov_) - set(INCLUDED_IN_COVERAGE apps) + set(INCLUDED_IN_COVERAGE apps extensions) foreach(module libs/cov-api - libs/cell libs/hilite/hilite libs/hilite/lighter libs/app libs/cov-rt - libs/collect-api ) list(APPEND INCLUDED_IN_COVERAGE ${module}/include ${module}/src) endforeach() @@ -75,6 +73,14 @@ if (COV_TESTING) endforeach() set(EXCLUDED_FROM_COVERAGE apps/tests) + foreach(extension + collect-api + excludes + native + ) + list(APPEND EXCLUDED_FROM_COVERAGE + extension/${extension}/test) + endforeach() set(cov_COVERALLS_DIRS ${INCLUDED_IN_COVERAGE}) include(${PROJECT_SOURCE_DIR}/tools/coveralls/Coveralls.cmake) From 6fb4c50db24d5f7cbca34606848bfcdacdd13ab9 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 19:51:28 +0200 Subject: [PATCH 15/39] feat(win32): read output from OpenCppCoverage --- CMakeLists.txt | 3 +- conanfile.txt | 1 + extensions/libs/collect-api/CMakeLists.txt | 2 + extensions/libs/collect-api/src/msvc.cc | 26 +- extensions/libs/collect-api/src/occ_xml.cc | 199 +++++++++++ extensions/libs/collect-api/src/occ_xml.hh | 59 ++++ extensions/libs/collect-api/src/report.cc | 20 +- extensions/libs/native/CMakeLists.txt | 3 +- .../libs/native/include/native/expat.hh | 326 ++++++++++++++++++ 9 files changed, 615 insertions(+), 24 deletions(-) create mode 100644 extensions/libs/collect-api/src/occ_xml.cc create mode 100644 extensions/libs/collect-api/src/occ_xml.hh create mode 100644 extensions/libs/native/include/native/expat.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d3dd589..7334fe09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ find_package(libgit2 REQUIRED) find_package(fmt REQUIRED) find_package(mbits-args REQUIRED) find_package(mbits-lngs REQUIRED) +find_package(expat REQUIRED) if (COV_TESTING) enable_testing() @@ -79,7 +80,7 @@ if (COV_TESTING) native ) list(APPEND EXCLUDED_FROM_COVERAGE - extension/${extension}/test) + extensions/${extension}/test) endforeach() set(cov_COVERALLS_DIRS ${INCLUDED_IN_COVERAGE}) diff --git a/conanfile.txt b/conanfile.txt index 16224aca..c9509ede 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -4,6 +4,7 @@ fmt/9.1.0 gtest/cci.20210126 mbits-lngs/0.7.6 ctre/3.7.2 +expat/2.2.10 zlib/1.2.12 libcurl/8.1.2 diff --git a/extensions/libs/collect-api/CMakeLists.txt b/extensions/libs/collect-api/CMakeLists.txt index 62d91718..5ec0f4ea 100644 --- a/extensions/libs/collect-api/CMakeLists.txt +++ b/extensions/libs/collect-api/CMakeLists.txt @@ -2,6 +2,8 @@ set(SOURCES src/gnu.cc src/llvm.cc src/msvc.cc + src/occ_xml.cc + src/occ_xml.hh src/queue.hh src/report.cc src/report.hh diff --git a/extensions/libs/collect-api/src/msvc.cc b/extensions/libs/collect-api/src/msvc.cc index 51abaa20..5e5d9c07 100644 --- a/extensions/libs/collect-api/src/msvc.cc +++ b/extensions/libs/collect-api/src/msvc.cc @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -18,12 +20,6 @@ using namespace std::literals; namespace cov::app::collect { - static unsigned u(long long val) { - static constexpr long long max_uint = - std::numeric_limits::max(); - return std::max(0u, static_cast(std::min(max_uint, val))); - } - std::string dos_path(std::filesystem::path const& path) { auto copy = path; copy.make_preferred(); @@ -69,15 +65,6 @@ namespace cov::app::collect { return platform::call(make_u8path(command), args); } - /* - OpenCppCoverage - -q - --working_dir - --export_type :\\\\.xml - --source - --cover_children - -- - ...*/ std::vector occ_args{ "-q"s, "--working_dir"s, @@ -86,7 +73,7 @@ namespace cov::app::collect { fmt::format("{}:{}", occ_filter_, dos_path(cfg.bin_dir / occ_dir_ / occ_output_)), }; - // +2 for "--cover_children --"; +1 for command + // +2 for "--cover_children --"; +1 for the observed command occ_args.reserve(occ_args.size() + 2 * cfg.include.size() + 2 + 1 + args.size()); @@ -114,7 +101,7 @@ namespace cov::app::collect { return platform::call(occ_, arguments{occ_args}); } - int report(config const&, coverage&) override { return 0; } + int report(config const&, coverage&) override; private: std::string ver_; @@ -204,4 +191,9 @@ namespace cov::app::collect { ver_ = fmt::format("{}.{}", major, minor); return true; } + + int msvc_toolkit::report(config const& cfg, coverage& cvg) { + auto const report_path = cfg.bin_dir / occ_dir_ / occ_output_; + return occ_load(report_path, cfg, cvg) ? 0 : 1; + } } // namespace cov::app::collect diff --git a/extensions/libs/collect-api/src/occ_xml.cc b/extensions/libs/collect-api/src/occ_xml.cc new file mode 100644 index 00000000..b0ec482f --- /dev/null +++ b/extensions/libs/collect-api/src/occ_xml.cc @@ -0,0 +1,199 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include "occ_xml.hh" +#include +#include +#include + +// define DEBUG_IGNORE + +#define SIMPLE_PARENT(PARENT, ...) \ + struct PARENT##_handler : handler_impl<__VA_ARGS__> { \ + using handler_impl<__VA_ARGS__>::handler_impl; \ + static std::string_view name() noexcept { return #PARENT##sv; } \ + }; + +using namespace std::literals; + +namespace cov::app::collect { + std::optional parse_uint(std::string_view text) { + unsigned value{}; + auto first = text.data(); + auto last = first + text.size(); + auto [end, err] = std::from_chars(first, last, value); + if (end != last || err != std::errc{}) return std::nullopt; + return value; + } + + struct line_handler : handler_interface { + using handler_interface::handler_interface; + static std::string_view name() noexcept { return "line"sv; } + void onElement(char const** attrs) override { + if (!ctx->sink) return; + + std::optional number, hits; + + for (auto attr = attrs; *attr; attr += 2) { + auto const name = std::string_view{attr[0]}; + if (name == "number"sv) { + number = parse_uint(attr[1]); + } else if (name == "hits"sv) { + hits = parse_uint(attr[1]); + } + if (number && hits) break; + } + + if (number && hits) ctx->sink->on_visited(*number, *hits); + } + }; + + SIMPLE_PARENT(lines, line_handler); + SIMPLE_PARENT(methods); + + struct class_handler : handler_interface { + using handler_interface::handler_interface; + static std::string_view name() noexcept { return "class"sv; } + void onElement(char const** attrs) override { + for (auto attr = attrs; *attr; attr += 2) { + auto const name = std::string_view{attr[0]}; + if (name == "filename"sv) { + auto path = get_u8path(make_u8path(ctx->source) / + make_u8path(attr[1])); + ctx->sink = ctx->cvg.get_file_mt(path); + break; + } + } + } + + void onStop() override { + if (ctx->sink) ctx->cvg.handover_mt(std::move(ctx->sink)); + ctx->sink.reset(); + } + + std::unique_ptr onChild( + std::string_view name) override { + if (ctx->sink) + return find_helper::find(name, + ctx); + return {}; + } + }; + + struct source_handler : handler_interface { + using handler_interface::handler_interface; + static std::string_view name() noexcept { return "source"sv; } + void onElement(char const**) override { ctx->source.clear(); } + + void onCharacter(std::string_view chunk) override { + ctx->source.append(chunk); + } + + void onStop() override { + if (ctx->source.empty() || ctx->source.back() != '/') + ctx->source.push_back('/'); + } + }; + + SIMPLE_PARENT(classes, class_handler); + SIMPLE_PARENT(package, classes_handler); + SIMPLE_PARENT(packages, package_handler); + SIMPLE_PARENT(sources, source_handler) + SIMPLE_PARENT(coverage, packages_handler, sources_handler); + SIMPLE_PARENT(document, coverage_handler); + + class parser : public xml::ExpatBase { + std::stack> handlers_{}; + int ignore_depth_{0}; + + public: + parser(msvc_context* ctx) { + handlers_.push(std::make_unique(ctx)); + } + + static bool load(std::filesystem::path const& filename, + config const& cfg, + coverage& cvg) { + auto file = io::fopen(filename); + if (!file) return false; + + msvc_context ctx{.cfg = cfg, .cvg = cvg}; + parser ldr{&ctx}; + + if (!ldr.create()) return false; + ldr.enableElementHandler(); + ldr.enableCdataSectionHandler(); + ldr.enableCharacterDataHandler(); + + char buffer[8196]; + while (auto const byte_count = file.load(buffer, sizeof(buffer))) { + ldr.parse(buffer, static_cast(byte_count), false); + } + ldr.parse(buffer, 0, true); + + return true; + } + + void onStartElement(char const* name, char const** attrs) { + if (!ignore_depth_) { + auto const tag = std::string_view{name}; + auto current = handlers_.top().get(); + auto next = current->onChild(tag); + if (next) { + next->onElement(attrs); + handlers_.push(std::move(next)); + return; + } + } +#if defined(DEBUG_IGNORE) + if (!ignore_depth_) { + fmt::print(stderr, "[{}] >>> {}", ignore_depth_, name); + for (auto attr = attrs; *attr; attr += 2) { + fmt::print(stderr, " {}=\"{}\"", attr[0], attr[1]); + } + fmt::print(stderr, "\n"); + } +#endif + + ++ignore_depth_; + } + + void onEndElement([[maybe_unused]] char const* name) { + if (ignore_depth_) { + --ignore_depth_; +#if defined(DEBUG_IGNORE) + if (!ignore_depth_) + fmt::print(stderr, "[{}] <<< {}\n", ignore_depth_, name); +#endif + return; + } + + auto current = std::move(handlers_.top()); + handlers_.pop(); + current->onStop(); + } + + void onCharacterData(char const* data, int length) { + if (ignore_depth_) return; + auto current = handlers_.top().get(); + current->onCharacter( + std::string_view{data, static_cast(length)}); + } + }; + + handler_interface::~handler_interface() = default; + void handler_interface::onElement(char const**) {} + std::unique_ptr handler_interface::onChild( + std::string_view) { + return {}; + } + void handler_interface::onCharacter(std::string_view) {} + void handler_interface::onStop() {} + + bool occ_load(std::filesystem::path const& filename, + config const& cfg, + coverage& cvg) { + return parser::load(filename, cfg, cvg); + } + +} // namespace cov::app::collect diff --git a/extensions/libs/collect-api/src/occ_xml.hh b/extensions/libs/collect-api/src/occ_xml.hh new file mode 100644 index 00000000..b01795a7 --- /dev/null +++ b/extensions/libs/collect-api/src/occ_xml.hh @@ -0,0 +1,59 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include + +namespace cov::app::collect { + struct msvc_context { + config const& cfg; + coverage& cvg; + std::string source{}; + std::unique_ptr sink{}; + }; + + struct handler_interface { + msvc_context* ctx{}; + handler_interface(msvc_context* ctx) : ctx{ctx} {} + virtual ~handler_interface(); + virtual void onElement(char const** attrs); + virtual std::unique_ptr onChild(std::string_view); + virtual void onCharacter(std::string_view); + virtual void onStop(); + }; + + template + struct find_helper; + + template <> + struct find_helper<> { + static std::unique_ptr find(std::string_view, + msvc_context*) { + return {}; + } + }; + + template + struct find_helper { + static std::unique_ptr find(std::string_view name, + msvc_context* ctx) { + if (name == First::name()) return std::make_unique(ctx); + return find_helper::find(name, ctx); + } + }; + + template + struct handler_impl : handler_interface { + using handler_interface::handler_interface; + std::unique_ptr onChild( + std::string_view name) override { + return find_helper::find(name, this->ctx); + } + }; + + bool occ_load(std::filesystem::path const& filename, + config const& cfg, + coverage& cvg); +} // namespace cov::app::collect diff --git a/extensions/libs/collect-api/src/report.cc b/extensions/libs/collect-api/src/report.cc index 954c0cac..bda68553 100644 --- a/extensions/libs/collect-api/src/report.cc +++ b/extensions/libs/collect-api/src/report.cc @@ -28,6 +28,9 @@ namespace cov::app::collect { auto rest = path.substr(incl.size()); if (rest.empty() || rest.front() == '/') { auto key = std::string{path.data(), path.size()}; +#ifdef _WIN32 + std::replace(key.begin(), key.end(), '\\', '/'); +#endif auto it = files_.find(key); if (it == files_.end()) { bool ignore = false; @@ -42,21 +45,26 @@ namespace cov::app::collect { } std::unique_ptr report::get_file_mt(std::string_view path) { + static constexpr auto sep = + static_cast(std::filesystem::path::preferred_separator); if (!path.starts_with(src_prefix_)) return nullptr; path = path.substr(src_prefix_.length()); for (auto const& excl_path : cfg_.exclude) { auto excl = get_u8path(excl_path); if (!path.starts_with(excl)) continue; auto rest = path.substr(excl.size()); - if (rest.empty() || rest.front() == '/') return nullptr; + if (rest.empty() || rest.front() == sep) return nullptr; } for (auto const& incl_path : cfg_.include) { auto incl = get_u8path(incl_path); if (!path.starts_with(incl)) continue; auto rest = path.substr(incl.size()); - if (rest.empty() || rest.front() == '/') { - return std::make_unique( - std::string{path.data(), path.size()}); + if (rest.empty() || rest.front() == sep) { + auto key = std::string{path.data(), path.size()}; +#ifdef _WIN32 + std::replace(key.begin(), key.end(), '\\', '/'); +#endif + return std::make_unique(key); } } return nullptr; @@ -123,7 +131,9 @@ namespace cov::app::collect { } std::string report::build_prefix() const { - return fmt::format("{}/", get_u8path(cfg_.src_dir)); + return fmt::format( + "{}{}", get_u8path(cfg_.src_dir), + static_cast(std::filesystem::path::preferred_separator)); } json::node report::function_cvg::get_json() const { diff --git a/extensions/libs/native/CMakeLists.txt b/extensions/libs/native/CMakeLists.txt index 769adc0e..fa9edbc6 100644 --- a/extensions/libs/native/CMakeLists.txt +++ b/extensions/libs/native/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES src/platform.cc + include/native/expat.hh include/native/platform.hh include/native/str.hh ) @@ -9,6 +10,6 @@ add_cov_library(ext_native ${SOURCES}) target_include_directories(ext_native PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/native ) -target_link_libraries(ext_native PUBLIC ctre::ctre app_main) +target_link_libraries(ext_native PUBLIC ctre::ctre expat::expat app_main) set_parent_scope() diff --git a/extensions/libs/native/include/native/expat.hh b/extensions/libs/native/include/native/expat.hh new file mode 100644 index 00000000..9d0d8165 --- /dev/null +++ b/extensions/libs/native/include/native/expat.hh @@ -0,0 +1,326 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#pragma once + +#include +#include + +namespace xml { + template + class ExpatBase { + public: + ExpatBase() : parser_(nullptr) {} + ~ExpatBase() { destroy(); } + + bool create(const XML_Char* encoding = nullptr, + const XML_Char* sep = nullptr) { + destroy(); + if (encoding != nullptr && encoding[0] == 0) encoding = nullptr; + + if (sep != nullptr && sep[0] == 0) sep = nullptr; + + parser_ = XML_ParserCreate_MM(encoding, nullptr, sep); + if (parser_ == nullptr) return false; + + Final* pThis = static_cast(this); + pThis->onPostCreate(); + + XML_SetUserData(parser_, static_cast(pThis)); + return true; + } + + bool isCreated() const { return parser_ != nullptr; } + + void destroy() { + if (parser_) XML_ParserFree(parser_); + parser_ = nullptr; + } + + bool parse(const char* buffer, int length = -1, bool isFinal = true) { + if (length < 0) length = static_cast(std::strlen(buffer)); + + return XML_Parse(parser_, buffer, length, isFinal) != 0; + } + + bool parseBuffer(int length, bool isFinal = true) { + return XML_ParseBuffer(parser_, length, isFinal) != 0; + } + + void* getBuffer(int length) { return XML_GetBuffer(parser_, length); } + + void enableStartElementHandler(bool enable = true) { + XML_SetStartElementHandler(parser_, + enable ? startElementHandler : nullptr); + } + + void enableEndElementHandler(bool enable = true) { + XML_SetEndElementHandler(parser_, + enable ? endElementHandler : nullptr); + } + + void enableElementHandler(bool enable = true) { + enableStartElementHandler(enable); + enableEndElementHandler(enable); + } + + void enableCharacterDataHandler(bool enable = true) { + XML_SetCharacterDataHandler( + parser_, enable ? characterDataHandler : nullptr); + } + + void enableProcessingInstructionHandler(bool enable = true) { + XML_SetProcessingInstructionHandler( + parser_, enable ? ProcessingInstructionHandler : nullptr); + } + + void enableCommentHandler(bool enable = true) { + XML_SetCommentHandler(parser_, enable ? commentHandler : nullptr); + } + + void enableStartCdataSectionHandler(bool enable = true) { + XML_SetStartCdataSectionHandler( + parser_, enable ? startCdataSectionHandler : nullptr); + } + + void enableEndCdataSectionHandler(bool enable = true) { + XML_SetEndCdataSectionHandler( + parser_, enable ? endCdataSectionHandler : nullptr); + } + + void enableCdataSectionHandler(bool enable = true) { + enableStartCdataSectionHandler(enable); + enableEndCdataSectionHandler(enable); + } + + void enableDefaultHandler(bool enable = true, bool expand = true) { + if (expand) { + XML_SetDefaultHandlerExpand(parser_, + enable ? defaultHandler : nullptr); + } else + XML_SetDefaultHandler(parser_, + enable ? defaultHandler : nullptr); + } + + void enableExternalEntityRefHandler(bool enable = true) { + XML_SetExternalEntityRefHandler( + parser_, enable ? externalEntityRefHandler : nullptr); + } + + void enableUnknownEncodingHandler(bool enable = true) { + Final* pThis = static_cast(this); + XML_SetUnknownEncodingHandler( + parser_, enable ? unknownEncodingHandler : nullptr, + enable ? static_cast(pThis) : nullptr); + } + + void enableStartNamespaceDeclHandler(bool enable = true) { + XML_SetStartNamespaceDeclHandler( + parser_, enable ? startNamespaceDeclHandler : nullptr); + } + + void enableEndNamespaceDeclHandler(bool enable = true) { + XML_SetEndNamespaceDeclHandler( + parser_, enable ? endNamespaceDeclHandler : nullptr); + } + + void enableNamespaceDeclHandler(bool enable = true) { + enableStartNamespaceDeclHandler(enable); + enableEndNamespaceDeclHandler(enable); + } + + void enableXmlDeclHandler(bool enable = true) { + XML_SetXmlDeclHandler(parser_, enable ? xmlDeclHandler : nullptr); + } + + void enableStartDoctypeDeclHandler(bool enable = true) { + XML_SetStartDoctypeDeclHandler( + parser_, enable ? startDoctypeDeclHandler : nullptr); + } + + void enableEndDoctypeDeclHandler(bool enable = true) { + XML_SetEndDoctypeDeclHandler( + parser_, enable ? endDoctypeDeclHandler : nullptr); + } + + void enableDoctypeDeclHandler(bool enable = true) { + enableStartDoctypeDeclHandler(enable); + enableEndDoctypeDeclHandler(enable); + } + + enum XML_Error getErrorCode() { return XML_GetErrorCode(parser_); } + + long getCurrentByteIndex() { return XML_GetCurrentByteIndex(parser_); } + + int getCurrentLineNumber() { return XML_GetCurrentLineNumber(parser_); } + + int getCurrentColumnNumber() { + return XML_GetCurrentColumnNumber(parser_); + } + + int getCurrentByteCount() { return XML_GetCurrentByteCount(parser_); } + + const char* getInputContext(int* offset, int* size) { + return XML_GetInputContext(parser_, offset, size); + } + + const XML_LChar* getErrorString() { + return XML_ErrorString(getErrorCode()); + } + + static const XML_LChar* getExpatVersion() { return XML_ExpatVersion(); } + + static XML_Expat_Version getExpatVersionInfo() { + return XML_ExpatVersionInfo(); + } + + static const XML_LChar* getErrorString(enum XML_Error error) { + return XML_ErrorString(error); + } + + void onStartElement(const XML_Char* name, const XML_Char** attrs) {} + + void onEndElement(const XML_Char* name) {} + + void onCharacterData(const XML_Char* data, int length) {} + + void onProcessingInstruction(const XML_Char* target, + const XML_Char* data) {} + + void onComment(const XML_Char* data) {} + + void onStartCdataSection() {} + + void onEndCdataSection() {} + + void onDefault(const XML_Char* data, int length) {} + + bool onExternalEntityRef(const XML_Char* context, + const XML_Char* base, + const XML_Char* systemID, + const XML_Char* publicID) { + return false; + } + + bool onUnknownEncoding(const XML_Char* name, XML_Encoding* info) { + return false; + } + + void onStartNamespaceDecl(const XML_Char* prefix, const XML_Char* uri) { + } + + void onEndNamespaceDecl(const XML_Char* prefix) {} + + void onXmlDecl(const XML_Char* version, + const XML_Char* encoding, + bool standalone) {} + + void onStartDoctypeDecl(const XML_Char* doctypeName, + const XML_Char* systemId, + const XML_Char* publicID, + bool hasInternalSubset) {} + + void onEndDoctypeDecl() {} + + protected: + void onPostCreate() {} + + static auto ptr(void* userData) { + return static_cast(userData); + } + + template + auto bool2(boolean_like result) { + return result ? true_value : false_value; + } + + static void startElementHandler(void* userData, + const XML_Char* name, + const XML_Char** attrs) { + ptr(userData)->onStartElement(name, attrs); + } + + static void endElementHandler(void* userData, const XML_Char* name) { + ptr(userData)->onEndElement(name); + } + + static void characterDataHandler(void* userData, + const XML_Char* data, + int length) { + ptr(userData)->onCharacterData(data, length); + } + + static void ProcessingInstructionHandler(void* userData, + const XML_Char* target, + const XML_Char* data) { + ptr(userData)->onProcessingInstruction(target, data); + } + + static void commentHandler(void* userData, const XML_Char* data) { + ptr(userData)->onComment(data); + } + + static void startCdataSectionHandler(void* userData) { + ptr(userData)->onStartCdataSection(); + } + + static void endCdataSectionHandler(void* userData) { + ptr(userData)->onEndCdataSection(); + } + + static void defaultHandler(void* userData, + const XML_Char* data, + int length) { + ptr(userData)->onDefault(data, length); + } + + static int externalEntityRefHandler(void* userData, + const XML_Char* context, + const XML_Char* base, + const XML_Char* systemID, + const XML_Char* publicID) { + return bool2<1, 0>(ptr(userData)->onExternalEntityRef( + context, base, systemID, publicID)); + } + + static int unknownEncodingHandler(void* userData, + const XML_Char* name, + XML_Encoding* info) { + return bool2( + ptr(userData)->onUnknownEncoding(name, info)); + } + + static void startNamespaceDeclHandler(void* userData, + const XML_Char* prefix, + const XML_Char* uri) { + ptr(userData)->onStartNamespaceDecl(prefix, uri); + } + + static void endNamespaceDeclHandler(void* userData, + const XML_Char* prefix) { + ptr(userData)->onEndNamespaceDecl(prefix); + } + + static void xmlDeclHandler(void* userData, + const XML_Char* version, + const XML_Char* encoding, + int standalone) { + ptr(userData)->onXmlDecl(version, encoding, standalone != 0); + } + + static void startDoctypeDeclHandler(void* userData, + const XML_Char* doctypeName, + const XML_Char* systemId, + const XML_Char* publicID, + int hasInternalSubset) { + ptr(userData)->onStartDoctypeDecl(doctypeName, systemId, publicID, + hasInternalSubset != 0); + } + + static void endDoctypeDeclHandler(void* userData) { + ptr(userData)->onEndDoctypeDecl(); + } + + XML_Parser parser_; + }; +} // namespace xml From 9a96e33f5ec1c3221426b611e10727e10c89f703 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 19:52:13 +0200 Subject: [PATCH 16/39] build: use `cov collect` with OCC --- tools/flow/lib/matrix.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index c6ad1bd4..5507906b 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -351,9 +351,8 @@ def get_bin(version: Tuple[int], config: dict): @step_call("Test") def test(config: dict): has_coverage = config.get("coverage") - uses_occ = config.get("os") == "windows" cov_exe = None - if has_coverage and not uses_occ: + if has_coverage: cov_exe = steps.get_bin(_collect_version, config) if cov_exe is not None: @@ -548,10 +547,7 @@ def dev_inst(config: dict): visible=lambda config: config.get("coverage") == True, ) def report(config: dict): - uses_occ = config.get("os") == "windows" - cov_exe = None - if not uses_occ: - cov_exe = steps.get_bin(_collect_version, config) + cov_exe = steps.get_bin(_collect_version, config) reporter = f"build/{config['preset']}/bin/cov" try: From 93742d5e7ceccca1ecbb3583219025754126ad2d Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 07:22:15 +0200 Subject: [PATCH 17/39] fix(core): remove short help from error messages --- .../038-config-set-but-multivar.json | 5 +- .../039-config-set-but-include.json | 5 +- .../040-config-unset-but-multivar.json | 5 +- .../041-config-unset-but-not-there.json | 5 +- .../042-config-unset-but-no-a-key.json | 5 +- .../064-module-no-covmodule-add.json | 5 +- .../008-report-A/072-report-not-the-json.json | 2 +- .../073-report-not-the-json-filtered.json | 2 +- .../010-log/083-log-no-args-inited.json | 5 +- .../main-set/010-log/093-log-two-HEADs.json | 5 +- .../main-set/010-log/094-log-123456789.json | 5 +- .../010-log/095-log-try-non-report.json | 5 +- ...6-B-branch-create-invalid-start-point.json | 5 +- .../011-refs/110-branch-create-unborn.json | 5 +- .../114-branch-delete-nonexisting.json | 5 +- .../011-refs/119-tag-create-unborn.json | 5 +- .../011-refs/121-tag-delete-nonexisting.json | 5 +- .../012-checkout/133-checkout-orphan.json | 5 +- .../134-checkout-orphan-main.json | 5 +- .../135-checkout-orphan-invalid-spec.json | 5 +- .../013-reset/142-reset-no-cov-HEAD.json | 5 +- .../014-show/146-show-no-args-unborn.json | 5 +- .../038-config-set-but-multivar.json | 5 +- .../039-config-set-but-include.json | 5 +- .../040-config-unset-but-multivar.json | 5 +- .../041-config-unset-but-not-there.json | 5 +- .../042-config-unset-but-no-a-key.json | 5 +- .../064-module-no-covmodule-add.json | 5 +- .../005-report/072-report-not-the-json.json | 2 +- .../073-report-not-the-json-filtered.json | 2 +- .../006-log/083-log-no-args-inited.json | 5 +- .../006-log/093-log-two-HEADs.json | 5 +- .../006-log/094-log-123456789.json | 5 +- .../006-log/095-log-try-non-report.json | 5 +- .../007-refs/110-branch-create-unborn.json | 5 +- .../114-branch-delete-nonexisting.json | 5 +- .../007-refs/119-tag-create-unborn.json | 5 +- .../007-refs/121-tag-delete-nonexisting.json | 5 +- .../012-checkout/133-checkout-orphan.json | 5 +- .../134-checkout-orphan-main.json | 5 +- .../135-checkout-orphan-invalid-spec.json | 5 +- .../014-show/146-show-no-args-unborn.json | 5 +- libs/app/src/args.cc | 1 - libs/cov-rt/src/report.cc | 78 ++++++++++++++++++- libs/cov-rt/src/report_command.cc | 8 +- tools/json_tests/nullify.py | 26 +++++-- tools/json_tests/runner.py | 2 - 47 files changed, 142 insertions(+), 171 deletions(-) diff --git a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json index 16c8c485..acf3ffd1 100644 --- a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json +++ b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: error: entry is not unique due to being a multivar\n" - ] + "cov config: error: entry is not unique due to being a multivar\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/main-set/005-config-C/039-config-set-but-include.json b/apps/tests/main-set/005-config-C/039-config-set-but-include.json index bf1f8fda..530f6f0b 100644 --- a/apps/tests/main-set/005-config-C/039-config-set-but-include.json +++ b/apps/tests/main-set/005-config-C/039-config-set-but-include.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: error: entry is not unique due to being included\n" - ] + "cov config: error: entry is not unique due to being included\n" ], "prepare": [ "touch '$TMP/config.inc' '[group]\nkey = value 1'", diff --git a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json index eeef8daf..cf8cdbe1 100644 --- a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json +++ b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: error: entry is not unique due to being a multivar\n" - ] + "cov config: error: entry is not unique due to being a multivar\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json index 31c19c52..e2be14b4 100644 --- a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json +++ b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: error: could not find key 'group.other' to delete\n" - ] + "cov config: error: could not find key 'group.other' to delete\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json index e6fbbf81..7c0cf06a 100644 --- a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json +++ b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: error: invalid config item name 'group-other'\n" - ] + "cov config: error: invalid config item name 'group-other'\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json index 32095757..7fe219c1 100644 --- a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json +++ b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov module [-h] [--show-sep []] | [--set-sep | --add

| --remove | --remove-all ] | []", - "cov module: error: requested file is a directory\n" - ] + "cov module: error: requested file is a directory\n" ], "prepare": [ "git init $TMP/repo", diff --git a/apps/tests/main-set/008-report-A/072-report-not-the-json.json b/apps/tests/main-set/008-report-A/072-report-not-the-json.json index 455b61fe..6d7cbd49 100644 --- a/apps/tests/main-set/008-report-A/072-report-not-the-json.json +++ b/apps/tests/main-set/008-report-A/072-report-not-the-json.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", + "cov report: /git: undefined", "cov report: error: there were issues with $DATA/no-git-coverage.json\n" ] ], diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index e232f91f..20bb4100 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -4,7 +4,7 @@ 2, "", [ - "usage: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", + "cov report: /git: undefined", "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter" ] ], diff --git a/apps/tests/main-set/010-log/083-log-no-args-inited.json b/apps/tests/main-set/010-log/083-log-no-args-inited.json index 5f01797d..802f2fce 100644 --- a/apps/tests/main-set/010-log/083-log-no-args-inited.json +++ b/apps/tests/main-set/010-log/083-log-no-args-inited.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: error: HEAD refers to branch with no reports\n" - ] + "cov log: error: HEAD refers to branch with no reports\n" ], "prepare": [ "git init '$TMP/repo'", diff --git a/apps/tests/main-set/010-log/093-log-two-HEADs.json b/apps/tests/main-set/010-log/093-log-two-HEADs.json index 17c68e08..2d0744c8 100644 --- a/apps/tests/main-set/010-log/093-log-two-HEADs.json +++ b/apps/tests/main-set/010-log/093-log-two-HEADs.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: error: invalid pattern '..'\n" - ] + "cov log: error: invalid pattern '..'\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/010-log/094-log-123456789.json b/apps/tests/main-set/010-log/094-log-123456789.json index 5eb210cc..aab86d49 100644 --- a/apps/tests/main-set/010-log/094-log-123456789.json +++ b/apps/tests/main-set/010-log/094-log-123456789.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: error: requested object could not be found\n" - ] + "cov log: error: requested object could not be found\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/010-log/095-log-try-non-report.json b/apps/tests/main-set/010-log/095-log-try-non-report.json index ade8455f..e152f2c3 100644 --- a/apps/tests/main-set/010-log/095-log-try-non-report.json +++ b/apps/tests/main-set/010-log/095-log-try-non-report.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: cov::category error: Object cannot be cast to required type\n" - ] + "cov log: cov::category error: Object cannot be cast to required type\n" ], "prepare": [ "unpack $DATA/repo.git.tar $TMP", diff --git a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json index bd9d1a85..22d9cc20 100644 --- a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json +++ b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov branch [-h] [ [] | -d ... | -l [...] | --show-current]", - "cov branch: error: requested object could not be found\n" - ] + "cov branch: error: requested object could not be found\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/011-refs/110-branch-create-unborn.json b/apps/tests/main-set/011-refs/110-branch-create-unborn.json index 36eaac56..f0f59442 100644 --- a/apps/tests/main-set/011-refs/110-branch-create-unborn.json +++ b/apps/tests/main-set/011-refs/110-branch-create-unborn.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov branch [-h] [ [] | -d ... | -l [...] | --show-current]", - "cov branch: error: HEAD refers to branch with no reports\n" - ] + "cov branch: error: HEAD refers to branch with no reports\n" ], "prepare": [ "cd $TMP", diff --git a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json index d511698e..8664b64a 100644 --- a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov branch [-h] [ [] | -d ... | -l [...] | --show-current]", - "cov branch: error: requested object could not be found\n" - ] + "cov branch: error: requested object could not be found\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/011-refs/119-tag-create-unborn.json b/apps/tests/main-set/011-refs/119-tag-create-unborn.json index bb77ca04..b607e588 100644 --- a/apps/tests/main-set/011-refs/119-tag-create-unborn.json +++ b/apps/tests/main-set/011-refs/119-tag-create-unborn.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov tag [-h] [ [] | -d ... | -l [...]]", - "cov tag: error: HEAD refers to branch with no reports\n" - ] + "cov tag: error: HEAD refers to branch with no reports\n" ], "prepare": [ "cd $TMP", diff --git a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json index d787a09a..2cb3d9ea 100644 --- a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov tag [-h] [ [] | -d ... | -l [...]]", - "cov tag: error: requested object could not be found\n" - ] + "cov tag: error: requested object could not be found\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/012-checkout/133-checkout-orphan.json b/apps/tests/main-set/012-checkout/133-checkout-orphan.json index f743b440..ac401621 100644 --- a/apps/tests/main-set/012-checkout/133-checkout-orphan.json +++ b/apps/tests/main-set/012-checkout/133-checkout-orphan.json @@ -7,10 +7,7 @@ "expected": [ 2, "branch-name\n", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: error: HEAD refers to branch with no reports\n" - ] + "cov log: error: HEAD refers to branch with no reports\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json index 9a70fe9f..add9350d 100644 --- a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json +++ b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov checkout [-h] [--detach|-b|--orphan] []", - "cov checkout: git::category error: Object exists preventing operation\n" - ] + "cov checkout: git::category error: Object exists preventing operation\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json index dd95f83e..9e935956 100644 --- a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json +++ b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov checkout [-h] [--detach|-b|--orphan] []", - "cov checkout: git::category error: Name/ref spec was not in a valid format\n" - ] + "cov checkout: git::category error: Name/ref spec was not in a valid format\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json index b4aba35a..302a79c3 100644 --- a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json +++ b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov reset [-h] ", - "cov reset: error: HEAD refers to branch with no reports\n" - ] + "cov reset: error: HEAD refers to branch with no reports\n" ], "prepare": [ "mkdirs '$TMP/reset-empty'", diff --git a/apps/tests/main-set/014-show/146-show-no-args-unborn.json b/apps/tests/main-set/014-show/146-show-no-args-unborn.json index a0701bf1..ba04e475 100644 --- a/apps/tests/main-set/014-show/146-show-no-args-unborn.json +++ b/apps/tests/main-set/014-show/146-show-no-args-unborn.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov show [-h] [] [-m ] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov show: error: HEAD refers to branch with no reports\n" - ] + "cov show: error: HEAD refers to branch with no reports\n" ], "prepare": [ "mkdirs '$TMP/dirname'", diff --git a/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json b/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json index 8f107f2e..c4f56289 100644 --- a/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json +++ b/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" - ] + "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/messages-pl/003-config/039-config-set-but-include.json b/apps/tests/messages-pl/003-config/039-config-set-but-include.json index 43cad013..b389b2d7 100644 --- a/apps/tests/messages-pl/003-config/039-config-set-but-include.json +++ b/apps/tests/messages-pl/003-config/039-config-set-but-include.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: błąd: wpis nie jest unikalny ze względu na to, że został załączony\n" - ] + "cov config: błąd: wpis nie jest unikalny ze względu na to, że został załączony\n" ], "prepare": [ "touch '$TMP/config.inc' '[group]\nkey = value 1'", diff --git a/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json b/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json index 596c2a3b..7c96b4cf 100644 --- a/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json +++ b/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" - ] + "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json b/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json index da1fd5b8..80091f7e 100644 --- a/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json +++ b/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: błąd: nie można odnaleźć klucza „group.other” do usunięcia\n" - ] + "cov config: błąd: nie można odnaleźć klucza „group.other” do usunięcia\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json b/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json index b2e46952..1ea9a720 100644 --- a/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json +++ b/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov config [-h] [] [ [] | --unset | -l | --list]", - "cov config: błąd: nieprawidłowa nazwa elementu konfiguracji „group-other”\n" - ] + "cov config: błąd: nieprawidłowa nazwa elementu konfiguracji „group-other”\n" ], "prepare": [ "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" diff --git a/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json b/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json index 9dc82bf8..e775219e 100644 --- a/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json +++ b/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov module [-h] [--show-sep []] | [--set-sep | --add | --remove | --remove-all ] | []", - "cov module: błąd: requested file is a directory\n" - ] + "cov module: błąd: requested file is a directory\n" ], "prepare": [ "git init $TMP/repo", diff --git a/apps/tests/messages-pl/005-report/072-report-not-the-json.json b/apps/tests/messages-pl/005-report/072-report-not-the-json.json index 4f49e58d..71862dad 100644 --- a/apps/tests/messages-pl/005-report/072-report-not-the-json.json +++ b/apps/tests/messages-pl/005-report/072-report-not-the-json.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", + "cov report: /git: undefined", "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json\n" ] ], diff --git a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json index 2e539d99..1ed33eef 100644 --- a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json +++ b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json @@ -5,7 +5,7 @@ 2, "", [ - "użycie: cov report [-h] [-f ] [-p = ...] [--amend] [-o ]", + "cov report: /git: undefined", "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json przetworzonym przez filtr echo-to-stdout" ] ], diff --git a/apps/tests/messages-pl/006-log/083-log-no-args-inited.json b/apps/tests/messages-pl/006-log/083-log-no-args-inited.json index 5e3d2a93..7e2187da 100644 --- a/apps/tests/messages-pl/006-log/083-log-no-args-inited.json +++ b/apps/tests/messages-pl/006-log/083-log-no-args-inited.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: błąd: HEAD odnosi się do gałęzi bez raportów\n" - ] + "cov log: błąd: HEAD odnosi się do gałęzi bez raportów\n" ], "prepare": [ "git init '$TMP/repo'", diff --git a/apps/tests/messages-pl/006-log/093-log-two-HEADs.json b/apps/tests/messages-pl/006-log/093-log-two-HEADs.json index 88354cc4..3f390cce 100644 --- a/apps/tests/messages-pl/006-log/093-log-two-HEADs.json +++ b/apps/tests/messages-pl/006-log/093-log-two-HEADs.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: błąd: nieprawidłowy wzorzec '..'\n" - ] + "cov log: błąd: nieprawidłowy wzorzec '..'\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/006-log/094-log-123456789.json b/apps/tests/messages-pl/006-log/094-log-123456789.json index e2040883..89cc3ca7 100644 --- a/apps/tests/messages-pl/006-log/094-log-123456789.json +++ b/apps/tests/messages-pl/006-log/094-log-123456789.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: błąd: nie można odnaleźć żądanego obiektu\n" - ] + "cov log: błąd: nie można odnaleźć żądanego obiektu\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/006-log/095-log-try-non-report.json b/apps/tests/messages-pl/006-log/095-log-try-non-report.json index ade8455f..e152f2c3 100644 --- a/apps/tests/messages-pl/006-log/095-log-try-non-report.json +++ b/apps/tests/messages-pl/006-log/095-log-try-non-report.json @@ -3,10 +3,7 @@ "expected": [ 2, "", - [ - "usage: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: cov::category error: Object cannot be cast to required type\n" - ] + "cov log: cov::category error: Object cannot be cast to required type\n" ], "prepare": [ "unpack $DATA/repo.git.tar $TMP", diff --git a/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json b/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json index 712a6434..8db14751 100644 --- a/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json +++ b/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov branch [-h] [ [] | -d ... | -l [...] | --show-current]", - "cov branch: błąd: HEAD odnosi się do gałęzi bez raportów\n" - ] + "cov branch: błąd: HEAD odnosi się do gałęzi bez raportów\n" ], "prepare": [ "cd $TMP", diff --git a/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json b/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json index f5fe5a3b..e7295939 100644 --- a/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json +++ b/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov branch [-h] [ [] | -d ... | -l [...] | --show-current]", - "cov branch: błąd: nie można odnaleźć żądanego obiektu\n" - ] + "cov branch: błąd: nie można odnaleźć żądanego obiektu\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json b/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json index 68cf2223..715e25d4 100644 --- a/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json +++ b/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov tag [-h] [ [] | -d ... | -l [...]]", - "cov tag: błąd: HEAD odnosi się do gałęzi bez raportów\n" - ] + "cov tag: błąd: HEAD odnosi się do gałęzi bez raportów\n" ], "prepare": [ "cd $TMP", diff --git a/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json b/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json index e79f4b2f..2e6cefd4 100644 --- a/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json +++ b/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov tag [-h] [ [] | -d ... | -l [...]]", - "cov tag: błąd: nie można odnaleźć żądanego obiektu\n" - ] + "cov tag: błąd: nie można odnaleźć żądanego obiektu\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json b/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json index 15709055..d37852e9 100644 --- a/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json +++ b/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json @@ -8,10 +8,7 @@ "expected": [ 2, "branch-name\n", - [ - "użycie: cov log [-h] [] [-n ] [--oneline] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov log: błąd: HEAD odnosi się do gałęzi bez raportów\n" - ] + "cov log: błąd: HEAD odnosi się do gałęzi bez raportów\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json b/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json index cc430cfc..fb4460f7 100644 --- a/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json +++ b/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov checkout [-h] [--detach|-b|--orphan] []", - "cov checkout: błąd git::category: Object exists preventing operation\n" - ] + "cov checkout: błąd git::category: Object exists preventing operation\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json b/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json index 1e16af27..cf596610 100644 --- a/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json +++ b/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov checkout [-h] [--detach|-b|--orphan] []", - "cov checkout: błąd git::category: Name/ref spec was not in a valid format\n" - ] + "cov checkout: błąd git::category: Name/ref spec was not in a valid format\n" ], "prepare": [ "unpack $DATA/revparse.tar $TMP", diff --git a/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json b/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json index c3c90ff8..b29acf33 100644 --- a/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json +++ b/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json @@ -4,10 +4,7 @@ "expected": [ 2, "", - [ - "użycie: cov show [-h] [] [-m ] [--format ] [--abbrev-hash] [--no-abbrev-hash] [--prop-names] [--no-prop-names] [--color ] [--decorate ]", - "cov show: błąd: HEAD odnosi się do gałęzi bez raportów\n" - ] + "cov show: błąd: HEAD odnosi się do gałęzi bez raportów\n" ], "prepare": [ "mkdirs '$TMP/dirname'", diff --git a/libs/app/src/args.cc b/libs/app/src/args.cc index eec141fd..3eb0e4bd 100644 --- a/libs/app/src/args.cc +++ b/libs/app/src/args.cc @@ -73,7 +73,6 @@ namespace cov::app { str::errors::Strings const& tr, str::args::Strings const& args) const { auto const msg = message(ec, tr, args); - parser_.short_help(stderr); std::fputs(msg.c_str(), stderr); std::fputc('\n', stderr); std::exit(2); diff --git a/libs/cov-rt/src/report.cc b/libs/cov-rt/src/report.cc index 377db24f..a3ad7292 100644 --- a/libs/cov-rt/src/report.cc +++ b/libs/cov-rt/src/report.cc @@ -290,11 +290,26 @@ namespace cov::app::report { auto const json_git_head = cast_from_json(json_git, u8"head"sv); - if (!json_git_branch || !json_git_head || !json_files) return false; + if (!json_git_branch || !json_git_head || !json_files) { + if (!json_git) { + fmt::print(stderr, "cov report: /git: undefined\n"); + } else { + if (!json_git_branch) + fmt::print(stderr, "cov report: /git/branch: undefined\n"); + if (!json_git_head) + fmt::print(stderr, "cov report: /git/head: undefined\n"); + } + if (!json_files) + fmt::print(stderr, "cov report: /files: undefined\n"); + return false; + } files.reserve(json_files->size()); + auto file_index{std::numeric_limits::max()}; for (auto const& file_node : *json_files) { + ++file_index; + auto const json_file_name = cast_from_json(file_node, u8"name"sv); auto const json_file_digest = @@ -306,6 +321,25 @@ namespace cov::app::report { if (!json_file_name || !json_file_digest || !json_file_line_coverage) { + std::string format = "cov report: /files[{}]/{}"; + if (json_file_name) format += " ({})"; + format += ": undefined\n"; + if (!json_file_name) + fmt::print(stderr, fmt::runtime(format), file_index, + "name"sv, + json_file_name ? from_json(*json_file_name) + : std::string_view{}); + if (!json_file_digest) + fmt::print(stderr, fmt::runtime(format), file_index, + "digest"sv, + json_file_name ? from_json(*json_file_name) + : std::string_view{}); + if (!json_file_line_coverage) + fmt::print(stderr, fmt::runtime(format), file_index, + "line_coverage"sv, + json_file_name ? from_json(*json_file_name) + : std::string_view{}); + [[unlikely]]; files.clear(); return false; @@ -315,6 +349,8 @@ namespace cov::app::report { auto const pos = digest_view.find(':'); auto const algorithm = lookup_digest(digest_view.substr(0, pos)); if (pos == std::string_view::npos || algorithm == digest::unknown) { + fmt::print(stderr, "cov report: /file[{}]/digest ({}): '{}'\n", + file_index, from_json(*json_file_name), digest_view); [[unlikely]]; files.clear(); return false; @@ -333,6 +369,12 @@ namespace cov::app::report { unsigned line{}; if (!hits || !conv_rebase(node_key, line)) { + json::string val; + json::write_json(val, node_value, json::concise); + fmt::print(stderr, + "cov report: /file[{}]/line_coverage[{}]: {}\n", + file_index, from_json(*json_file_name), + from_json(node_key), from_json(val)); [[unlikely]]; files.clear(); return false; @@ -343,7 +385,10 @@ namespace cov::app::report { if (json_file_functions_coverage) { auto& cvg = dst.function_coverage; cvg.reserve(json_file_functions_coverage->size()); + + auto function_index{std::numeric_limits::max()}; for (auto const& node_file : *json_file_functions_coverage) { + ++function_index; auto const name = cast_from_json(node_file, u8"name"sv); auto const count = @@ -351,7 +396,36 @@ namespace cov::app::report { auto const start_line = cast_from_json(node_file, u8"start_line"sv); - if (!name || !count || !start_line) continue; + if (!name || !count || !start_line) { + std::string format = "cov report: /files[{}]/{}"; + if (json_file_name) format += " ({})"; + format += ": undefined\n"; + if (!name) + fmt::print( + stderr, + "cov report: /files[{}]/functions[{}]/name " + "({}): undefined", + file_index, function_index, + from_json(*json_file_name)); + if (!count) + fmt::print( + stderr, + "cov report: /files[{}]/functions[{}]/count " + "({}): undefined", + file_index, function_index, + from_json(*json_file_name)); + if (!start_line) + fmt::print(stderr, + "cov report: " + "/files[{}]/functions[{}]/start_line " + "({}): undefined", + file_index, function_index, + from_json(*json_file_name)); + + [[unlikely]]; + files.clear(); + return false; + } auto const demangled = cast_from_json( node_file, u8"demangled"sv); diff --git a/libs/cov-rt/src/report_command.cc b/libs/cov-rt/src/report_command.cc index de936e53..11924794 100644 --- a/libs/cov-rt/src/report_command.cc +++ b/libs/cov-rt/src/report_command.cc @@ -108,10 +108,12 @@ namespace cov::app::builtin::report { if (!result.report.load_from_text( report_contents(result.repo.git(), rest))) { if (filter_) { - error(tr_.format(replng::ERROR_FILTERED_REPORT_ISSUES, report_, - *filter_)); + simple_error(tr_, parser_.program(), + tr_.format(replng::ERROR_FILTERED_REPORT_ISSUES, + report_, *filter_)); } else { // GCOV_EXCL_LINE[WIN32] - error(tr_.format(replng::ERROR_REPORT_ISSUES, report_)); + simple_error(tr_, parser_.program(), + tr_.format(replng::ERROR_REPORT_ISSUES, report_)); } } result.props = cov::report::builder::properties(props_); diff --git a/tools/json_tests/nullify.py b/tools/json_tests/nullify.py index 53901c25..6a743353 100755 --- a/tools/json_tests/nullify.py +++ b/tools/json_tests/nullify.py @@ -9,11 +9,13 @@ from driver.test import Test __file_dir__ = os.path.dirname(__file__) -__root_dir__ = os.path.dirname(os.path.dirname(__file_dir__)) +__root_dir__ = os.path.abspath(os.path.dirname(os.path.dirname(__file_dir__))) __test_dir__ = os.path.join(__root_dir__, "apps", "tests") parser = argparse.ArgumentParser() -parser.add_argument("--tests", required=True, metavar="DIR") +parser.add_argument( + "--tests", required=True, metavar="DIR", default=[], action="append", nargs="+" +) parser.add_argument( "--lang", metavar="ID", @@ -28,9 +30,10 @@ def _enum_tests(args: argparse.Namespace): testsuite: List[str] = [] - for root, _, files in os.walk(args.tests): - for filename in files: - testsuite.append(os.path.join(root, filename)) + for testdir in args.tests: + for root, _, files in os.walk(testdir): + for filename in files: + testsuite.append(os.path.join(root, filename)) return testsuite @@ -53,9 +56,18 @@ def _load_tests(testsuite: List[str], run: List[str]): def __main__(): args = parser.parse_args() - args.tests = os.path.join(__test_dir__, args.tests) + args.tests = [testdir for group in args.tests for testdir in group] + for index in range(len(args.tests)): + testdir = args.tests[index] + if not os.path.isdir(f"{__test_dir__}/{testdir}") and os.path.isdir( + f"{__test_dir__}/main-set/{testdir}" + ): + testdir = f"main-set/{testdir}" + args.tests[index] = os.path.join(__test_dir__, testdir) testsuite = _enum_tests(args) - print("tests: ", args.tests) + print("tests:") + for testdir in args.tests: + print(f" - {testdir}") run = args.run diff --git a/tools/json_tests/runner.py b/tools/json_tests/runner.py index f6c8fc6a..9247807b 100755 --- a/tools/json_tests/runner.py +++ b/tools/json_tests/runner.py @@ -56,8 +56,6 @@ new_args.extend([("--run", run) for run in args.run]) -print(f"{__file_dir__}/test_driver.py", [item for arg in new_args for item in arg]) - sys.exit( subprocess.run( [ From 05a5f0e8d59d2e82f97ae2c75bb5deea00a06041 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 07:22:50 +0200 Subject: [PATCH 18/39] fix: don't report on non-existent files --- extensions/libs/collect-api/src/report.cc | 13 ++++++++++--- extensions/libs/collect-api/src/report.hh | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/extensions/libs/collect-api/src/report.cc b/extensions/libs/collect-api/src/report.cc index bda68553..a98a48ab 100644 --- a/extensions/libs/collect-api/src/report.cc +++ b/extensions/libs/collect-api/src/report.cc @@ -85,8 +85,14 @@ namespace cov::app::collect { } void report::post_process() { + std::vector to_remove{}; + to_remove.reserve(files_.size()); for (auto& [name, data] : files_) { - data->post_process(cfg_.src_dir / make_u8path(name)); + if (!data->post_process(cfg_.src_dir / make_u8path(name))) + to_remove.push_back(name); + } + for (auto const& name : to_remove) { + files_.erase(name); } } @@ -173,11 +179,11 @@ namespace cov::app::collect { std::make_move_iterator(src.functions_.end())); } - void report::file::post_process(std::filesystem::path const& path) { + bool report::file::post_process(std::filesystem::path const& path) { auto input = cov::io::fopen(path, "rb"); if (!input) { hash_.clear(); - return; + return false; } std::byte buffer[8192]; @@ -189,6 +195,7 @@ namespace cov::app::collect { hash_ = fmt::format("sha1:{}", m.finalize().str()); std::sort(functions_.begin(), functions_.end()); + return true; } json::node report::file::get_json(std::string_view filename) const { diff --git a/extensions/libs/collect-api/src/report.hh b/extensions/libs/collect-api/src/report.hh index 6c71dbc1..d9a6fc7c 100644 --- a/extensions/libs/collect-api/src/report.hh +++ b/extensions/libs/collect-api/src/report.hh @@ -62,7 +62,7 @@ namespace cov::app::collect { return functions_; } - void post_process(std::filesystem::path const& path); + bool post_process(std::filesystem::path const& path); json::node get_json(std::string_view filename) const; json::node get_lines() const; json::node get_functions() const; From e2fa691648a26b45c866af3cd018f6bff606280c Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 21:24:20 +0200 Subject: [PATCH 19/39] style: apply linter comments --- extensions/libs/collect-api/src/llvm.cc | 2 +- extensions/libs/collect-api/src/occ_xml.cc | 2 ++ extensions/libs/collect-api/src/occ_xml.hh | 3 +++ extensions/libs/collect-api/src/queue.hh | 9 +++++---- extensions/libs/collect-api/src/report.cc | 2 ++ extensions/libs/collect-api/src/thread_pool.cc | 6 +++--- extensions/libs/collect-api/src/thread_pool.hh | 5 +++-- extensions/libs/collect-api/src/toolkit.cc | 2 ++ extensions/libs/collect-api/src/toolkit.hh | 3 +++ extensions/libs/collect-api/src/walk.cc | 1 + extensions/libs/excludes/src/excludes.cc | 1 + extensions/libs/excludes/src/parser.hh | 2 ++ extensions/libs/native/include/native/expat.hh | 3 ++- 13 files changed, 30 insertions(+), 11 deletions(-) diff --git a/extensions/libs/collect-api/src/llvm.cc b/extensions/libs/collect-api/src/llvm.cc index edfb47ff..17e30926 100644 --- a/extensions/libs/collect-api/src/llvm.cc +++ b/extensions/libs/collect-api/src/llvm.cc @@ -131,7 +131,7 @@ namespace cov::app::collect { line_segments[0]->is_entry); auto mapped = !start_of_skipped_region && - ((wrapped_segment && wrapped_segment->has_count) or + ((wrapped_segment && wrapped_segment->has_count) || (min_region_count > 0)); if (!mapped) return result; diff --git a/extensions/libs/collect-api/src/occ_xml.cc b/extensions/libs/collect-api/src/occ_xml.cc index b0ec482f..48d223cc 100644 --- a/extensions/libs/collect-api/src/occ_xml.cc +++ b/extensions/libs/collect-api/src/occ_xml.cc @@ -4,7 +4,9 @@ #include "occ_xml.hh" #include #include +#include #include +#include // define DEBUG_IGNORE diff --git a/extensions/libs/collect-api/src/occ_xml.hh b/extensions/libs/collect-api/src/occ_xml.hh index b01795a7..676d9976 100644 --- a/extensions/libs/collect-api/src/occ_xml.hh +++ b/extensions/libs/collect-api/src/occ_xml.hh @@ -3,8 +3,11 @@ #pragma once +#include #include +#include #include +#include namespace cov::app::collect { struct msvc_context { diff --git a/extensions/libs/collect-api/src/queue.hh b/extensions/libs/collect-api/src/queue.hh index 3c6302b8..4c04f87f 100644 --- a/extensions/libs/collect-api/src/queue.hh +++ b/extensions/libs/collect-api/src/queue.hh @@ -7,17 +7,18 @@ #include #include #include +#include namespace cov { template - class queue { + class mt_queue { public: - queue() = default; - queue(queue const& other) { + mt_queue() = default; + mt_queue(mt_queue const& other) { std::lock_guard lock{other.m_}; items_ = other.items_; } - queue& operator=(queue const& other) { + mt_queue& operator=(mt_queue const& other) { std::unique_lock self{m_, std::defer_lock}; std::unique_lock lock{other.m_, std::defer_lock}; std::lock(self, lock); diff --git a/extensions/libs/collect-api/src/report.cc b/extensions/libs/collect-api/src/report.cc index a98a48ab..082510dc 100644 --- a/extensions/libs/collect-api/src/report.cc +++ b/extensions/libs/collect-api/src/report.cc @@ -3,12 +3,14 @@ #include "report.hh" #include +#include #include #include #include #include #include #include +#include using namespace std::literals; diff --git a/extensions/libs/collect-api/src/thread_pool.cc b/extensions/libs/collect-api/src/thread_pool.cc index f959b956..129bed3b 100644 --- a/extensions/libs/collect-api/src/thread_pool.cc +++ b/extensions/libs/collect-api/src/thread_pool.cc @@ -23,14 +23,14 @@ namespace cov { std::atomic counter{1}; void thread_pool::thread_proc(std::stop_token tok, - queue>& tasks) { + mt_queue>& tasks) { #if REPORT_TIMES using namespace std::chrono; size_t id{1}, internal{}; steady_clock::duration runtime{}; while (!counter.compare_exchange_weak(id, id + 1, - std::memory_order_relaxed)) - ; + std::memory_order_relaxed)) { + } #endif while (!tok.stop_requested()) { std::function task; diff --git a/extensions/libs/collect-api/src/thread_pool.hh b/extensions/libs/collect-api/src/thread_pool.hh index 2335fb1a..8b07b66e 100644 --- a/extensions/libs/collect-api/src/thread_pool.hh +++ b/extensions/libs/collect-api/src/thread_pool.hh @@ -6,6 +6,7 @@ #include #include #include +#include namespace cov { class thread_pool { @@ -17,8 +18,8 @@ namespace cov { private: static void thread_proc(std::stop_token, - queue>& tasks); - queue> tasks_{}; + mt_queue>& tasks); + mt_queue> tasks_{}; std::vector threads_{}; }; } // namespace cov diff --git a/extensions/libs/collect-api/src/toolkit.cc b/extensions/libs/collect-api/src/toolkit.cc index 92b57671..adff9d3f 100644 --- a/extensions/libs/collect-api/src/toolkit.cc +++ b/extensions/libs/collect-api/src/toolkit.cc @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include using namespace std::literals; diff --git a/extensions/libs/collect-api/src/toolkit.hh b/extensions/libs/collect-api/src/toolkit.hh index 79c4e308..d1528884 100644 --- a/extensions/libs/collect-api/src/toolkit.hh +++ b/extensions/libs/collect-api/src/toolkit.hh @@ -3,11 +3,14 @@ #pragma once +#include #include #include #include #include +#include #include +#include #include namespace cov::app::collect { diff --git a/extensions/libs/collect-api/src/walk.cc b/extensions/libs/collect-api/src/walk.cc index 6984f105..a698ce96 100644 --- a/extensions/libs/collect-api/src/walk.cc +++ b/extensions/libs/collect-api/src/walk.cc @@ -5,6 +5,7 @@ #include #include +#include #ifdef WIN32 #include diff --git a/extensions/libs/excludes/src/excludes.cc b/extensions/libs/excludes/src/excludes.cc index d032fddc..ae6bb7b5 100644 --- a/extensions/libs/excludes/src/excludes.cc +++ b/extensions/libs/excludes/src/excludes.cc @@ -3,6 +3,7 @@ #include "excludes.hh" #include +#include #include #include diff --git a/extensions/libs/excludes/src/parser.hh b/extensions/libs/excludes/src/parser.hh index bc082dc7..7523b455 100644 --- a/extensions/libs/excludes/src/parser.hh +++ b/extensions/libs/excludes/src/parser.hh @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include using namespace std::literals; diff --git a/extensions/libs/native/include/native/expat.hh b/extensions/libs/native/include/native/expat.hh index 9d0d8165..48733f54 100644 --- a/extensions/libs/native/include/native/expat.hh +++ b/extensions/libs/native/include/native/expat.hh @@ -97,9 +97,10 @@ namespace xml { if (expand) { XML_SetDefaultHandlerExpand(parser_, enable ? defaultHandler : nullptr); - } else + } else { XML_SetDefaultHandler(parser_, enable ? defaultHandler : nullptr); + } } void enableExternalEntityRefHandler(bool enable = true) { From b7c6edebea946d41079586d50323a4e9afe8f8b6 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 21:24:54 +0200 Subject: [PATCH 20/39] ci: move github secret to gh --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86afc8c8..07a4b295 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,6 +34,7 @@ jobs: BUILD_TYPE: ${{ matrix.build_type }} CONAN_REVISIONS_ENABLED: 1 FLOW_COMMAND: python ./flow.py run --github --cutdown-os -c os=${{ matrix.os }} build_type=${{ matrix.build_type }} compiler=${{ matrix.compiler }} sanitizer=${{ matrix.sanitizer }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} runs-on: ${{ matrix.github_os }} name: ${{ matrix.build_type }} with ${{ matrix.compiler }} on ${{ matrix.os }}${{ matrix.sanitizer && ' (and sanitizer)' || '' }} From 6522dc038765f62c8552d38a497783e11ed8b9b1 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 22:11:19 +0200 Subject: [PATCH 21/39] fix: cleanup code for clang 15 --- extensions/libs/collect-api/src/gnu.cc | 37 ++++++++++--------- extensions/libs/collect-api/src/llvm.cc | 2 +- .../libs/native/include/native/expat.hh | 12 +++++- extensions/libs/native/src/platform.cc | 4 +- libs/cov-rt/include/cov/app/report.hh | 16 +++++++- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/extensions/libs/collect-api/src/gnu.cc b/extensions/libs/collect-api/src/gnu.cc index 2636f847..f66eaa36 100644 --- a/extensions/libs/collect-api/src/gnu.cc +++ b/extensions/libs/collect-api/src/gnu.cc @@ -61,7 +61,7 @@ namespace cov::app::collect { int observe(config const&, std::string_view command, - args::arglist arguments) const { + args::arglist arguments) const override { return platform::call(make_u8path(command), arguments); } @@ -76,23 +76,24 @@ namespace cov::app::collect { closure state{.cfg = cfg, .cvg = cvg}; for (auto const& [dirname, filenames] : paths) { - state.push([&, this]() { - std::vector nodes; - - if (state.set_return_code( - load_directory(dirname, filenames, nodes))) - return; - - for (auto& node : nodes) { - state.push([this, &state, node = std::move(node)] { - auto const ret = - analyze_node(state.cfg, state.cvg, node); - state.task_finished(); - if (!ret) state.set_return_code(1); - }); - } - state.task_finished(); - }); + state.push( + [&, this, &dirname = dirname, &filenames = filenames]() { + std::vector nodes; + + if (state.set_return_code( + load_directory(dirname, filenames, nodes))) + return; + + for (auto& node : nodes) { + state.push([this, &state, node = std::move(node)] { + auto const ret = + analyze_node(state.cfg, state.cvg, node); + state.task_finished(); + if (!ret) state.set_return_code(1); + }); + } + state.task_finished(); + }); } return state.wait(); diff --git a/extensions/libs/collect-api/src/llvm.cc b/extensions/libs/collect-api/src/llvm.cc index 17e30926..da7b3ea1 100644 --- a/extensions/libs/collect-api/src/llvm.cc +++ b/extensions/libs/collect-api/src/llvm.cc @@ -215,7 +215,7 @@ namespace cov::app::collect { int observe(config const& cfg, std::string_view command, - args::arglist arguments) const { + args::arglist arguments) const override { auto const file_mask = get_u8path(cfg.bin_dir / prof_data_dir_ / "raw"sv / ("%p" + raw_ext_)); setenv("LLVM_PROFILE_FILE", file_mask.c_str(), 1); diff --git a/extensions/libs/native/include/native/expat.hh b/extensions/libs/native/include/native/expat.hh index 48733f54..80b70ba1 100644 --- a/extensions/libs/native/include/native/expat.hh +++ b/extensions/libs/native/include/native/expat.hh @@ -6,6 +6,10 @@ #include #include +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#endif namespace xml { template class ExpatBase { @@ -231,7 +235,7 @@ namespace xml { } template - auto bool2(boolean_like result) { + static auto bool2(boolean_like result) { return result ? true_value : false_value; } @@ -275,11 +279,12 @@ namespace xml { ptr(userData)->onDefault(data, length); } - static int externalEntityRefHandler(void* userData, + static int externalEntityRefHandler(XML_Parser parser, const XML_Char* context, const XML_Char* base, const XML_Char* systemID, const XML_Char* publicID) { + auto const userData = XML_GetUserData(parser); return bool2<1, 0>(ptr(userData)->onExternalEntityRef( context, base, systemID, publicID)); } @@ -325,3 +330,6 @@ namespace xml { XML_Parser parser_; }; } // namespace xml +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/extensions/libs/native/src/platform.cc b/extensions/libs/native/src/platform.cc index ec8389aa..c7ef2909 100644 --- a/extensions/libs/native/src/platform.cc +++ b/extensions/libs/native/src/platform.cc @@ -31,5 +31,5 @@ namespace cov::app::platform { } return result; - } -}; // namespace cov::app::platform + } // GCOV_EXCL_LINE +}; // namespace cov::app::platform diff --git a/libs/cov-rt/include/cov/app/report.hh b/libs/cov-rt/include/cov/app/report.hh index 5120fb5f..b47b4a23 100644 --- a/libs/cov-rt/include/cov/app/report.hh +++ b/libs/cov-rt/include/cov/app/report.hh @@ -53,7 +53,18 @@ namespace cov::app::report { std::string digest{}; std::map line_coverage{}; std::vector function_coverage{}; - auto operator<=>(file_info const&) const noexcept = default; + bool operator==(file_info const& rhs) const noexcept = default; + auto operator<=>(file_info const& rhs) const noexcept { + // without this definition, clang 16 does not like the + // function_coverage' spaceship... + if (auto const cmp = name <=> rhs.name; cmp != 0) return cmp; + if (auto const cmp = algorithm <=> rhs.algorithm; cmp != 0) + return cmp; + if (auto const cmp = digest <=> rhs.digest; cmp != 0) return cmp; + if (auto const cmp = line_coverage <=> rhs.line_coverage; cmp != 0) + return cmp; + return function_coverage <=> rhs.function_coverage; + } coverage_info expand_coverage(size_t line_count) const; }; @@ -67,7 +78,8 @@ namespace cov::app::report { git_info git{}; std::vector files{}; - auto operator<=>(report_info const&) const noexcept = default; + bool operator==(report_info const&) const noexcept = default; + auto operator<=>(report_info const& rhs) const noexcept = default; bool load_from_text(std::string_view u8_encoded); }; From e6fd51377f2e9a0351ba60676623fd438684bc61 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sat, 29 Jul 2023 22:28:04 +0200 Subject: [PATCH 22/39] fix: apply linter suggestions --- .github/workflows/build.yml | 2 +- CMakeLists.txt | 4 ---- libs/cov-rt/include/cov/app/report.hh | 15 +++++++++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07a4b295..df261725 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,7 +74,6 @@ jobs: sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 90 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-12 90 sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 90 - sudo locale-gen pl_PL.UTF-8 en_US.UTF-8 en_GB.UTF-8 - name: Set up Clang if: ${{ matrix.clang }} @@ -91,6 +90,7 @@ jobs: sudo rm -rf `which gcc-11` sudo rm -rf `which clang++-14` sudo rm -rf `which clang-14` + sudo locale-gen pl_PL.UTF-8 en_US.UTF-8 en_GB.UTF-8 - name: Install Conan id: conan diff --git a/CMakeLists.txt b/CMakeLists.txt index 7334fe09..0a4b8931 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,10 +194,6 @@ add_subdirectory(libs) add_subdirectory(extensions) add_subdirectory(apps) -message(STATUS "COV_TOOLS: ${COV_TOOLS}") -message(STATUS "COV_LIBS: ${COV_LIBS}") -message(STATUS "VS_MODS: ${VS_MODS}") - execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/packages/system.py props OUTPUT_VARIABLE COV_PROPERTIES OUTPUT_STRIP_TRAILING_WHITESPACE diff --git a/libs/cov-rt/include/cov/app/report.hh b/libs/cov-rt/include/cov/app/report.hh index b47b4a23..5cc387c1 100644 --- a/libs/cov-rt/include/cov/app/report.hh +++ b/libs/cov-rt/include/cov/app/report.hh @@ -57,12 +57,19 @@ namespace cov::app::report { auto operator<=>(file_info const& rhs) const noexcept { // without this definition, clang 16 does not like the // function_coverage' spaceship... - if (auto const cmp = name <=> rhs.name; cmp != 0) return cmp; - if (auto const cmp = algorithm <=> rhs.algorithm; cmp != 0) + if (auto const cmp = name <=> rhs.name; cmp != 0) { return cmp; - if (auto const cmp = digest <=> rhs.digest; cmp != 0) return cmp; - if (auto const cmp = line_coverage <=> rhs.line_coverage; cmp != 0) + } + if (auto const cmp = algorithm <=> rhs.algorithm; cmp != 0) { + return cmp; + } + if (auto const cmp = digest <=> rhs.digest; cmp != 0) { return cmp; + } + if (auto const cmp = line_coverage <=> rhs.line_coverage; + cmp != 0) { + return cmp; + } return function_coverage <=> rhs.function_coverage; } coverage_info expand_coverage(size_t line_count) const; From 55a1e41033a5f172dd027a4b3dcdd84c3e7d942c Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 07:29:41 +0200 Subject: [PATCH 23/39] ci: move token from secrets to sign.py (#69) * ci: turn non-release packages on * ci: move token from secrets to sign.py * ci: bring back the exclusive packages --- .github/workflows/build.yml | 2 ++ tools/win32/sign.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df261725..1b36bdd8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -142,6 +142,8 @@ jobs: id: artifacts if: ${{ fromJson(needs.M.outputs.RELEASE) }} run: ${{ env.FLOW_COMMAND }} -s Sign,Pack,SignPackages,StorePackages + env: + SIGN_TOKEN: ${{ secrets.SIGN_TOKEN }} # ## ## ######## ## ####### ### ######## # ## ## ## ## ## ## ## ## ## ## ## diff --git a/tools/win32/sign.py b/tools/win32/sign.py index 66bd88b8..86fc496b 100644 --- a/tools/win32/sign.py +++ b/tools/win32/sign.py @@ -13,7 +13,7 @@ __dir_name__ = os.path.dirname(__file__) __root_dir__ = os.path.dirname(os.path.dirname(__dir_name__)) -ENV_KEY = "SIGNATURE_KEY_SECRET" +ENV_KEY = "SIGN_TOKEN" Version = Tuple[int, int, int] From 8cc8bdd5e9b3de96a93a4fd7980afcb376c12dc7 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 07:46:51 +0200 Subject: [PATCH 24/39] ci: fix name on the self-signed certificate --- tools/win32/refresh-cert.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/win32/refresh-cert.ps1 b/tools/win32/refresh-cert.ps1 index dd8f778e..b6e59bc5 100644 --- a/tools/win32/refresh-cert.ps1 +++ b/tools/win32/refresh-cert.ps1 @@ -6,7 +6,7 @@ param( $params = @{ Type = 'Custom' Container = 'test*' - Subject = 'CN=Marcin Zdun, O=midnightBITS, L=Warszawa, C=PL' + Subject = 'CN=Marcin Zdun' TextExtension = @( '2.5.29.37={text}1.3.6.1.5.5.7.3.3', '2.5.29.17={text}email=mzdun@midnightbits.com' ) From 7949d577e3dd2eb717b1af4d425400a7202ffe0e Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 07:51:33 +0200 Subject: [PATCH 25/39] ci: use latest successfully uploaded Conan cache --- .github/workflows/flow.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flow.json b/.github/workflows/flow.json index c9188936..8899c4a0 100644 --- a/.github/workflows/flow.json +++ b/.github/workflows/flow.json @@ -21,7 +21,7 @@ "cpack_generator": ["TGZ", "DEB"], "ubuntu": true, "home": "/home/runner", - "latest_conan_hash": "e903f3ceb636ec2e496810737eb6033a1a8c39c227b437a0693d31086d8aa9df" + "latest_conan_hash": "0dbd3bbacea7ac58e0064195451c86646e20419f302f8539956ab60fa4b0bcfd" }, { "os": "windows", @@ -31,7 +31,7 @@ "cpack_generator": ["ZIP", "WIX"], "windows": true, "home": "C:/Users/runneradmin", - "latest_conan_hash": "1f8eec6aa067e5a60fc4f0ab2668dae66a983ae5902b1eda006f134b009f84eb" + "latest_conan_hash": "586b1c2983ee7a95473708c44799b6027035f6df0503ed7dbcbcf3d3d847dd0e" }, {"os": "ubuntu", "report_os": "Linux"}, {"compiler": "gcc", "report_compiler": "GNU", "gcc": true}, From bf47db6bb6f4b5320bf9e7523a478e5f889cfc46 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 08:19:25 +0200 Subject: [PATCH 26/39] chore: leave hex dump for posterity --- libs/app/src/posix/run.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libs/app/src/posix/run.cc b/libs/app/src/posix/run.cc index 26c9e5dd..24af66f1 100644 --- a/libs/app/src/posix/run.cc +++ b/libs/app/src/posix/run.cc @@ -11,6 +11,8 @@ #include #include "../path_env.hh" +// define STDOUT_DUMP + #ifdef RUNNING_GCOV extern "C" { #include @@ -143,6 +145,7 @@ namespace cov::app::platform { this, std::ref(src)); } +#ifdef STDOUT_DUMP static void dump(std::span buffer) { static constexpr auto len = 20zu; char line[len * 4 + 2]; @@ -160,7 +163,8 @@ namespace cov::app::platform { line[index * 3] = alphabet[(c >> 4) & 0xF]; line[index * 3 + 1] = alphabet[c & 0xF]; line[index * 3 + 2] = ' '; - line[len * 3 + index] = std::isprint(c) ? c : '.'; + line[len * 3 + index] = + std::isprint(c) ? static_cast(c) : '.'; ++index; } if (index < len) { @@ -173,6 +177,7 @@ namespace cov::app::platform { fputs(line, stdout); } } +#endif std::thread async_read(std::vector& dst) { return std::thread( @@ -183,7 +188,9 @@ namespace cov::app::platform { auto const actual = ::read(fd, buffer, std::size(buffer)); if (actual <= 0) break; - // dump({buffer, buffer + actual}); +#ifdef STDOUT_DUMP + dump({buffer, buffer + actual}); +#endif bytes.insert(bytes.end(), buffer, buffer + actual); } }, From 81b6133048cacc2c1a177d0c5b6353867445e2f8 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 14:27:56 +0200 Subject: [PATCH 27/39] test: cover strip-excludes --- apps/CMakeLists.txt | 1 + apps/tests/data/extensions.tar | Bin 0 -> 102400 bytes .../data/extensions/report-broken-A.json | 29 ++++ .../data/extensions/report-broken-B.json | 29 ++++ .../data/extensions/report-broken-C.json | 21 +++ apps/tests/data/extensions/report-llvm.json | 45 ++++++ apps/tests/data/extensions/report-multi.json | 89 +++++++++++ .../tests/data/extensions/report-no-such.json | 27 ++++ apps/tests/data/extensions/report-strip.json | 76 +++++++++ .../073-report-not-the-json-filtered.json | 2 +- .../015-filters-A/01-strip-excludes.json | 70 ++++++++ .../015-filters-A/02-strip-excludes-osOS.json | 70 ++++++++ .../03-A-strip-excludes-llvm.json | 47 ++++++ .../03-B-strip-excludes-clang.json | 47 ++++++ .../04-strip-excludes-compilerA-OS.json | 70 ++++++++ .../05-strip-excludes-multi.json | 57 +++++++ .../06-strip-excludes-no-such.json | 13 ++ .../07-A-strip-excludes-broken.json | 16 ++ .../07-B-strip-excludes-broken.json | 16 ++ .../07-C-strip-excludes-brokenjson | 16 ++ docs/roadmap.md | 2 + tools/flow/lib/matrix.py | 3 +- tools/json_tests/schema.json | 31 ++++ tools/run_ctest.py | 149 ++++++++++++++++++ 24 files changed, 924 insertions(+), 2 deletions(-) create mode 100644 apps/tests/data/extensions.tar create mode 100644 apps/tests/data/extensions/report-broken-A.json create mode 100644 apps/tests/data/extensions/report-broken-B.json create mode 100644 apps/tests/data/extensions/report-broken-C.json create mode 100644 apps/tests/data/extensions/report-llvm.json create mode 100644 apps/tests/data/extensions/report-multi.json create mode 100644 apps/tests/data/extensions/report-no-such.json create mode 100644 apps/tests/data/extensions/report-strip.json create mode 100644 apps/tests/main-set/015-filters-A/01-strip-excludes.json create mode 100644 apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json create mode 100644 apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json create mode 100644 apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json create mode 100644 apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json create mode 100644 apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json create mode 100644 apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json create mode 100644 apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json create mode 100644 apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json create mode 100644 apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson create mode 100644 tools/json_tests/schema.json create mode 100644 tools/run_ctest.py diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index fbdda9b4..802075ba 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -135,6 +135,7 @@ if (COV_TESTING) 012-checkout 013-reset 014-show + 015-filters-A ) add_test( NAME cov-exec--${TEST_SET} diff --git a/apps/tests/data/extensions.tar b/apps/tests/data/extensions.tar new file mode 100644 index 0000000000000000000000000000000000000000..a5b73acbad22be5505c538a97bb71665d19db95f GIT binary patch literal 102400 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 N111Jc42&@b{vTq!!~y^S literal 0 HcmV?d00001 diff --git a/apps/tests/data/extensions/report-broken-A.json b/apps/tests/data/extensions/report-broken-A.json new file mode 100644 index 00000000..dd084761 --- /dev/null +++ b/apps/tests/data/extensions/report-broken-A.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "digest": "sha1:8d9b6856ab8d5620a0f95b350e0e0a99c2f38216", + "line_coverage": { + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "39": 1 + }, + "functions": [ + { + "name": "partial_function_exclusion1", + "count": 0, + "start_line": 4, + "end_line": 10 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-broken-B.json b/apps/tests/data/extensions/report-broken-B.json new file mode 100644 index 00000000..4d9ae8f9 --- /dev/null +++ b/apps/tests/data/extensions/report-broken-B.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "main.cc", + "line_coverage": { + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "39": 1 + }, + "functions": [ + { + "name": "partial_function_exclusion1", + "count": 0, + "start_line": 4, + "end_line": 10 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-broken-C.json b/apps/tests/data/extensions/report-broken-C.json new file mode 100644 index 00000000..e4a3144c --- /dev/null +++ b/apps/tests/data/extensions/report-broken-C.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "main.cc", + "digest": "sha1:8d9b6856ab8d5620a0f95b350e0e0a99c2f38216", + "functions": [ + { + "name": "partial_function_exclusion1", + "count": 0, + "start_line": 4, + "end_line": 10 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-llvm.json b/apps/tests/data/extensions/report-llvm.json new file mode 100644 index 00000000..45601e53 --- /dev/null +++ b/apps/tests/data/extensions/report-llvm.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "llvm.cc", + "digest": "sha1:0aa758b8ddf6e4f546a353f20a4781fab8ff33fa", + "line_coverage": { + "3": 0, + "4": 0, + "5": 0, + "6": 0 + }, + "functions": [ + { + "name": "foo", + "count": 0, + "start_line": 1, + "end_line": 8 + } + ] + }, + { + "name": "clang.cc", + "digest": "sha1:a7d8793014e5e0dd0186427d7f49607fef1b7f36", + "line_coverage": { + "3": 0, + "4": 0, + "5": 0, + "6": 0 + }, + "functions": [ + { + "name": "foo", + "count": 0, + "start_line": 1, + "end_line": 8 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-multi.json b/apps/tests/data/extensions/report-multi.json new file mode 100644 index 00000000..e9fe4935 --- /dev/null +++ b/apps/tests/data/extensions/report-multi.json @@ -0,0 +1,89 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "no-exclusions.cc", + "digest": "sha1:7a8387f153415d9943ed4194242acbdd19be01a0", + "line_coverage": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1 + }, + "functions": [ + { + "name": "foo", + "count": 1, + "start_line": 1, + "end_line": 6 + } + ] + }, + { + "name": "start-start.cc", + "digest": "sha1:ca07ba87cceec9631bc941369dba40d424804d9b", + "line_coverage": { + "1": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "8": 1 + }, + "functions": [ + { + "name": "foo", + "count": 1, + "start_line": 1, + "end_line": 8 + } + ] + }, + { + "name": "start-end.cc", + "digest": "sha1:c37d4dd51a1a6d24bbe16ce734bd6939d0126750", + "line_coverage": { + "1": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "8": 1 + }, + "functions": [ + { + "name": "foo", + "count": 1, + "start_line": 1, + "end_line": 8 + } + ] + }, + { + "name": "start.cc", + "digest": "sha1:070cb0e88d0b5ea1dfb8c003ff3a74d895ca0a4e", + "line_coverage": { + "1": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1 + }, + "functions": [ + { + "name": "foo", + "count": 1, + "start_line": 1, + "end_line": 7 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-no-such.json b/apps/tests/data/extensions/report-no-such.json new file mode 100644 index 00000000..f0a7ce87 --- /dev/null +++ b/apps/tests/data/extensions/report-no-such.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "no-such-file.cc", + "digest": "sha1:0aa758b8ddf6e4f546a353f20a4781fab8ff33fa", + "line_coverage": { + "3": 0, + "4": 0, + "5": 0, + "6": 0 + }, + "functions": [ + { + "name": "foo", + "count": 0, + "start_line": 1, + "end_line": 8 + } + ] + } + ] +} diff --git a/apps/tests/data/extensions/report-strip.json b/apps/tests/data/extensions/report-strip.json new file mode 100644 index 00000000..01b06bc2 --- /dev/null +++ b/apps/tests/data/extensions/report-strip.json @@ -0,0 +1,76 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.21.1/apps/report-schema.json", + "git": { + "branch": "main", + "head": "98d4978ecbddf677c1e6bf5a40da84bd0b337340" + }, + "files": [ + { + "name": "main.cc", + "digest": "sha1:8d9b6856ab8d5620a0f95b350e0e0a99c2f38216", + "line_coverage": { + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0, + "9": 0, + "10": 0, + "14": 4, + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "25": 5, + "28": 0, + "29": 0, + "30": 0, + "31": 0, + "32": 0, + "33": 0, + "37": 1, + "38": 1, + "39": 1 + }, + "functions": [ + { + "name": "partial_function_exclusion1", + "count": 0, + "start_line": 4, + "end_line": 10 + }, + { + "name": "sep1", + "count": 0, + "start_line": 14 + }, + { + "name": "partial_function_exclusion2", + "count": 0, + "start_line": 17, + "end_line": 23 + }, + { + "name": "sep2", + "count": 1, + "start_line": 25 + }, + { + "name": "full_function_exclusion", + "count": 0, + "start_line": 28, + "end_line": 33 + }, + { + "name": "main", + "count": 1, + "start_line": 37, + "end_line": 39 + } + ] + } + ] +} diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index 20bb4100..4607645b 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -5,7 +5,7 @@ "", [ "cov report: /git: undefined", - "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter" + "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter\n" ] ], "prepare": [ diff --git a/apps/tests/main-set/015-filters-A/01-strip-excludes.json b/apps/tests/main-set/015-filters-A/01-strip-excludes.json new file mode 100644 index 00000000..beb55dd8 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/01-strip-excludes.json @@ -0,0 +1,70 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-strip.json'", + "post": [ + "show HEAD:main.cc" + ], + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " one file, \u001b[31m 33%\u001b[m (5/15, -10), Fn\u001b[31m 40%\u001b[m (2/5)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 33%\u001b[m", + "", + "file main.cc", + "blob 8413b254a0751500a3f50ecb1dd93ae4fbf12658", + "functions 2efee5e14da1591abe9e2af91e246c6e38199117", + "lines 6277d9678915703ea7af2326a3e214fc053e8cb6", + "stats 40 15 5, 5 2, 0 0", + "", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| Name | % Funcs | Missing | % Lines | Visited | Relevant | Missing | Line count |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| main.cc | 40.00 +40.00 | 3 +3 | 33.33 +33.33 | 5 +5 | 15 +15 | 10 +10 | 40 +40 |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "", + " 1 | | module;", + " 2 | | import std;", + " 3 | | ", + " 0x | partial_function_exclusion1", + " 4 | 0x | -void partial_function_exclusion() /*after*/ {", + " 5 | 0x | - line1();", + " 6 | 0x | -// GCOV_EXCL_START[OS]", + " 7 | 0x | - line2();", + " 8 | 0x | - line3();", + " 9 | 0x | - line4();", + " 10 | 0x | -}", + " 11 | | ", + " 12 | | // GCOV_EXCL_STOP", + " 13 | | ", + " 0x | sep1", + " 14 | 4x | +void sep1() {}", + " 15 | | // GCOV_EXCL_START", + " 16 | | ", + " 0x | partial_function_exclusion2", + " 17 | | void partial_function_exclusion1() /*before*/ {", + " 18 | | line1();", + " 19 | | line2();", + " 20 | | // GCOV_EXCL_STOP", + " 21 | 0x | - line3();", + " 22 | 0x | - line4();", + " 23 | 0x | -}", + " 24 | | ", + " 1x | sep2", + " 25 | 5x | +void sep2() {}", + " 26 | | ", + "\n" + ], + "strip-excludes: excluded 10 lines, 1 function\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json new file mode 100644 index 00000000..3ed91f30 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json @@ -0,0 +1,70 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS", + "post": [ + "show HEAD:main.cc" + ], + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " one file, \u001b[31m 50%\u001b[m (5/10, -5), Fn\u001b[31m 40%\u001b[m (2/5)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 50%\u001b[m", + "", + "file main.cc", + "blob 8413b254a0751500a3f50ecb1dd93ae4fbf12658", + "functions 2efee5e14da1591abe9e2af91e246c6e38199117", + "lines b0815db9957ba028c131708a2bb7df42d5084aaf", + "stats 40 10 5, 5 2, 0 0", + "", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| Name | % Funcs | Missing | % Lines | Visited | Relevant | Missing | Line count |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| main.cc | 40.00 +40.00 | 3 +3 | 50.00 +50.00 | 5 +5 | 10 +10 | 5 +5 | 40 +40 |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "", + " 1 | | module;", + " 2 | | import std;", + " 3 | | ", + " 0x | partial_function_exclusion1", + " 4 | 0x | -void partial_function_exclusion() /*after*/ {", + " 5 | 0x | - line1();", + " 6 | | // GCOV_EXCL_START[OS]", + " 7 | | line2();", + " 8 | | line3();", + " 9 | | line4();", + " 10 | | }", + " 11 | | ", + " 12 | | // GCOV_EXCL_STOP", + " 13 | | ", + " 0x | sep1", + " 14 | 4x | +void sep1() {}", + " 15 | | // GCOV_EXCL_START", + " 16 | | ", + " 0x | partial_function_exclusion2", + " 17 | | void partial_function_exclusion1() /*before*/ {", + " 18 | | line1();", + " 19 | | line2();", + " 20 | | // GCOV_EXCL_STOP", + " 21 | 0x | - line3();", + " 22 | 0x | - line4();", + " 23 | 0x | -}", + " 24 | | ", + " 1x | sep2", + " 25 | 5x | +void sep2() {}", + " 26 | | ", + "\n" + ], + "strip-excludes: excluded 15 lines, 1 function\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json new file mode 100644 index 00000000..6308eda9 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json @@ -0,0 +1,47 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler llvm", + "post": "show", + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", + "report [0-9a-f]{40}": "report $OID", + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", + "Added: .*": "Added: $DATE" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " 2 files, \u001b[31m 0%\u001b[m (0/0), Fn\u001b[31m 0%\u001b[m (0/2)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m", + "", + "report $OID", + "commit 98d4978ecbddf677c1e6bf5a40da84bd0b337340", + "build $BUILD_HASH [ 0%]", + "GitBranch: main", + "Coverage: [ 0%] 0/0 (fail)", + "Functions: [ 0%] 0/2 (fail)", + "Author: Johnny Appleseed ", + "Added: $DATE", + "", + " Commit \"extensions\"", + "", + "+------------+---------+---------+---------+---------+----------+------------+", + "| Name | % Funcs | Missing | % Lines | Visited | Relevant | Line count |", + "+------------+---------+---------+---------+---------+----------+------------+", + "| clang.cc | 0.00 | 1 +1 | 0.00 | 0 | 0 | 8 +8 |", + "| llvm.cc | 0.00 | 1 +1 | 0.00 | 0 | 0 | 8 +8 |", + "+------------+---------+---------+---------+---------+----------+------------+", + "| > TOTAL | 0.00 | 2 +2 | 0.00 | 0 | 0 | 16 +16 |", + "+------------+---------+---------+---------+---------+----------+------------+\n" + ], + "strip-excludes: excluded 8 lines\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json new file mode 100644 index 00000000..228b1b53 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json @@ -0,0 +1,47 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler clang", + "post": "show", + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", + "report [0-9a-f]{40}": "report $OID", + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", + "Added: .*": "Added: $DATE" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " 2 files, \u001b[31m 0%\u001b[m (0/0), Fn\u001b[31m 0%\u001b[m (0/2)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m", + "", + "report $OID", + "commit 98d4978ecbddf677c1e6bf5a40da84bd0b337340", + "build $BUILD_HASH [ 0%]", + "GitBranch: main", + "Coverage: [ 0%] 0/0 (fail)", + "Functions: [ 0%] 0/2 (fail)", + "Author: Johnny Appleseed ", + "Added: $DATE", + "", + " Commit \"extensions\"", + "", + "+------------+---------+---------+---------+---------+----------+------------+", + "| Name | % Funcs | Missing | % Lines | Visited | Relevant | Line count |", + "+------------+---------+---------+---------+---------+----------+------------+", + "| clang.cc | 0.00 | 1 +1 | 0.00 | 0 | 0 | 8 +8 |", + "| llvm.cc | 0.00 | 1 +1 | 0.00 | 0 | 0 | 8 +8 |", + "+------------+---------+---------+---------+---------+----------+------------+", + "| > TOTAL | 0.00 | 2 +2 | 0.00 | 0 | 0 | 16 +16 |", + "+------------+---------+---------+---------+---------+----------+------------+\n" + ], + "strip-excludes: excluded 8 lines\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json new file mode 100644 index 00000000..a4166838 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json @@ -0,0 +1,70 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS --compiler compilerA", + "post": [ + "show HEAD:main.cc" + ], + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " one file, \u001b[31m 29%\u001b[m (2/7, -5), Fn\u001b[31m 25%\u001b[m (1/4)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 29%\u001b[m", + "", + "file main.cc", + "blob 8413b254a0751500a3f50ecb1dd93ae4fbf12658", + "functions 14f0e1233783a10d5073ddcd060500201cf35c29", + "lines 901e3f666456f35c146cbd93cb9b95b2ad1fa5c0", + "stats 40 7 2, 4 1, 0 0", + "", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| Name | % Funcs | Missing | % Lines | Visited | Relevant | Missing | Line count |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "| main.cc | 25.00 +25.00 | 3 +3 | 28.57 +28.57 | 2 +2 | 7 +7 | 5 +5 | 40 +40 |", + "+-----------+--------------+---------+--------------+---------+----------+---------+------------+", + "", + " 1 | | module;", + " 2 | | import std;", + " 3 | | ", + " 0x | partial_function_exclusion1", + " 4 | 0x | -void partial_function_exclusion() /*after*/ {", + " 5 | 0x | - line1();", + " 6 | | // GCOV_EXCL_START[OS]", + " 7 | | line2();", + " 8 | | line3();", + " 9 | | line4();", + " 10 | | }", + " 11 | | ", + " 12 | | // GCOV_EXCL_STOP", + " 13 | | ", + " 0x | sep1", + " 14 | 4x | +void sep1() {}", + " 15 | | // GCOV_EXCL_START", + " 16 | | ", + " 0x | partial_function_exclusion2", + " 17 | | void partial_function_exclusion1() /*before*/ {", + " 18 | | line1();", + " 19 | | line2();", + " 20 | | // GCOV_EXCL_STOP", + " 21 | 0x | - line3();", + " 22 | 0x | - line4();", + " 23 | 0x | -}", + " 24 | | ", + " 1x | sep2", + " 25 | 5x | +void sep2() {}", + " 26 | | ", + "\n" + ], + "strip-excludes: excluded 18 lines, 2 functions\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json new file mode 100644 index 00000000..1822f36a --- /dev/null +++ b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json @@ -0,0 +1,57 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-multi.json'", + "post": "show", + "patches": { + "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", + " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", + "report [0-9a-f]{40}": "report $OID", + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", + "Added: .*": "Added: $DATE" + }, + "expected": [ + 0, + [ + "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", + " 4 files, \u001b[32m100%\u001b[m (9/9), Fn\u001b[32m100%\u001b[m (4/4)", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", + " parent 45c01b5bd", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[32m100%\u001b[m", + "", + "report $OID", + "commit 98d4978ecbddf677c1e6bf5a40da84bd0b337340", + "build $BUILD_HASH [100%]", + "GitBranch: main", + "Coverage: [100%] 9/9 (pass)", + "Functions: [100%] 4/4 (pass)", + "Author: Johnny Appleseed ", + "Added: $DATE", + "", + " Commit \"extensions\"", + "", + "+--------------------+----------------+----------------+---------+----------+------------+", + "| Name | % Funcs | % Lines | Visited | Relevant | Line count |", + "+--------------------+----------------+----------------+---------+----------+------------+", + "| no-exclusions.cc | 100.00 +100.00 | 100.00 +100.00 | 6 +6 | 6 +6 | 6 +6 |", + "| start-end.cc | 100.00 +100.00 | 100.00 +100.00 | 1 +1 | 1 +1 | 8 +8 |", + "| start-start.cc | 100.00 +100.00 | 100.00 +100.00 | 1 +1 | 1 +1 | 8 +8 |", + "| start.cc | 100.00 +100.00 | 100.00 +100.00 | 1 +1 | 1 +1 | 7 +7 |", + "+--------------------+----------------+----------------+---------+----------+------------+", + "| > TOTAL | 100.00 +100.00 | 100.00 +100.00 | 9 +9 | 9 +9 | 29 +29 |", + "+--------------------+----------------+----------------+---------+----------+------------+\n" + ], + [ + "\u001b[1;37m$TMP/extensions/start-start.cc:7:8:\u001b[m \u001b[1;35mwarning:\u001b[m double start: found GCOV_EXCL_START", + "\u001b[1;37m$TMP/extensions/start-start.cc:2:8:\u001b[m \u001b[1;36mnote:\u001b[m see previous start", + "\u001b[1;37m$TMP/extensions/start-start.cc:2:8:\u001b[m \u001b[1;35mwarning:\u001b[m GCOV_EXCL_START not matched with GCOV_EXCL_STOP", + "\u001b[1;37m$TMP/extensions/start-end.cc:7:8:\u001b[m \u001b[1;35mwarning:\u001b[m found GCOV_EXCL_END; did you mean GCOV_EXCL_STOP?", + "\u001b[1;37m$TMP/extensions/start-end.cc:2:8:\u001b[m \u001b[1;35mwarning:\u001b[m GCOV_EXCL_START not matched with GCOV_EXCL_STOP", + "\u001b[1;37m$TMP/extensions/start.cc:2:8:\u001b[m \u001b[1;35mwarning:\u001b[m GCOV_EXCL_START not matched with GCOV_EXCL_STOP", + "strip-excludes: excluded 15 lines\n" + ] + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json new file mode 100644 index 00000000..891f1ec8 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json @@ -0,0 +1,13 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-no-such.json'", + "expected": [ + 1, + "", + "cov report: error: cannot find no-such-file.cc\n" + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json new file mode 100644 index 00000000..0ed7efc4 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-broken-A.json'", + "expected": [ + 2, + "", + [ + "cov report: /files[0]/name: undefined", + "cov report: error: there were issues with $DATA/extensions/report-broken-A.json processed by strip-excludes filter\n" + ] + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json new file mode 100644 index 00000000..7304077b --- /dev/null +++ b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-broken-B.json'", + "expected": [ + 2, + "", + [ + "cov report: /files[0]/digest (main.cc): undefined", + "cov report: error: there were issues with $DATA/extensions/report-broken-B.json processed by strip-excludes filter\n" + ] + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson new file mode 100644 index 00000000..df235543 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson @@ -0,0 +1,16 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-broken-C.json'", + "expected": [ + 2, + "", + [ + "cov report: /files[0]/line_coverage (main.cc): undefined", + "cov report: error: there were issues with $DATA/extensions/report-broken-C.json processed by strip-excludes filter\n" + ] + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/docs/roadmap.md b/docs/roadmap.md index 92cba08e..a6f1c11d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -80,6 +80,8 @@ - Update schema id and references in filters - [ ] change `SHARE_DIR` to `share/cov-${PROJECT_VERSION_MAJOR}` - [ ] Freeze translation IDs (mzdun/cov#63) +- [ ] Post-release issues + - [ ] support `cov show --oneline` (see `matrix.py`'s Report) - [ ] `cov serve` - [ ] Boost.Beast WS - [ ] React frontend diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 5507906b..81ce4687 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -28,6 +28,7 @@ _platform_name, _platform_version, _platform_arch = uname() _collect_version = (0, 22, 0) +_report_version = (0, 20, 0) platform = _platform_name @@ -548,8 +549,8 @@ def dev_inst(config: dict): ) def report(config: dict): cov_exe = steps.get_bin(_collect_version, config) + reporter = steps.get_bin(_report_version, config) - reporter = f"build/{config['preset']}/bin/cov" try: tag_process = subprocess.run([reporter, "tag"], stdout=subprocess.PIPE) tags = ( diff --git a/tools/json_tests/schema.json b/tools/json_tests/schema.json new file mode 100644 index 00000000..179c3fed --- /dev/null +++ b/tools/json_tests/schema.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "required": ["args", "expected"], + "properties": { + "$schema": {"type": "string"}, + "linear": {"type": "boolean"}, + "disabled": {"type": ["string", "boolean"]}, + "lang": {"type": "boolean"}, + "args": {"type": "string"}, + "post": {"type": ["string", "array"], "items": {"type": "string"}}, + "expected": {"type": ["array", "null"]}, + "patches": { + "type": "object", + "properties": { + "^$": {"not": {}}, + "^.+$": {"type": "string"} + } + }, + "prepare": { + "type": ["string", "array"], + "items": {"type": ["string", "array"], "items": {"type": "string"}} + }, + "cleanup": { + "type": ["string", "array"], + "items": {"type": ["string", "array"], "items": {"type": "string"}} + } + }, + "additionalProperties": false, + "default": {} +} \ No newline at end of file diff --git a/tools/run_ctest.py b/tools/run_ctest.py new file mode 100644 index 00000000..19a7c6f8 --- /dev/null +++ b/tools/run_ctest.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +import json +import os +import subprocess +import sys +import shlex +from pprint import pprint +from typing import Dict, List + +from github.cmake import _cmake + + +def _test_directory(preset_name: str): + configs, presets = _load_presets("CMakePresets.json") + stack = [preset_name] + while len(stack): + next = stack[0] + stack = stack[1:] + preset = presets.get(next) + if preset is None: + continue + + if preset[0] is not None: + bin_dir = _get_bin_dir(configs, preset[0]) + if bin_dir is not None: + return bin_dir + stack.extend(reversed(preset[1])) + + return None + + +def _get_bin_dir(configs: Dict[str, tuple], preset_name: str): + stack = [preset_name] + while len(stack): + next = stack[0] + stack = stack[1:] + preset = configs.get(next) + if preset is None: + continue + + if preset[0] is not None: + return preset[0] + + stack.extend(reversed(preset[1])) + + return None + + +def _load_presets(path: str, known: List[str] = []): + path = os.path.abspath(path) + dirname = os.path.dirname(path) + if path in known: + return ({}, {}) + known.append(path) + + with open(path, encoding="UTF-8") as root_json: + presets = json.load(root_json) + + configures: Dict[str, tuple] = {} + for configurePreset in presets.get("configurePresets", []): + name = configurePreset.get("name") + if name is None: + continue + binaryDir = configurePreset.get("binaryDir") + inherits = configurePreset.get("inherits", []) + configures[name] = (binaryDir, inherits) + + tests: Dict[str, tuple] = {} + for testPreset in presets.get("testPresets", []): + name = testPreset.get("name") + if name is None: + continue + configurePreset = testPreset.get("configurePreset") + inherits = testPreset.get("inherits", []) + tests[name] = (configurePreset, inherits) + + includes = presets.get("include", []) + for include in includes: + sub_cfgs, sub_tests = _load_presets(os.path.join(dirname, include), known) + for name, cfg in sub_cfgs.items(): + configures[name] = cfg + for name, test in sub_tests.items(): + tests[name] = test + + return (configures, tests) + + +def _load_tests(dirname: str): + commands = _cmake(os.path.join(dirname, "CTestTestfile.cmake")) + + tests: Dict[str, List[str]] = {} + + for command in commands: + if command.name == "set_tests_properties": + continue + if command.name == "subdirs": + if len(command.args): + sub = _load_tests(os.path.join(dirname, command.args[0].value)) + for name, cmd in sub.items(): + tests[name] = cmd + continue + + if command.name == "add_test": + if len(command.args) > 1: + name = command.args[0].value[3:-3] + cmd = [arg.value for arg in command.args[1:]] + tests[name] = cmd + continue + + pprint((dirname, command)) + + return tests + + +def _print_arg(arg: str): + cwd = os.getcwd().replace("\\", "/") + cwd += "/" + if arg[: len(cwd)] == cwd: + arg = arg[len(cwd) :] + color = "" + if arg[:1] == "-": + color = "\033[2;37m" + arg = shlex.join([arg.replace("\\", "/")]) + if color == "" and arg[:1] in ["'", '"']: + color = "\033[2;34m" + if color == "": + return arg + return f"{color}{arg}\033[m" + + +def print_args(*args: str): + cmd = shlex.join([args[0]]) + args = " ".join([_print_arg(arg) for arg in args[1:]]) + print(f"\033[33m{cmd}\033[m {args}", file=sys.stderr) + + +bin_dir = _test_directory(sys.argv[1]) +if bin_dir is None: + sys.exit(1) + +bin_dir = bin_dir.replace("${sourceDir}/", "./") +tests = _load_tests(bin_dir) +if len(sys.argv) < 3: + print("known test:", " ".join(tests.keys())) + sys.exit(0) +test = [*tests[sys.argv[2]], *sys.argv[3:]] +print_args(*test) +subprocess.run(test, shell=False) From 57d514c063ee0781f7a34f4c0e983b8bc90c370e Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 20:54:44 +0200 Subject: [PATCH 28/39] test: cover `cov collect` (part 1) --- .covcollect | 4 + CMakeGraphVizOptions.cmake | 1 + CMakeLists.txt | 5 +- apps/CMakeLists.txt | 1 + .../tests/data/covcollect/OpenCppCoverage.xml | 35 ++++++++ apps/tests/data/covcollect/ini | 7 ++ .../main-set/016-collect/01-collect-help.json | 20 +++++ .../016-collect/02-collect-unborn.json | 15 ++++ .../016-collect/03-collect-no-HEAD.json | 18 +++++ .../016-collect/04-collect-too-many-args.json | 19 +++++ .../05-collect-too-little-args.json | 19 +++++ .../016-collect/06-collect-observe.json | 19 +++++ .../016-collect/07-collect-clang.json | 37 +++++++++ .../main-set/016-collect/08-collect-gcc.json | 33 ++++++++ .../016-collect/09-collect-gcc-triple.json | 19 +++++ .../016-collect/10-collect-clean.json | 19 +++++ .../016-collect/11-collect-no-output.json | 33 ++++++++ .../main-set/016-collect/12-collect-msvc.json | 36 +++++++++ extensions/CMakeLists.txt | 1 + extensions/tests/CMakeLists.txt | 33 ++++++++ extensions/tests/mock_cl.cc | 10 +++ extensions/tests/mock_clang.cc | 16 ++++ extensions/tests/mock_gcc.cc | 14 ++++ extensions/tests/mock_gcov.cc | 4 + extensions/tests/mock_llvm_cov.cc | 4 + extensions/tests/mock_llvm_profdata.cc | 4 + extensions/tests/mock_occ.cc | 4 + tools/json_tests/driver/commands.py | 3 + tools/json_tests/driver/test.py | 79 ++++++++++++++++++- tools/json_tests/driver/testbed.py | 1 + tools/json_tests/schema.json | 4 +- tools/json_tests/test_driver.py | 1 + 32 files changed, 514 insertions(+), 4 deletions(-) create mode 100644 .covcollect create mode 100644 apps/tests/data/covcollect/OpenCppCoverage.xml create mode 100644 apps/tests/data/covcollect/ini create mode 100644 apps/tests/main-set/016-collect/01-collect-help.json create mode 100644 apps/tests/main-set/016-collect/02-collect-unborn.json create mode 100644 apps/tests/main-set/016-collect/03-collect-no-HEAD.json create mode 100644 apps/tests/main-set/016-collect/04-collect-too-many-args.json create mode 100644 apps/tests/main-set/016-collect/05-collect-too-little-args.json create mode 100644 apps/tests/main-set/016-collect/06-collect-observe.json create mode 100644 apps/tests/main-set/016-collect/07-collect-clang.json create mode 100644 apps/tests/main-set/016-collect/08-collect-gcc.json create mode 100644 apps/tests/main-set/016-collect/09-collect-gcc-triple.json create mode 100644 apps/tests/main-set/016-collect/10-collect-clean.json create mode 100644 apps/tests/main-set/016-collect/11-collect-no-output.json create mode 100644 apps/tests/main-set/016-collect/12-collect-msvc.json create mode 100644 extensions/tests/CMakeLists.txt create mode 100644 extensions/tests/mock_cl.cc create mode 100644 extensions/tests/mock_clang.cc create mode 100644 extensions/tests/mock_gcc.cc create mode 100644 extensions/tests/mock_gcov.cc create mode 100644 extensions/tests/mock_llvm_cov.cc create mode 100644 extensions/tests/mock_llvm_profdata.cc create mode 100644 extensions/tests/mock_occ.cc diff --git a/.covcollect b/.covcollect new file mode 100644 index 00000000..f8b6acfe --- /dev/null +++ b/.covcollect @@ -0,0 +1,4 @@ +[collect] + compiler = /home/marcin/code/coverage/git2-cxx/apps/tests/copy/mocks/g++ + bin-dir = build/ + src-dir = . diff --git a/CMakeGraphVizOptions.cmake b/CMakeGraphVizOptions.cmake index 28063e1f..cd6fcefc 100644 --- a/CMakeGraphVizOptions.cmake +++ b/CMakeGraphVizOptions.cmake @@ -7,4 +7,5 @@ set(GRAPHVIZ_IGNORE_TARGETS "CONAN_LIB::.*" ".*-test" cov-echo cov-pwd + "mock-.*" ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a4b8931..3260f037 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,10 @@ if (COV_TESTING) list(APPEND INCLUDED_IN_COVERAGE libs/hilite/hilite-${extra}/src) endforeach() - set(EXCLUDED_FROM_COVERAGE apps/tests) + set(EXCLUDED_FROM_COVERAGE + apps/tests + extensions/tests + ) foreach(extension collect-api excludes diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 802075ba..0e286aa5 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -136,6 +136,7 @@ if (COV_TESTING) 013-reset 014-show 015-filters-A + 016-collect ) add_test( NAME cov-exec--${TEST_SET} diff --git a/apps/tests/data/covcollect/OpenCppCoverage.xml b/apps/tests/data/covcollect/OpenCppCoverage.xml new file mode 100644 index 00000000..418efa95 --- /dev/null +++ b/apps/tests/data/covcollect/OpenCppCoverage.xml @@ -0,0 +1,35 @@ + + + + $SOURCES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/tests/data/covcollect/ini b/apps/tests/data/covcollect/ini new file mode 100644 index 00000000..b8923d28 --- /dev/null +++ b/apps/tests/data/covcollect/ini @@ -0,0 +1,7 @@ +[collect] + compiler = $COMPILER + bin-dir = build/ + src-dir = . + include = src + include = include + exclude = src/test diff --git a/apps/tests/main-set/016-collect/01-collect-help.json b/apps/tests/main-set/016-collect/01-collect-help.json new file mode 100644 index 00000000..1b956e80 --- /dev/null +++ b/apps/tests/main-set/016-collect/01-collect-help.json @@ -0,0 +1,20 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect -h", + "expected": [ + 0, + [ + "usage: cov-collect [-h] [-c ARG] [--clean] [--observe]", + "", + "optional arguments:", + " -h, --help show this help message and exit", + " -c, --config ARG ", + " --clean ", + " --observe \n" + ], + "" + ], + "prepare": [ + "cd '$TMP'" + ] +} diff --git a/apps/tests/main-set/016-collect/02-collect-unborn.json b/apps/tests/main-set/016-collect/02-collect-unborn.json new file mode 100644 index 00000000..653d5a42 --- /dev/null +++ b/apps/tests/main-set/016-collect/02-collect-unborn.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "expected": [ + 1, + "", + "[git] called on unborn branch\n" + ], + "prepare": [ + "mkdirs '$TMP/unborn'", + "cd '$TMP/unborn'", + "git init", + "cov init" + ] +} diff --git a/apps/tests/main-set/016-collect/03-collect-no-HEAD.json b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json new file mode 100644 index 00000000..3168845c --- /dev/null +++ b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json @@ -0,0 +1,18 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "disabled": true, + "args": "collect", + "expected": [ + 1, + "", + "[git] called on unborn branch\n" + ], + "prepare": [ + "mkdirs '$TMP/unborn'", + "cd '$TMP/unborn'", + "git init", + "cov init", + "mkdirs .git/refs/heads", + "touch .git/refs/heads/main 'ref: refs/heads/main\n'" + ] +} diff --git a/apps/tests/main-set/016-collect/04-collect-too-many-args.json b/apps/tests/main-set/016-collect/04-collect-too-many-args.json new file mode 100644 index 00000000..c1384656 --- /dev/null +++ b/apps/tests/main-set/016-collect/04-collect-too-many-args.json @@ -0,0 +1,19 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect ctest -C Debug .", + "expected": [ + 2, + "", + [ + "usage: cov-collect [-h] [-c ARG] [--clean] [--observe]", + "cov-collect: error: unrecognized argument: ctest\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/observe'", + "cd '$TMP/observe'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty" + ] +} diff --git a/apps/tests/main-set/016-collect/05-collect-too-little-args.json b/apps/tests/main-set/016-collect/05-collect-too-little-args.json new file mode 100644 index 00000000..fdc4c3bb --- /dev/null +++ b/apps/tests/main-set/016-collect/05-collect-too-little-args.json @@ -0,0 +1,19 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect --observe", + "expected": [ + 2, + "", + [ + "usage: cov-collect [-h] [-c ARG] [--clean] [--observe]", + "cov-collect: error: argument --observe: missing tool name and arguments\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/observe'", + "cd '$TMP/observe'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty" + ] +} diff --git a/apps/tests/main-set/016-collect/06-collect-observe.json b/apps/tests/main-set/016-collect/06-collect-observe.json new file mode 100644 index 00000000..10edff9b --- /dev/null +++ b/apps/tests/main-set/016-collect/06-collect-observe.json @@ -0,0 +1,19 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect --observe ctest -C Debug .", + "expected": [ + 0, + "Test project $TMP/observe\n", + "No tests were found!!!\n" + ], + "prepare": [ + "mkdirs '$TMP/observe'", + "cd '$TMP/observe'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mock hal9000-lcars-GLaDOS-g++-17 g++", + "mock hal9000-lcars-GLaDOS-gcov-17 gcov", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/g++'" + ] +} diff --git a/apps/tests/main-set/016-collect/07-collect-clang.json b/apps/tests/main-set/016-collect/07-collect-clang.json new file mode 100644 index 00000000..b6146c1b --- /dev/null +++ b/apps/tests/main-set/016-collect/07-collect-clang.json @@ -0,0 +1,37 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "patches": { + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + }, + "expected": [ + 0, + "", + [ + "[toolkit] LLVM 17.0.1 (from $TMP/clang/.covcollect)", + " [merge] $TMP/mocks/llvm-profdata-17", + " [cov] $TMP/mocks/llvm-cov-17", + " [data] $TMP/clang/build/llvm", + "[preprocess] start...", + "[preprocess] #.## s", + "[report] start...", + "[0/0] finished ", + "[report] #.## s", + "[files] 0", + "[lines] 0 / 0", + "[functions] 0 / 0", + "[i/o] $TMP/clang/build/cov-collect.json\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/clang'", + "cd '$TMP/clang'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mock clang++-17 clang++-17", + "mock llvm-cov-17 llvm-cov-17", + "mock llvm-profdata-17 llvm-profdata-17", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/clang++-17'" + ] +} diff --git a/apps/tests/main-set/016-collect/08-collect-gcc.json b/apps/tests/main-set/016-collect/08-collect-gcc.json new file mode 100644 index 00000000..1780ec46 --- /dev/null +++ b/apps/tests/main-set/016-collect/08-collect-gcc.json @@ -0,0 +1,33 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "patches": { + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + }, + "expected": [ + 0, + "", + [ + "[toolkit] GNU 17.0.1 (from $TMP/collect/.covcollect)", + " [gcov] $TMP/mocks/gcov-17.0.1", + "[report] start...", + "[0/0] finished ", + "[report] #.## s", + "[files] 0", + "[lines] 0 / 0", + "[functions] 0 / 0", + "[i/o] $TMP/collect/build/cov-collect.json\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/collect'", + "cd '$TMP/collect'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mock hal9000-lcars-GLaDOS-g++-17 g++", + "mock hal9000-lcars-GLaDOS-gcov-17 gcov", + "mock hal9000-lcars-GLaDOS-gcov-17 gcov-17.0.1", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/g++'" + ] +} diff --git a/apps/tests/main-set/016-collect/09-collect-gcc-triple.json b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json new file mode 100644 index 00000000..b5812f8f --- /dev/null +++ b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json @@ -0,0 +1,19 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "disabled": true, + "patches": { + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + }, + "expected": null, + "prepare": [ + "mkdirs '$TMP/collect'", + "cd '$TMP/collect'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mock hal9000-lcars-GLaDOS-g++-17 hal9000-lcars-GLaDOS-g++-17", + "mock hal9000-lcars-GLaDOS-gcov-17 hal9000-lcars-GLaDOS-gcov", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/hal9000-lcars-GLaDOS-g++-17'" + ] +} diff --git a/apps/tests/main-set/016-collect/10-collect-clean.json b/apps/tests/main-set/016-collect/10-collect-clean.json new file mode 100644 index 00000000..a3e3ce24 --- /dev/null +++ b/apps/tests/main-set/016-collect/10-collect-clean.json @@ -0,0 +1,19 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect --clean", + "expected": [ + 0, + "", + "" + ], + "prepare": [ + "mkdirs '$TMP/collect'", + "cd '$TMP/collect'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mock hal9000-lcars-GLaDOS-g++-17 g++", + "mock hal9000-lcars-GLaDOS-gcov-17 gcov", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/g++'" + ] +} diff --git a/apps/tests/main-set/016-collect/11-collect-no-output.json b/apps/tests/main-set/016-collect/11-collect-no-output.json new file mode 100644 index 00000000..e607b5d7 --- /dev/null +++ b/apps/tests/main-set/016-collect/11-collect-no-output.json @@ -0,0 +1,33 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "patches": { + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + }, + "expected": [ + 1, + "", + [ + "[toolkit] GNU 17.0.1 (from $TMP/dir/.covcollect)", + " [gcov] $TMP/mocks/gcov", + "[report] start...", + "[0/0] finished ", + "[report] #.## s", + "[files] 0", + "[lines] 0 / 0", + "[functions] 0 / 0", + "[i/o] cannot open $TMP/dir/build/cov-collect.json\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/dir'", + "cd '$TMP/dir'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mkdirs build/cov-collect.json", + "mock hal9000-lcars-GLaDOS-g++-17 g++", + "mock hal9000-lcars-GLaDOS-gcov-17 gcov", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/g++'" + ] +} diff --git a/apps/tests/main-set/016-collect/12-collect-msvc.json b/apps/tests/main-set/016-collect/12-collect-msvc.json new file mode 100644 index 00000000..906effda --- /dev/null +++ b/apps/tests/main-set/016-collect/12-collect-msvc.json @@ -0,0 +1,36 @@ +{ + "$schema": "../../../../tools/json_tests/schema.json", + "args": "collect", + "patches": { + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + }, + "expected": [ + 0, + "", + [ + "[toolkit] MSVC 17.01.74656 (from $TMP/dir/.covcollect)", + " [occ] $TMP/mocks/OpenCppCoverage", + " [outfile] /OpenCppCoverage/cobertura.xml", + "[report] start...", + "[report] #.## s", + "[files] 1", + "[lines] 2 / 2", + "[functions] 0 / 0", + "[i/o] $TMP/dir/build/cov-collect.json\n" + ] + ], + "prepare": [ + "mkdirs '$TMP/dir'", + "cd '$TMP/dir'", + "git init", + "cov init", + "git commit -m 'initial' --allow-empty", + "mkdirs build/OpenCppCoverage", + "cp '$DATA/covcollect/OpenCppCoverage.xml' build/OpenCppCoverage/cobertura.xml", + "touch src/main.cc", + "mock cl.exe cl.exe", + "mock OpenCppCoverage OpenCppCoverage", + "generate '$DATA/covcollect/ini' .covcollect 'COMPILER=$TMP/mocks/cl.exe'", + "generate '$DATA/covcollect/OpenCppCoverage.xml' build/OpenCppCoverage/cobertura.xml 'SOURCES=$TMP/dir'" + ] +} diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 0eb9a2d1..9e03bc5b 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(libs) +add_subdirectory(tests) set(NATIVE_FILTERS strip-excludes diff --git a/extensions/tests/CMakeLists.txt b/extensions/tests/CMakeLists.txt new file mode 100644 index 00000000..233a18f4 --- /dev/null +++ b/extensions/tests/CMakeLists.txt @@ -0,0 +1,33 @@ +macro(mock_ex name source linkname) + add_executable(mock-${name} mock_${source}.cc) + set_target_properties(mock-${name} PROPERTIES OUTPUT_NAME ${linkname}) + + target_link_libraries(mock-${name} PRIVATE fmt::fmt mbits::args) + + set_target_properties(mock-${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mocks") + + foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set_target_properties( + mock-${name} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} "${CMAKE_BINARY_DIR}/mocks" + ) + endforeach() +endmacro() + +macro(mock name linkname) + string(REPLACE "-" "_" SAFE ${name}) + mock_ex(${name} ${SAFE} ${linkname}) +endmacro() + +if (COV_TESTING) + mock(gcc hal9000-lcars-GLaDOS-g++-17) + mock(gcov hal9000-lcars-GLaDOS-gcov-17) + mock(clang clang++-17) + mock(llvm-cov llvm-cov-17) + mock(llvm-profdata llvm-profdata-17) + mock(cl cl) + mock(occ OpenCppCoverage) + + set_target_properties(mock-cl PROPERTIES SUFFIX ".exe") +endif() diff --git a/extensions/tests/mock_cl.cc b/extensions/tests/mock_cl.cc new file mode 100644 index 00000000..d7a76199 --- /dev/null +++ b/extensions/tests/mock_cl.cc @@ -0,0 +1,10 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include + +int main(int, char**) { + fmt::print( + "1701\n" + "170174656\n"); +} diff --git a/extensions/tests/mock_clang.cc b/extensions/tests/mock_clang.cc new file mode 100644 index 00000000..58c63a42 --- /dev/null +++ b/extensions/tests/mock_clang.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include + +using namespace std::literals; + +int main(int, char**) { + static constexpr auto version = "17.0.1"sv; + fmt::print( + "Chell clang version {}\n" + "Target: hal9000-lcars-GLaDOS\n" + "Thread model: Elim Garak\n", + version); +} diff --git a/extensions/tests/mock_gcc.cc b/extensions/tests/mock_gcc.cc new file mode 100644 index 00000000..1b7a6923 --- /dev/null +++ b/extensions/tests/mock_gcc.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +#include +#include +#include + +using namespace std::literals; + +int main(int argc, char** argv) { + auto const args = ::args::from_main(argc, argv); + static constexpr auto version = "17.0.1"sv; + fmt::print("{0} (Chell {1}-D) {1}\n", args.progname, version); +} diff --git a/extensions/tests/mock_gcov.cc b/extensions/tests/mock_gcov.cc new file mode 100644 index 00000000..234f17e2 --- /dev/null +++ b/extensions/tests/mock_gcov.cc @@ -0,0 +1,4 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +int main() {} diff --git a/extensions/tests/mock_llvm_cov.cc b/extensions/tests/mock_llvm_cov.cc new file mode 100644 index 00000000..234f17e2 --- /dev/null +++ b/extensions/tests/mock_llvm_cov.cc @@ -0,0 +1,4 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +int main() {} diff --git a/extensions/tests/mock_llvm_profdata.cc b/extensions/tests/mock_llvm_profdata.cc new file mode 100644 index 00000000..234f17e2 --- /dev/null +++ b/extensions/tests/mock_llvm_profdata.cc @@ -0,0 +1,4 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +int main() {} diff --git a/extensions/tests/mock_occ.cc b/extensions/tests/mock_occ.cc new file mode 100644 index 00000000..234f17e2 --- /dev/null +++ b/extensions/tests/mock_occ.cc @@ -0,0 +1,4 @@ +// Copyright (c) 2023 Marcin Zdun +// This code is licensed under MIT license (see LICENSE for details) + +int main() {} diff --git a/tools/json_tests/driver/commands.py b/tools/json_tests/driver/commands.py index 06634b06..a61013d8 100644 --- a/tools/json_tests/driver/commands.py +++ b/tools/json_tests/driver/commands.py @@ -65,6 +65,7 @@ def _shell(test: test.Test, args: List[str]): HANDLERS: Dict[str, Tuple[int, Callable]] = { "mkdirs": (1, lambda test, args: test.makedirs(args[0])), "rm": (1, lambda test, args: test.rmtree(args[0])), + "cp": (2, lambda test, args: test.cp(args[0], args[1])), "ro": (1, _make_RO), "rw": (1, _make_RW), "touch": (1, _touch), @@ -74,4 +75,6 @@ def _shell(test: test.Test, args: List[str]): "cat": (1, _cat), "store": (2, lambda test, args: test.store_output(args[0], args[1:])), "shell": (0, _shell), + "mock": (2, lambda test, args: test.mock(args[0], args[1])), + "generate": (3, lambda test, args: test.generate(args[0], args[1], args[2:])), } diff --git a/tools/json_tests/driver/test.py b/tools/json_tests/driver/test.py index e89fdaca..5c33be00 100644 --- a/tools/json_tests/driver/test.py +++ b/tools/json_tests/driver/test.py @@ -35,7 +35,7 @@ def _alt_sep(input, value, var): first = split[0] split = split[1:] for index in range(len(split)): - m = re.match(r"(\S+)(\s*.*)", split[index]) + m = re.match(r"^(\S+)(\s*(\n|.)*)$", split[index]) if m is None: continue g2 = m.group(2) @@ -58,6 +58,7 @@ def to_lines(stream: str): @dataclass class Env: target: str + build_dir: str data_dir: str tempdir: str version: str @@ -67,6 +68,10 @@ class Env: data_dir_alt: Optional[str] = None tempdir_alt: Optional[str] = None + @property + def mocks_dir(self): + return os.path.join(self.tempdir, "mocks") + def expand(self, input: str, tempdir: str, additional: Dict[str, str] = {}): input = ( input.replace("$TMP", tempdir) @@ -135,6 +140,7 @@ def __init__(self, data: dict, filename: str, count: int): self.current_env: Optional[Env] = None self.additional_env: Dict[str, str] = {} self.patches: Dict[str, str] = data.get("patches", {}) + self.needs_occ_path: bool = False self.check = ["all", "all"] for stream in range(len(_streams)): @@ -263,6 +269,7 @@ def run(self, environment: Env): ) root = self.cwd = os.path.join(self.cwd, root) os.makedirs(root, exist_ok=True) + shutil.rmtree(environment.mocks_dir, ignore_errors=True) prep = self.run_cmds(environment, self.prepare, environment.tempdir) if prep is None: @@ -288,6 +295,9 @@ def run(self, environment: Env): _env[key] = environment.expand(value, environment.tempdir) elif key in _env: del _env[key] + if self.needs_occ_path: + _env["PATH"] += os.pathsep + _env["PATH"] += environment.mocks_dir cwd = None if self.linear else self.cwd proc: subprocess.CompletedProcess = subprocess.run( @@ -425,6 +435,9 @@ def ls(self, sub): def rmtree(self, sub): shutil.rmtree(self.path(sub)) + def cp(self, src: str, dst: str): + shutil.copy2(self.path(src), self.path(dst)) + def makedirs(self, sub): os.makedirs(self.path(sub), exist_ok=True) @@ -438,6 +451,70 @@ def store_output(self, name: str, args: List[str]): self.additional_env[name] = proc.stdout.decode("UTF-8").strip() print(f"export {name}={self.additional_env[name]}") + def mock(self, exe, link: str): + ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" + src = os.path.join(self.current_env.build_dir, "mocks", f"{exe}{ext}") + dst = os.path.join(self.current_env.mocks_dir, f"{link}{ext}") + os.makedirs(os.path.dirname(dst), exist_ok=True) + try: + os.remove(dst) + except FileNotFoundError: + pass + os.symlink(src, dst, target_is_directory=os.path.isdir(src)) + if exe == "OpenCppCoverage": + self.needs_occ_path = True + + def generate_cov_collect(self, template, args: List[str]): + with open(template, encoding="UTF-8") as tmplt: + text = tmplt.read().split("$") + + ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" + values = { + "COMPILER": os.path.join(self.current_env.mocks_dir, f"{args[0]}{ext}") + } + first = text[0] + text = text[1:] + for index in range(len(text)): + m = re.match(r"^(\S+)(\s*(\n|.)*)$", text[index]) + if m: + key = m.group(1) + value = values.get(key, f"${key}") + text[index] = f"{value}{m.group(2)}" + + with open(os.path.join(self.cwd, ".covcollect"), "w", encoding="UTF-8") as ini: + ini.write("".join([first, *text])) + + def generate(self, template, dst, args: List[str]): + with open(template, encoding="UTF-8") as tmplt: + text = tmplt.read().split("$") + + ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" + values = {} + for arg in args: + kv = [a.strip() for a in arg.split("=", 1)] + key = kv[0] + if len(kv) == 1: + values[key] = "" + else: + value = kv[1] + if key in ["COMPILER"]: + value = f"{value}{ext}" + values[key] = value + + first = text[0] + text = text[1:] + for index in range(len(text)): + m = re.match(r"^([a-zA-Z0-9_]+)(\s*(\n|.)*)$", text[index]) + if m: + key = m.group(1) + value = values.get(key, f"${key}") + text[index] = f"{value}{m.group(2)}" + + path = self.path(dst) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w", encoding="UTF-8") as ini: + ini.write("".join([first, *text])) + @staticmethod def load(filename, count): with open(filename, encoding="UTF-8") as f: diff --git a/tools/json_tests/driver/testbed.py b/tools/json_tests/driver/testbed.py index 95823782..5f18ebf7 100644 --- a/tools/json_tests/driver/testbed.py +++ b/tools/json_tests/driver/testbed.py @@ -95,6 +95,7 @@ def task( env2 = test.Env( env1.target, + env1.build_dir, env1.data_dir, tempdir, env1.version, diff --git a/tools/json_tests/schema.json b/tools/json_tests/schema.json index 179c3fed..b8436872 100644 --- a/tools/json_tests/schema.json +++ b/tools/json_tests/schema.json @@ -5,11 +5,11 @@ "properties": { "$schema": {"type": "string"}, "linear": {"type": "boolean"}, - "disabled": {"type": ["string", "boolean"]}, + "disabled": {"type": ["boolean", "string"]}, "lang": {"type": "boolean"}, "args": {"type": "string"}, "post": {"type": ["string", "array"], "items": {"type": "string"}}, - "expected": {"type": ["array", "null"]}, + "expected": {"type": ["null", "array"]}, "patches": { "type": "object", "properties": { diff --git a/tools/json_tests/test_driver.py b/tools/json_tests/test_driver.py index 71a2d415..f1c5efcd 100755 --- a/tools/json_tests/test_driver.py +++ b/tools/json_tests/test_driver.py @@ -122,6 +122,7 @@ def _make_env(args: argparse.Namespace, counter_total: int): return Env( target=target, + build_dir=os.path.dirname(os.path.dirname(target)), data_dir=args.data_dir, tempdir=tempdir, version=args.version, From bb49fe63ce4821ed7063c0d1ccf9de0907e7466b Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 21:00:30 +0200 Subject: [PATCH 29/39] fix: apply changes stemming from test runs --- extensions/cov_collect.cc | 5 +-- extensions/libs/collect-api/src/gnu.cc | 7 ++-- extensions/libs/collect-api/src/llvm.cc | 29 +++++++++++------ extensions/libs/collect-api/src/msvc.cc | 11 ++++--- extensions/libs/collect-api/src/report.cc | 37 ++-------------------- extensions/libs/collect-api/src/report.hh | 1 - extensions/libs/collect-api/src/toolkit.cc | 4 +-- extensions/libs/collect-api/src/toolkit.hh | 1 - 8 files changed, 38 insertions(+), 57 deletions(-) diff --git a/extensions/cov_collect.cc b/extensions/cov_collect.cc index 7ff39c65..7ae1e4d1 100644 --- a/extensions/cov_collect.cc +++ b/extensions/cov_collect.cc @@ -133,14 +133,14 @@ int measure(std::string_view label, Callback&& cb) { int tool(args::args_view const& arguments) { git::init memory{}; + auto params = parse_arguments(arguments); + auto repo = open_here(); if (!repo) return 1; json::string branch{}; git::oid ref{}; if (!repo_head(repo, branch, ref)) return 1; - auto params = parse_arguments(arguments); - if (!params.config) { find_config(repo, params.config); if (!params.config) return 1; @@ -164,6 +164,7 @@ int tool(args::args_view const& arguments) { fmt::print(stderr, "[toolkit] {} {} (from {})\n", toolkit->label(), toolkit->version(), get_u8path(*params.config)); + toolkit->hello(cfg); collect::report cvg{cfg}; if (toolkit->needs_preprocess()) { diff --git a/extensions/libs/collect-api/src/gnu.cc b/extensions/libs/collect-api/src/gnu.cc index f66eaa36..656f5374 100644 --- a/extensions/libs/collect-api/src/gnu.cc +++ b/extensions/libs/collect-api/src/gnu.cc @@ -52,7 +52,7 @@ namespace cov::app::collect { std::string_view version() const noexcept override { return ver_; } void hello(config const&) const override { - fmt::print(" [gcov] {}\n", get_u8path(gcov_)); + fmt::print(stderr, " [gcov] {}\n", get_u8path(gcov_)); } void clean(config const& cfg) const override { @@ -130,7 +130,10 @@ namespace cov::app::collect { : std::string{}; auto tk = std::make_unique( cfg.compiler, matched.get<1>().to_string(), std::move(triplet)); - if (!tk->find_tools()) tk.reset(); + if (!tk->find_tools()) { + fmt::print(stderr, "[gcc] cannot configure the toolkit\n"); + tk.reset(); + } return tk; } return {}; diff --git a/extensions/libs/collect-api/src/llvm.cc b/extensions/libs/collect-api/src/llvm.cc index da7b3ea1..5d1fd4f2 100644 --- a/extensions/libs/collect-api/src/llvm.cc +++ b/extensions/libs/collect-api/src/llvm.cc @@ -189,15 +189,17 @@ namespace cov::app::collect { std::string_view version() const noexcept override { return ver_; } void hello(config const&) const override { - fmt::print(" [merge] {}\n", get_u8path(merger_)); - fmt::print(" [cov] {}\n", get_u8path(exporter_)); - if (!raw_ext_.empty()) fmt::print(" [raw] {}\n", raw_ext_); + fmt::print(stderr, " [merge] {}\n", get_u8path(merger_)); + fmt::print(stderr, " [cov] {}\n", get_u8path(exporter_)); + if (!raw_ext_.empty()) + fmt::print(stderr, " [raw] {}\n", raw_ext_); if (!prof_data_dir_.empty()) - fmt::print(" [data] {}\n", get_u8path(prof_data_dir_)); + fmt::print(stderr, " [data] {}\n", + get_u8path(prof_data_dir_)); if (!exec_.empty()) { - fmt::print(" [exe]\n"); + fmt::print(stderr, " [exe]\n"); for (auto const& exe : exec_) { - fmt::print(" - {}\n", get_u8path(exe)); + fmt::print(stderr, " - {}\n", get_u8path(exe)); } } } @@ -257,7 +259,10 @@ namespace cov::app::collect { if (auto matched = CLANG(lines[0]); matched) { auto tk = std::make_unique( cfg.compiler, matched.get<1>().to_string()); - if (!tk->load_config(cfg) || !tk->find_tools()) tk.reset(); + if (!tk->load_config(cfg) || !tk->find_tools()) { + fmt::print(stderr, "[clang] cannot configure the toolkit\n"); + tk.reset(); + } return tk; } return {}; @@ -387,7 +392,7 @@ namespace cov::app::collect { if (!filename || (!segments && !branches)) continue; - auto sink = cvg.get_file(from_u8(*filename)); + auto sink = cvg.get_file_mt(from_u8(*filename)); if (!sink) continue; if (segments) { @@ -403,6 +408,8 @@ namespace cov::app::collect { cvg_segment::run_coverage(data, *sink); } + + cvg.handover_mt(std::move(sink)); } } if (functions) { @@ -423,10 +430,12 @@ namespace cov::app::collect { if (!region) continue; auto filename = cast((*filenames)[0]); - auto sink = cvg.get_file(from_u8(*filename)); - if (sink) + auto sink = cvg.get_file_mt(from_u8(*filename)); + if (sink) { sink->on_function(region->start, region->end, u(*count), get_u8path(*name), {}); + cvg.handover_mt(std::move(sink)); + } } } } diff --git a/extensions/libs/collect-api/src/msvc.cc b/extensions/libs/collect-api/src/msvc.cc index 5e5d9c07..fe60e774 100644 --- a/extensions/libs/collect-api/src/msvc.cc +++ b/extensions/libs/collect-api/src/msvc.cc @@ -40,7 +40,7 @@ namespace cov::app::collect { bool find_tools() { auto const hint = compiler_.parent_path(); auto const ver = split(ver_, '.'); - if (!find_tool(occ_, LR"(C:/Program Files/OpenCppCoverage)"sv, + if (!find_tool(occ_, "C:/Program Files/OpenCppCoverage"sv, "OpenCppCoverage"sv, {})) return false; occ_.make_preferred(); @@ -51,8 +51,8 @@ namespace cov::app::collect { std::string_view version() const noexcept override { return ver_; } void hello(config const&) const override { - fmt::print(" [occ] {}\n", get_u8path(occ_)); - fmt::print(" [outfile] {}\n", + fmt::print(stderr, " [occ] {}\n", get_u8path(occ_)); + fmt::print(stderr, " [outfile] {}\n", get_u8path("" / occ_dir_ / occ_output_)); } @@ -114,8 +114,11 @@ namespace cov::app::collect { std::unique_ptr msvc(config const& cfg) { auto tk = std::make_unique(cfg.compiler); - if (!tk->load_config(cfg) || !tk->get_version(cfg) || !tk->find_tools()) + if (!tk->load_config(cfg) || !tk->get_version(cfg) || + !tk->find_tools()) { + fmt::print(stderr, "[msvc] cannot configure the toolkit\n"); tk.reset(); + } return tk; } diff --git a/extensions/libs/collect-api/src/report.cc b/extensions/libs/collect-api/src/report.cc index 082510dc..8b03c0b3 100644 --- a/extensions/libs/collect-api/src/report.cc +++ b/extensions/libs/collect-api/src/report.cc @@ -15,37 +15,6 @@ using namespace std::literals; namespace cov::app::collect { - coverage_file* report::get_file(std::string_view path) { - if (!path.starts_with(src_prefix_)) return nullptr; - path = path.substr(src_prefix_.length()); - for (auto const& excl_path : cfg_.exclude) { - auto excl = get_u8path(excl_path); - if (!path.starts_with(excl)) continue; - auto rest = path.substr(excl.size()); - if (rest.empty() || rest.front() == '/') return nullptr; - } - for (auto const& incl_path : cfg_.include) { - auto incl = get_u8path(incl_path); - if (!path.starts_with(incl)) continue; - auto rest = path.substr(incl.size()); - if (rest.empty() || rest.front() == '/') { - auto key = std::string{path.data(), path.size()}; -#ifdef _WIN32 - std::replace(key.begin(), key.end(), '\\', '/'); -#endif - auto it = files_.find(key); - if (it == files_.end()) { - bool ignore = false; - std::tie(it, ignore) = - files_.insert({key, std::make_unique(key)}); - } - return it->second.get(); - } - } - return nullptr; - {} - } - std::unique_ptr report::get_file_mt(std::string_view path) { static constexpr auto sep = static_cast(std::filesystem::path::preferred_separator); @@ -76,11 +45,11 @@ namespace cov::app::collect { std::lock_guard lock{m_}; std::unique_ptr src{static_cast(returned.release())}; - auto it = files_.find(src->filename()); + auto key = src->filename(); + auto it = files_.find(key); if (it == files_.end()) { bool ignore = false; - std::tie(it, ignore) = - files_.insert({src->filename(), std::move(src)}); + std::tie(it, ignore) = files_.insert({key, std::move(src)}); return; } it->second->merge(*src); diff --git a/extensions/libs/collect-api/src/report.hh b/extensions/libs/collect-api/src/report.hh index d9a6fc7c..50f40c9f 100644 --- a/extensions/libs/collect-api/src/report.hh +++ b/extensions/libs/collect-api/src/report.hh @@ -18,7 +18,6 @@ namespace cov::app::collect { struct report : coverage { report(config const& cfg) : cfg_{cfg} {} - coverage_file* get_file(std::string_view path) override; std::unique_ptr get_file_mt( std::string_view path) override; void handover_mt(std::unique_ptr&&) override; diff --git a/extensions/libs/collect-api/src/toolkit.cc b/extensions/libs/collect-api/src/toolkit.cc index adff9d3f..22faec61 100644 --- a/extensions/libs/collect-api/src/toolkit.cc +++ b/extensions/libs/collect-api/src/toolkit.cc @@ -58,9 +58,7 @@ namespace cov::app::collect { } std::unique_ptr recognize_toolkit(config const& cfg) { -#ifdef _WIN32 if (cfg.compiler.filename() == L"cl.exe"sv) return msvc(cfg); -#endif char ver[] = "--version"; char* v_args[] = {ver, nullptr}; auto const proc = platform::run(cfg.compiler, {1, v_args}); @@ -138,8 +136,8 @@ namespace cov::app::collect { return 0; }); - if (bin_dir.empty()) bin_dir = cfg_dir; if (src_dir.empty()) src_dir = cfg_dir; + if (bin_dir.empty()) bin_dir = src_dir; if (output.empty()) output = "cov-collect.json"; } } // namespace cov::app::collect diff --git a/extensions/libs/collect-api/src/toolkit.hh b/extensions/libs/collect-api/src/toolkit.hh index d1528884..9119a8fe 100644 --- a/extensions/libs/collect-api/src/toolkit.hh +++ b/extensions/libs/collect-api/src/toolkit.hh @@ -44,7 +44,6 @@ namespace cov::app::collect { struct coverage { virtual ~coverage(); - virtual coverage_file* get_file(std::string_view path) = 0; virtual std::unique_ptr get_file_mt( std::string_view path) = 0; virtual void handover_mt(std::unique_ptr&&) = 0; From 3935b894a184e104ae3645352c8f7f3e7f87728c Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 21:03:11 +0200 Subject: [PATCH 30/39] test: exclude some unvisitable lines The ExpatBase is treated as 3rd code here, it's not the place of this project to make sure it's covered... --- extensions/cov_collect.cc | 2 ++ extensions/filters/strip_excludes.cc | 12 +++++++----- extensions/libs/excludes/src/excludes.cc | 8 ++------ extensions/libs/excludes/src/excludes.hh | 2 +- extensions/libs/native/include/native/expat.hh | 2 ++ extensions/libs/native/include/native/str.hh | 6 +++--- libs/cov-rt/src/cvg_info.cc | 4 ++++ 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/extensions/cov_collect.cc b/extensions/cov_collect.cc index 7ae1e4d1..ccb1493f 100644 --- a/extensions/cov_collect.cc +++ b/extensions/cov_collect.cc @@ -56,8 +56,10 @@ bool repo_head(git::repository const& repo, return true; } } + // GCOV_EXCL_START fmt::print(stderr, "[git] cannot resolve HEAD to a commit\n"); return false; + // GCOV_EXCL_STOP } enum class command { clean, observe, collect }; diff --git a/extensions/filters/strip_excludes.cc b/extensions/filters/strip_excludes.cc index 7620ac14..8a112791 100644 --- a/extensions/filters/strip_excludes.cc +++ b/extensions/filters/strip_excludes.cc @@ -50,11 +50,8 @@ namespace cov::app::strip { return {}; } + enum which_lines { soft = false, hard = true }; - bool non_zero(json::node const& n) { - auto num = cast(n); - return num && *num; - } bool erase_line(json::map& line_coverage, unsigned line, @@ -100,7 +97,8 @@ namespace cov::app::strip { for (auto& node_range : *array) { auto json_range = cast(node_range); if (!json_range) { - ++counter; + ++counter; // GCOV_EXCL_LINE -- oh, c'mon, continue is + // counted... continue; } auto const block = mask_range(*json_range, blocks); @@ -186,7 +184,9 @@ namespace cov::app::strip { if (auto json_array = json::cast(file, u8"branches"); json_array) { + // GCOV_EXCL_START -- TODO: [BRANCHES] Enable for next task br_counter += filter_blocks(json_array, excludes); + // GCOV_EXCL_STOP } } @@ -206,12 +206,14 @@ namespace cov::app::strip { fmt::print(stderr, "{} {}", fn_counter, fn_counter == 1 ? "function"sv : "functions"sv); } + // GCOV_EXCL_START -- TODO: [BRANCHES] Enable for next task if (br_counter) { if (!first) fmt::print(stderr, ", "); first = false; fmt::print(stderr, "{} {}", br_counter, br_counter == 1 ? "branch"sv : "branches"sv); } + // GCOV_EXCL_STOP fmt::print(stderr, "\n"); } diff --git a/extensions/libs/excludes/src/excludes.cc b/extensions/libs/excludes/src/excludes.cc index ae6bb7b5..1b73ae77 100644 --- a/extensions/libs/excludes/src/excludes.cc +++ b/extensions/libs/excludes/src/excludes.cc @@ -122,11 +122,7 @@ namespace cov::app::strip { std::string excludes::stop_for(std::string_view start, std::string_view suffix) { - if (start.ends_with(suffix)) - return fmt::format( - "{}_STOP", start.substr(0, start.length() - suffix.length())); - std::string stop{}; - stop.assign("GCOV_EXCL_STOP"sv); - return stop; + return fmt::format("{}_STOP", + start.substr(0, start.length() - suffix.length())); } } // namespace cov::app::strip diff --git a/extensions/libs/excludes/src/excludes.hh b/extensions/libs/excludes/src/excludes.hh index 0053f132..4f2d3837 100644 --- a/extensions/libs/excludes/src/excludes.hh +++ b/extensions/libs/excludes/src/excludes.hh @@ -15,7 +15,7 @@ namespace cov::app::strip { struct excl_block { unsigned start{}; - unsigned end{}; + unsigned end{}; // GCOV_EXCL_LINE auto operator<=>(excl_block const&) const noexcept = default; }; diff --git a/extensions/libs/native/include/native/expat.hh b/extensions/libs/native/include/native/expat.hh index 80b70ba1..9d4451f9 100644 --- a/extensions/libs/native/include/native/expat.hh +++ b/extensions/libs/native/include/native/expat.hh @@ -10,6 +10,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" #endif +// GCOV_EXCL_START namespace xml { template class ExpatBase { @@ -330,6 +331,7 @@ namespace xml { XML_Parser parser_; }; } // namespace xml +// GCOV_EXCL_STOP #if defined(__clang__) #pragma clang diagnostic pop #endif diff --git a/extensions/libs/native/include/native/str.hh b/extensions/libs/native/include/native/str.hh index 20014f48..e5aef6e0 100644 --- a/extensions/libs/native/include/native/str.hh +++ b/extensions/libs/native/include/native/str.hh @@ -42,7 +42,7 @@ namespace cov::app { c = static_cast(std::tolower(static_cast(c))); } return result; - } + } // GCOV_EXCL_LINE[GCC] template inline void split(std::string_view text, char sep, Callback&& cb) { @@ -71,5 +71,5 @@ namespace cov::app { split(text, sep, [&result](auto, auto view) { result.push_back(view); }); return result; - } -}; // namespace cov::app + } // GCOV_EXCL_LINE[GCC] +}; // namespace cov::app diff --git a/libs/cov-rt/src/cvg_info.cc b/libs/cov-rt/src/cvg_info.cc index 16465a62..2ce0de69 100644 --- a/libs/cov-rt/src/cvg_info.cc +++ b/libs/cov-rt/src/cvg_info.cc @@ -178,8 +178,10 @@ namespace cov::app { } return fmt::format( + // GCOV_EXCL_START[gcc] "{} {:>{}} |{} {}", prefix, count_column, widths.line_no_width + 3 + widths.count_width + 1, suffix, + // GCOV_EXCL_STOP line_printer::to_string(total_count, name, shorten, use_color)); } @@ -193,9 +195,11 @@ namespace cov::app { auto const count_column = count ? fmt::format("{}x", *count) : " "s; return fmt::format( + // GCOV_EXCL_START[gcc] " {:>{}} | {:>{}} | {}", line_no + 1, widths.line_no_width, count_column, widths.count_width + 1, line_printer::to_string(count, line_text, line.contents, + // GCOV_EXCL_STOP syntax.dict, use_color)); } } // namespace cov::app From 0dd5dbc1acb30a7330e82cbb256e16eae5f53f24 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 30 Jul 2023 22:26:07 +0200 Subject: [PATCH 31/39] tests: fix latest json tests on Windows --- .../main-set/016-collect/07-collect-clang.json | 3 ++- .../main-set/016-collect/08-collect-gcc.json | 3 ++- .../016-collect/11-collect-no-output.json | 3 ++- .../main-set/016-collect/12-collect-msvc.json | 4 +++- .../073-report-not-the-json-filtered.json | 2 +- extensions/tests/CMakeLists.txt | 5 ++--- extensions/tests/mock_gcc.cc | 7 ++++++- libs/app/src/win32/run.cc | 17 +++++++++++++++-- tools/json_tests/driver/test.py | 14 ++++++++++---- tools/run_ctest.py | 11 ++++++++++- 10 files changed, 53 insertions(+), 16 deletions(-) diff --git a/apps/tests/main-set/016-collect/07-collect-clang.json b/apps/tests/main-set/016-collect/07-collect-clang.json index b6146c1b..5096d244 100644 --- a/apps/tests/main-set/016-collect/07-collect-clang.json +++ b/apps/tests/main-set/016-collect/07-collect-clang.json @@ -2,7 +2,8 @@ "$schema": "../../../../tools/json_tests/schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "(.+)\\.exe": "\\1" }, "expected": [ 0, diff --git a/apps/tests/main-set/016-collect/08-collect-gcc.json b/apps/tests/main-set/016-collect/08-collect-gcc.json index 1780ec46..cc583378 100644 --- a/apps/tests/main-set/016-collect/08-collect-gcc.json +++ b/apps/tests/main-set/016-collect/08-collect-gcc.json @@ -2,7 +2,8 @@ "$schema": "../../../../tools/json_tests/schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "(.+)\\.exe": "\\1" }, "expected": [ 0, diff --git a/apps/tests/main-set/016-collect/11-collect-no-output.json b/apps/tests/main-set/016-collect/11-collect-no-output.json index e607b5d7..42678563 100644 --- a/apps/tests/main-set/016-collect/11-collect-no-output.json +++ b/apps/tests/main-set/016-collect/11-collect-no-output.json @@ -2,7 +2,8 @@ "$schema": "../../../../tools/json_tests/schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "(.+)\\.exe": "\\1" }, "expected": [ 1, diff --git a/apps/tests/main-set/016-collect/12-collect-msvc.json b/apps/tests/main-set/016-collect/12-collect-msvc.json index 906effda..480042e4 100644 --- a/apps/tests/main-set/016-collect/12-collect-msvc.json +++ b/apps/tests/main-set/016-collect/12-collect-msvc.json @@ -2,7 +2,9 @@ "$schema": "../../../../tools/json_tests/schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s" + "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + " \\[occ\\] C:\\\\Program Files\\\\OpenCppCoverage\\\\OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", + " \\[outfile\\] \\\\OpenCppCoverage\\\\cobertura\\.xml": " [outfile] /OpenCppCoverage/cobertura.xml" }, "expected": [ 0, diff --git a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json index 1ed33eef..844192fc 100644 --- a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json +++ b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json @@ -6,7 +6,7 @@ "", [ "cov report: /git: undefined", - "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json przetworzonym przez filtr echo-to-stdout" + "cov report: błąd: wystąpiły problemy z $DATA/no-git-coverage.json przetworzonym przez filtr echo-to-stdout\n" ] ], "prepare": [ diff --git a/extensions/tests/CMakeLists.txt b/extensions/tests/CMakeLists.txt index 233a18f4..7636b0fb 100644 --- a/extensions/tests/CMakeLists.txt +++ b/extensions/tests/CMakeLists.txt @@ -1,10 +1,9 @@ macro(mock_ex name source linkname) add_executable(mock-${name} mock_${source}.cc) set_target_properties(mock-${name} PROPERTIES OUTPUT_NAME ${linkname}) - - target_link_libraries(mock-${name} PRIVATE fmt::fmt mbits::args) - + target_link_libraries(mock-${name} PRIVATE fmt::fmt mbits::args app) set_target_properties(mock-${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mocks") + fix_vs_modules(mock-${name}) foreach(BUILD_TYPE DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) set_target_properties( diff --git a/extensions/tests/mock_gcc.cc b/extensions/tests/mock_gcc.cc index 1b7a6923..72f4932c 100644 --- a/extensions/tests/mock_gcc.cc +++ b/extensions/tests/mock_gcc.cc @@ -3,12 +3,17 @@ #include #include +#include #include using namespace std::literals; int main(int argc, char** argv) { + using namespace cov::app; + auto const args = ::args::from_main(argc, argv); static constexpr auto version = "17.0.1"sv; - fmt::print("{0} (Chell {1}-D) {1}\n", args.progname, version); + auto progname = get_u8path(make_u8path(args.progname).filename()); + + fmt::print("{0} (Chell {1}-D) {1}\n", progname, version); } diff --git a/libs/app/src/win32/run.cc b/libs/app/src/win32/run.cc index 32288c3c..fbb21161 100644 --- a/libs/app/src/win32/run.cc +++ b/libs/app/src/win32/run.cc @@ -370,11 +370,24 @@ namespace cov::app::platform { return !ec && std::filesystem::is_regular_file(status); } + std::vector all_lower( + std::span items) { + std::vector result{}; + result.reserve(items.size()); + for (auto view : items) { + std::wstring arg; + arg.assign(view); + CharLowerW(arg.data()); + result.push_back(std::move(arg)); + } + return result; + } + std::filesystem::path where(std::filesystem::path const& bin, wchar_t const* environment_variable, std::wstring const& program) { auto ext_str = env(L"PATHEXT"); - auto path_ext = split(std::wstring{}, ext_str); + auto path_ext = all_lower(split(std::wstring{}, ext_str)); if (program.find_first_of(L"\\/"sv) != std::string::npos) { return program; @@ -388,7 +401,7 @@ namespace cov::app::platform { auto path = std::filesystem::path{dir} / filename(program, ext); if (file_exists(path)) { - return std::filesystem::canonical(path); + return path; } } } diff --git a/tools/json_tests/driver/test.py b/tools/json_tests/driver/test.py index 5c33be00..42cdf41e 100644 --- a/tools/json_tests/driver/test.py +++ b/tools/json_tests/driver/test.py @@ -35,7 +35,7 @@ def _alt_sep(input, value, var): first = split[0] split = split[1:] for index in range(len(split)): - m = re.match(r"^(\S+)(\s*(\n|.)*)$", split[index]) + m = re.match(r"^(\S+)((\n|.)*)$", split[index]) if m is None: continue g2 = m.group(2) @@ -452,7 +452,7 @@ def store_output(self, name: str, args: List[str]): print(f"export {name}={self.additional_env[name]}") def mock(self, exe, link: str): - ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" + ext = ".exe" if os.name == "nt" and os.path.basename(exe) != "cl.exe" else "" src = os.path.join(self.current_env.build_dir, "mocks", f"{exe}{ext}") dst = os.path.join(self.current_env.mocks_dir, f"{link}{ext}") os.makedirs(os.path.dirname(dst), exist_ok=True) @@ -468,7 +468,9 @@ def generate_cov_collect(self, template, args: List[str]): with open(template, encoding="UTF-8") as tmplt: text = tmplt.read().split("$") - ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" + ext = ( + ".exe" if os.name == "nt" and os.path.basename(args[0]) != "cl.exe" else "" + ) values = { "COMPILER": os.path.join(self.current_env.mocks_dir, f"{args[0]}{ext}") } @@ -488,7 +490,6 @@ def generate(self, template, dst, args: List[str]): with open(template, encoding="UTF-8") as tmplt: text = tmplt.read().split("$") - ext = ".exe" if os.name == "nt" and os.path.filename(exe) != "cl.exe" else "" values = {} for arg in args: kv = [a.strip() for a in arg.split("=", 1)] @@ -498,6 +499,11 @@ def generate(self, template, dst, args: List[str]): else: value = kv[1] if key in ["COMPILER"]: + ext = ( + ".exe" + if os.name == "nt" and os.path.basename(value) != "cl.exe" + else "" + ) value = f"{value}{ext}" values[key] = value diff --git a/tools/run_ctest.py b/tools/run_ctest.py index 19a7c6f8..fb4adba1 100644 --- a/tools/run_ctest.py +++ b/tools/run_ctest.py @@ -105,9 +105,14 @@ def _load_tests(dirname: str): if len(command.args) > 1: name = command.args[0].value[3:-3] cmd = [arg.value for arg in command.args[1:]] + if not len(cmd) or cmd[0] == "NOT_AVAILABLE": + continue tests[name] = cmd continue + if command.name in ["if", "elseif", "else", "endif"]: + continue + pprint((dirname, command)) return tests @@ -144,6 +149,10 @@ def print_args(*args: str): if len(sys.argv) < 3: print("known test:", " ".join(tests.keys())) sys.exit(0) -test = [*tests[sys.argv[2]], *sys.argv[3:]] +try: + test = [*tests[sys.argv[2]], *sys.argv[3:]] +except KeyError: + print("known test:", " ".join(tests.keys())) + sys.exit(1) print_args(*test) subprocess.run(test, shell=False) From 5ac1dadb22188946c574f42a927cbaac765a6519 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Mon, 31 Jul 2023 06:18:57 +0200 Subject: [PATCH 32/39] test: fix collect / collect-msvc for GitHub docker --- apps/tests/main-set/016-collect/12-collect-msvc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/tests/main-set/016-collect/12-collect-msvc.json b/apps/tests/main-set/016-collect/12-collect-msvc.json index 480042e4..5cf56454 100644 --- a/apps/tests/main-set/016-collect/12-collect-msvc.json +++ b/apps/tests/main-set/016-collect/12-collect-msvc.json @@ -3,7 +3,8 @@ "args": "collect", "patches": { "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", - " \\[occ\\] C:\\\\Program Files\\\\OpenCppCoverage\\\\OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", + " \\[occ\\] C:\\\\+Program Files(:? \\(x86\\))?\\\\+OpenCppCoverage\\\\+OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", + " \\[occ\\] \\$TMP\\/+mocks\\/+OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", " \\[outfile\\] \\\\OpenCppCoverage\\\\cobertura\\.xml": " [outfile] /OpenCppCoverage/cobertura.xml" }, "expected": [ From 0fca9b82911d35ed56238b9d3cd5b90c38f0ceae Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Mon, 14 Aug 2023 17:56:26 +0200 Subject: [PATCH 33/39] test: prepare for switch to runner --- apps/tests/data/covcollect/cobertura.xml | 35 +++++++++++ runner.chai | 75 ++++++++++++++++++++++++ tools/json_tests/driver/commands.py | 14 ++--- tools/json_tests/driver/test.py | 27 +++++++-- tools/json_tests/driver/testbed.py | 1 + tools/json_tests/test_driver.py | 1 + tools/run_ctest.py | 0 7 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 apps/tests/data/covcollect/cobertura.xml create mode 100644 runner.chai mode change 100644 => 100755 tools/run_ctest.py diff --git a/apps/tests/data/covcollect/cobertura.xml b/apps/tests/data/covcollect/cobertura.xml new file mode 100644 index 00000000..418efa95 --- /dev/null +++ b/apps/tests/data/covcollect/cobertura.xml @@ -0,0 +1,35 @@ + + + + $SOURCES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/runner.chai b/runner.chai new file mode 100644 index 00000000..532cccb6 --- /dev/null +++ b/runner.chai @@ -0,0 +1,75 @@ +import("fs"); + +global proj = project("cov"); +proj.allow("git"); + +proj.install_component("main_exec"); +proj.install_component("tools"); + +proj.datasets(fs.abspath("apps/tests"), "main-set"); +proj.environment("DATA", fs.abspath("apps/tests/data")); + +proj.register_patch( + re_escape("\033[31m[") + "(.+) [0-9a-fA-F]+" + re_escape("]\033[m ") + "(.+)", + "\033[31m[\\1 $REPORT]\033[m \\2"); +proj.register_patch( + re_escape("[") + "(.+) [0-9a-fA-F]+" + re_escape("] ") + "(.+)", + "[\\1 $REPORT] \\2"); +proj.register_patch( + re_escape(" \033[2;37mcontains ") + "[0-9a-fA-F]+" + re_escape(":\033[m ") + "(.+)", + " \033[2;37mcontains $BUILD:\033[m \\1"); +proj.register_patch(" contains [0-9a-fA-F]+: (.+)", " contains $BUILD: \\1"); +proj.register_patch( + re_escape(" \033[2;37mbased on\033[m \033[2;33m") + "[0-9a-fA-F]+@(.+)" + re_escape("\033[m"), + " \033[2;37mbased on\033[m \033[2;33m$HEAD@\\1\033[m"); +proj.register_patch(" based on [0-9a-fA-F]+@(.+)", " based on $HEAD@\\1"); +proj.register_patch("(\\s+)parent [0-9a-fA-F]+", "\\1parent $PARENT"); + +proj.register_patch("CommitDate:(\\s+).*", "CommitDate:\\1$DATE"); +proj.register_patch("Added:(\\s+).*", "Added:\\1$DATE"); + + +def text_from(path) { + var file = path.open(); + if (!file) { + return ""; + } + var text = file.read(); + file.close(); + return text; +} + +def detach(test, args) { + var dirname = test.path(args[0]); + var HEAD = fs.join(dirname, "HEAD"); + var branch = text_from(HEAD).trim_right(); + if (!branch.starts_with("ref: ")) { + return true; + } + branch = branch.substr(5, branch.size()); + + var commit = text_from(fs.join(dirname, branch)); + if (commit.trim().empty()) { return false; } + var file = HEAD.open("w"); + file.write(commit); + return true; +} +proj.handle("detach", 1, detach); + +def cov_install(copy_dir, rt) { + var filters_target = fs.join(copy_dir, "additional-filters"); + + rt.append("COV_FILTER_PATH", filters_target); + rt.append("COV_PATH", fs.join(rt.build_dir, "dont-copy")); + rt.append("COV_PATH", fs.join(rt.build_dir, "elsewhere/libexec/cov")); + + fs.create_directories(filters_target); + var filters = fs.directory_iterator("apps/tests/test-filters"); + for (entry: filters) { + if (fs.extension(entry.path) != ".py") { + continue; + } + var installed_path = fs.join(filters_target, fs.stem(entry.path)); + fs.copy(entry.path, installed_path); + } +} diff --git a/tools/json_tests/driver/commands.py b/tools/json_tests/driver/commands.py index a61013d8..8254e070 100644 --- a/tools/json_tests/driver/commands.py +++ b/tools/json_tests/driver/commands.py @@ -64,17 +64,17 @@ def _shell(test: test.Test, args: List[str]): HANDLERS: Dict[str, Tuple[int, Callable]] = { "mkdirs": (1, lambda test, args: test.makedirs(args[0])), + "cd": (1, lambda test, args: test.chdir(args[0])), "rm": (1, lambda test, args: test.rmtree(args[0])), - "cp": (2, lambda test, args: test.cp(args[0], args[1])), - "ro": (1, _make_RO), - "rw": (1, _make_RW), "touch": (1, _touch), - "cd": (1, lambda test, args: test.chdir(args[0])), - "ls": (1, lambda test, args: test.ls(args[0])), "unpack": (2, _unpack), - "cat": (1, _cat), "store": (2, lambda test, args: test.store_output(args[0], args[1:])), - "shell": (0, _shell), + "ro": (1, _make_RO), "mock": (2, lambda test, args: test.mock(args[0], args[1])), "generate": (3, lambda test, args: test.generate(args[0], args[1], args[2:])), + "cp": (2, lambda test, args: test.cp(args[0], args[1])), + "rw": (1, _make_RW), + "ls": (1, lambda test, args: test.ls(args[0])), + "cat": (1, _cat), + "shell": (0, _shell), } diff --git a/tools/json_tests/driver/test.py b/tools/json_tests/driver/test.py index 42cdf41e..85acb65f 100644 --- a/tools/json_tests/driver/test.py +++ b/tools/json_tests/driver/test.py @@ -60,6 +60,7 @@ class Env: target: str build_dir: str data_dir: str + inst_dir: str tempdir: str version: str counter_digits: int @@ -76,6 +77,7 @@ def expand(self, input: str, tempdir: str, additional: Dict[str, str] = {}): input = ( input.replace("$TMP", tempdir) .replace("$DATA", self.data_dir) + .replace("$INST", self.inst_dir) .replace("$VERSION", self.version) ) for key, value in additional.items(): @@ -94,17 +96,32 @@ def fix(self, raw_input: bytes, patches: Dict[str, str]): input = _alt_sep(input, self.tempdir_alt, "$TMP") input = _alt_sep(input, self.data_dir_alt, "$DATA") - if not len(patches): - return input + builtins = { + "\x1B\\[31m\\[(.+) [0-9a-fA-F]+\\]\x1B\\[m (.+)": "\x1B[31m[\\1 $REPORT]\x1B[m \\2", + " \x1B\\[2;37mbased on\x1B\\[m \x1B\\[2;33m[0-9a-fA-F]+@(.+)\x1B\\[m": " \x1B[2;37mbased on\x1B[m \x1B[2;33m$HEAD@\\1\x1B[m", + " \x1B\\[2;37mcontains [0-9a-fA-F]+:\x1B\\[m (.+)": " \x1B[2;37mcontains $BUILD:\x1B[m \\1", + " based on [0-9a-fA-F]+@(.+)": " based on $HEAD@\\1", + " contains [0-9a-fA-F]+: (.+)": " contains $BUILD: \\1", + "(\\s+)parent [0-9a-fA-F]+": "\\1parent $PARENT", + "Added:(\\s+).*": "Added:\\1$DATE", + "CommitDate:(\\s+).*": "CommitDate:\\1$DATE", + "\\[(.+) [0-9a-fA-F]+\\] (.+)": "[\\1 $REPORT] \\2", + } lines = input.split("\n") - for patch in patches: - patched = patches[patch] + for patch, replacement in builtins.items(): + pattern = re.compile(patch) + for lineno in range(len(lines)): + m = pattern.match(lines[lineno]) + if m: + lines[lineno] = m.expand(replacement) + + for patch, replacement in patches.items(): pattern = re.compile(patch) for lineno in range(len(lines)): m = pattern.match(lines[lineno]) if m: - lines[lineno] = m.expand(patched) + lines[lineno] = m.expand(replacement) return "\n".join(lines) diff --git a/tools/json_tests/driver/testbed.py b/tools/json_tests/driver/testbed.py index 5f18ebf7..d7c806e3 100644 --- a/tools/json_tests/driver/testbed.py +++ b/tools/json_tests/driver/testbed.py @@ -97,6 +97,7 @@ def task( env1.target, env1.build_dir, env1.data_dir, + env1.inst_dir, tempdir, env1.version, env1.counter_digits, diff --git a/tools/json_tests/test_driver.py b/tools/json_tests/test_driver.py index f1c5efcd..eb59afd3 100755 --- a/tools/json_tests/test_driver.py +++ b/tools/json_tests/test_driver.py @@ -124,6 +124,7 @@ def _make_env(args: argparse.Namespace, counter_total: int): target=target, build_dir=os.path.dirname(os.path.dirname(target)), data_dir=args.data_dir, + inst_dir=os.path.join(os.path.dirname(args.data_dir), "copy", "bin"), tempdir=tempdir, version=args.version, counter_digits=digits, diff --git a/tools/run_ctest.py b/tools/run_ctest.py old mode 100644 new mode 100755 From 1b3083c24a2b60726b7c231b23be7c845939dceb Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Mon, 14 Aug 2023 18:08:03 +0200 Subject: [PATCH 34/39] ci: get runner from github --- .vscode/settings.json | 9 +- CMakeLists.txt | 5 + apps/CMakeLists.txt | 24 ++--- apps/tests/runner-schema.json | 1 + tools/download-runner.py | 195 ++++++++++++++++++++++++++++++++++ tools/flow/lib/matrix.py | 6 ++ 6 files changed, 227 insertions(+), 13 deletions(-) create mode 120000 apps/tests/runner-schema.json create mode 100755 tools/download-runner.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 147dd65e..d33fb5d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,25 +5,32 @@ "arglist", "cfglng", "cobertura", - "covdata", "covcollect", + "covdata", "covlng", "covmodules", + "cpack", + "ctest", + "DCOV", "demangled", + "devel", "errlng", "fmtlng", "hilite", "initlng", + "libexec", "lngs", "loglng", "modcnt", "modlng", + "oneline", "pofile", "polib", "propset", "refslng", "replng", "resetlng", + "stdclang", "workdir" ], "files.associations": { diff --git a/CMakeLists.txt b/CMakeLists.txt index 3260f037..92c5e216 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,11 @@ if (COV_TESTING) enable_testing() find_package(GTest REQUIRED) + find_program(Runner_EXECUTABLE runner REQUIRED HINTS + "${PROJECT_SOURCE_DIR}/build/downloads" + "${PROJECT_SOURCE_DIR}/../build/release/bin" + ) + message(STATUS "Runner_EXECUTABLE is: ${Runner_EXECUTABLE}") set(COVERALLS_PREFIX cov_) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 0e286aa5..3fbd2aff 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -124,6 +124,8 @@ if (COV_TESTING) ) endforeach() + string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_PRESET) + foreach(TEST_SET 001-cov 002-init @@ -139,24 +141,22 @@ if (COV_TESTING) 016-collect ) add_test( - NAME cov-exec--${TEST_SET} - COMMAND "${Python3_EXECUTABLE}" - "${PROJECT_SOURCE_DIR}/tools/json_tests/runner.py" - --bin "${PROJECT_BINARY_DIR}" + NAME cov-exec--${TEST_SET}-alt + COMMAND "${Runner_EXECUTABLE}" + --preset "${CMAKE_PRESET}" --tests "main-set/${TEST_SET}" - --version "${PROJECT_VERSION}${PROJECT_VERSION_STABILITY}${PROJECT_VERSION_BUILD_META}" - ) + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + ) endforeach() if (NOT cov_COVERALLS) add_test( - NAME cov-exec-pl - COMMAND "${Python3_EXECUTABLE}" - "${PROJECT_SOURCE_DIR}/tools/json_tests/runner.py" - --bin "${PROJECT_BINARY_DIR}" + NAME cov-exec-pl-alt + COMMAND "${Runner_EXECUTABLE}" + --preset "${CMAKE_PRESET}" --tests "messages-pl" - --version "${PROJECT_VERSION}${PROJECT_VERSION_STABILITY}${PROJECT_VERSION_BUILD_META}" - ) + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + ) endif() if (CMAKE_GENERATOR MATCHES "Visual Studio" AND TARGET cov_coveralls_test) diff --git a/apps/tests/runner-schema.json b/apps/tests/runner-schema.json new file mode 120000 index 00000000..551bcd98 --- /dev/null +++ b/apps/tests/runner-schema.json @@ -0,0 +1 @@ +../../build/downloads/runner-schema.json \ No newline at end of file diff --git a/tools/download-runner.py b/tools/download-runner.py new file mode 100755 index 00000000..ef5c1c28 --- /dev/null +++ b/tools/download-runner.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# Copyright (c) 2023 Marcin Zdun +# This code is licensed under MIT license (see LICENSE for details) + +import hashlib +import io +import os +import sys +from typing import Dict + +import requests + +TOOL_DIR = f"build/downloads" +if os.name == "nt": + ARCHIVE_EXT = "zip" + ARCHIVE_ARCH = "windows-x86_64" + EXEC_EXT = ".exe" +else: + ARCHIVE_EXT = "tar.gz" + ARCHIVE_ARCH = "ubuntu-22.04-x86_64" + EXEC_EXT = "" + + +def _hash(filename: str) -> str: + sha = hashlib.sha256() + with open(filename, "rb") as data: + for block in iter(lambda: data.read(io.DEFAULT_BUFFER_SIZE), b""): + sha.update(block) + return sha.hexdigest() + + +def _download(url: str, filename: str, store: bool = True): + response = requests.get(url, allow_redirects=True) + if response.status_code // 100 != 2: + print( + f"{url}: download failed: {response.status_code}, {response.reason}", + file=sys.stderr, + ) + return None + if not store: + return response.content + + with open(filename, "wb") as file: + file.write(response.content) + return True + + +if os.name == "nt": + import zipfile + + def _extract(path: str, entry: str, target_path: str): + with zipfile.ZipFile(path) as zip: + try: + info = zip.getinfo(entry) + except KeyError: + print( + f"{path}: extract failed: {entry} not found", + file=sys.stderr, + ) + return False + + entry_data = zip.open(info) + try: + with open(target_path, "wb") as binary_dest: + for block in iter( + lambda: entry_data.read(io.DEFAULT_BUFFER_SIZE), b"" + ): + binary_dest.write(block) + finally: + entry_data.close() + return True + +else: + import tarfile + + def _extract(path: str, entry: str, target_path: str): + with tarfile.open(path) as tar: + try: + info = tar.getmember(entry) + except KeyError: + print( + f"{path}: extract failed: {entry} not found", + file=sys.stderr, + ) + return False + entry_data = tar.extractfile(info) + try: + with open(target_path, "wb") as binary_dest: + for block in iter( + lambda: entry_data.read(io.DEFAULT_BUFFER_SIZE), b"" + ): + binary_dest.write(block) + finally: + entry_data.close() + + if not info.issym(): + try: + os.chmod(target_path, info.mode) + except OSError as e: + print( + f"{target_path}: could not change mode: {e}", + file=sys.stderr, + ) + return False + try: + os.utime(target_path, (info.mtime, info.mtime)) + except OSError as e: + print( + f"{target_path}: could not change modification time: {e}", + file=sys.stderr, + ) + return False + + return True + + +def download_tools(version: str): + package_name = f"runner-{version}-{ARCHIVE_ARCH}" + sha_url = ( + f"https://github.com/mzdun/runner/releases/download/v{version}/sha256sum.txt" + ) + arch_url = f"https://github.com/mzdun/runner/releases/download/v{version}/{package_name}.{ARCHIVE_EXT}" + path = f"{TOOL_DIR}/{package_name}.{ARCHIVE_EXT}" + + os.makedirs(TOOL_DIR, exist_ok=True) + + print(f"[DL] {sha_url}", file=sys.stderr) + sha256sum_text = _download(sha_url, f"{TOOL_DIR}/sha256sum.txt", False) + if not sha256sum_text: + return False + sha256sum: Dict[str, str] = {} + + for hash, filename in [ + line.split(" ", 1) + for line in sha256sum_text.decode("UTF-8").split("\n") + if line != "" + ]: + if filename[:1] != "*": + continue + filename = filename[1:] + sha256sum[filename] = hash + + expected_hash = sha256sum.get(f"{package_name}.{ARCHIVE_EXT}") + if expected_hash is None: + print( + f"{sha_url}: error: cannot locate sha256sum for {package_name}.{ARCHIVE_EXT}", + file=sys.stderr, + ) + return False + + needs_download = True + if os.path.isfile(path): + needs_download = _hash(path) != expected_hash + + if not needs_download: + print(f"[USE] {path}", file=sys.stderr) + + if needs_download: + print(f"[DL] {arch_url}", file=sys.stderr) + if not _download(arch_url, path): + return False + actual_hash = _hash(path) + if actual_hash != expected_hash: + os.remove(path) + print( + f"{arch_url}: download failed: unexpected sh256sum:\n expecting {expected_hash}\n received {actual_hash}", + file=sys.stderr, + ) + return False + + short_version = ".".join(version.split(".")[:2]) + print( + f"[EXTRACT] {package_name}/share/runner-{short_version}/schema.json", + file=sys.stderr, + ) + if not _extract( + path, + f"{package_name}/share/runner-{short_version}/schema.json", + f"{TOOL_DIR}/runner-schema.json", + ): + return False + + print(f"[EXTRACT] {package_name}/bin/runner{EXEC_EXT}", file=sys.stderr) + if not _extract( + path, f"{package_name}/bin/runner{EXEC_EXT}", f"{TOOL_DIR}/runner{EXEC_EXT}" + ): + return False + + return True + + +if __name__ == "__main__" and not download_tools( + "0.1.2" if len(sys.argv) < 2 else sys.argv[1] +): + sys.exit(1) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 81ce4687..dc7b6939 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -29,6 +29,7 @@ _collect_version = (0, 22, 0) _report_version = (0, 20, 0) +_runner_version = (0, 1, 2) platform = _platform_name @@ -312,6 +313,11 @@ def configure_cmake(config: dict): cov_COVERALLS = "ON" if config.get("coverage") else "OFF" COV_SANITIZE = "ON" if config.get("sanitizer") else "OFF" COV_CUTDOWN_OS = "ON" if runner.CUTDOWN_OS else "OFF" + runner.call( + sys.executable, + "tools/download-runner.py", + ".".join(str(x) for x in _runner_version), + ) runner.call( "cmake", "--preset", From fdea071aee627b3afdd19c4c7d7ecbb4412ba3d7 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Mon, 14 Aug 2023 19:41:19 +0200 Subject: [PATCH 35/39] test: mark $chema in test files --- apps/tests/main-set/001-cov/001-version.json | 1 + apps/tests/main-set/001-cov/002-help.json | 1 + .../main-set/001-cov/003-unknown-option.json | 1 + apps/tests/main-set/001-cov/004-alias.json | 1 + .../001-cov/005-alias-short-help.json | 1 + .../main-set/001-cov/006-alias-long-help.json | 1 + .../001-cov/007-alias-to-nothing.json | 1 + .../tests/main-set/001-cov/008-bad-alias.json | 5 ++--- .../main-set/001-cov/009-external-tool.json | 1 + .../001-cov/010-escaped-arguments.json | 2 +- .../001-cov/011-multiple-aliases.json | 1 + .../tests/main-set/001-cov/012-list-cmds.json | 1 + .../001-cov/013-bad-alias-full-output.json | 1 + .../014-echo-with-nonascii-arguments.json | 1 + .../001-cov/015-bad-alias-with-env.json | 19 ++++++++----------- .../016-external-tool-outside-libexec.json | 1 + .../main-set/002-init/015-init-no-args.json | 1 + .../main-set/002-init/016-init-git-dir.json | 1 + .../main-set/002-init/017-init-directory.json | 1 + .../main-set/002-init/018-init-dependent.json | 1 + .../002-init/019-init-independent.json | 1 + .../002-init/020-init-no-gitrepo.json | 1 + .../002-init/021-init-no-args-no-cwd.json | 5 ++--- .../002-init/022-init-git-dir-relative.json | 1 + .../main-set/002-init/023-init-no-force.json | 1 + .../main-set/002-init/024-init-force.json | 1 + .../003-config-A/025-config-no-args.json | 1 + .../003-config-A/026-config-list-local.json | 1 + .../003-config-A/027-config-list-global.json | 3 ++- .../003-config-A/028-config-list-system.json | 3 ++- .../003-config-A/029-config-list-file.json | 1 + .../004-config-B/030-config-list-any.json | 3 ++- .../031-config-list-after-get.json | 1 + .../032-config-unset-after-list.json | 1 + .../033-config-add-after-unset-all.json | 1 + .../034-config-get-all-after-get.json | 1 + .../035-config-list-local-no-cov.json | 1 + .../004-config-B/036-config-add-one-arg.json | 1 + .../037-config-unset-too-many.json | 1 + .../038-config-set-but-multivar.json | 5 ++--- .../039-config-set-but-include.json | 1 + .../040-config-unset-but-multivar.json | 5 ++--- .../041-config-unset-but-not-there.json | 5 ++--- .../042-config-unset-but-no-a-key.json | 5 ++--- .../main-set/005-config-C/043-config-get.json | 11 +++-------- .../005-config-C/044-config-get-all.json | 5 ++--- .../main-set/005-config-C/045-config-add.json | 1 + .../005-config-C/046-config-unset-all.json | 1 + .../006-module-A/047-module-help.json | 1 + .../048-module-build-and-print.json | 1 + .../049-module-build-and-print-sep.json | 7 ++----- .../050-module-deconstruct-and-print.json | 1 + .../051-module-modify-in-bare-git.json | 1 + .../052-module-add-duplicate.json | 1 + .../053-module-remove-from-nothing.json | 1 + .../054-module-print-from-HEAD.json | 1 + .../055-module-print-sep-from-HEAD.json | 7 ++----- .../056-module-open_from_ref-range.json | 1 + .../057-module-open_from_ref-tree.json | 1 + .../007-module-B/058-module-no-git.json | 1 + .../007-module-B/059-module-excl-show.json | 1 + .../060-module-excl-show-sep.json | 1 + .../061-module-too-many-refs.json | 1 + .../062-module-too-little-args.json | 1 + .../062-module-too-many-args.json | 1 + .../007-module-B/063-module-no-covmodule.json | 7 ++----- .../064-module-no-covmodule-add.json | 1 + ...5-module-open_from_ref-no-such-object.json | 7 ++----- .../008-report-A/066-report-no-args.json | 1 + .../008-report-A/067-report-help.json | 1 + .../008-report-A/068-report-no-cov.json | 1 + .../008-report-A/069-report-no-commit.json | 1 + .../070-report-failing-filter.json | 1 + .../008-report-A/071-report-no-filter.json | 1 + .../008-report-A/072-report-not-the-json.json | 1 + .../073-report-not-the-json-filtered.json | 1 + .../009-report-B/074-report-no-file.json | 1 + .../009-report-B/075-report-empty.json | 7 ++----- .../009-report-B/076-report-one-file.json | 7 ++----- .../077-report-amend-on-empty.json | 4 +--- .../009-report-B/078-D-report-with-props.json | 7 ++----- .../078-report-amend-on-parentless.json | 7 ++----- .../079-B-report-the-same-twice.json | 1 + .../079-C-report-almost-the-same-twice.json | 1 + .../009-report-B/079-report-with-parent.json | 1 + .../009-report-B/080-report-on-detached.json | 9 ++------- .../081-report-hash-bang-less.json | 1 + .../main-set/010-log/082-log-no-args.json | 5 ++--- .../010-log/083-log-no-args-inited.json | 1 + .../010-log/084-log-no-args-Dmain.json | 8 ++------ .../010-log/085-log-G..K-oneline.json | 1 + .../086-log-separate-raw-decorate.json | 1 + .../087-log-feat3-fuller-decorate.json | 9 ++------- .../010-log/088-log-G..K-oneline-color.json | 1 + .../010-log/089-log-B..K-format-pretty.json | 5 ++--- .../090-log-B..K-no-format-but-pretty.json | 5 ++--- .../010-log/091-2-log-HEAD-format-custom.json | 4 +--- .../010-log/091-log-B..K-format-unknown.json | 4 +--- apps/tests/main-set/010-log/092-log-help.json | 1 + .../main-set/010-log/093-log-two-HEADs.json | 1 + .../main-set/010-log/094-log-123456789.json | 1 + .../010-log/095-log-try-non-report.json | 1 + .../main-set/011-refs/095-branch-no-args.json | 5 ++--- .../main-set/011-refs/096-tag-no-args.json | 5 ++--- .../main-set/011-refs/097-branch-help.json | 5 ++--- .../tests/main-set/011-refs/098-tag-help.json | 5 ++--- .../main-set/011-refs/099-branch-list.json | 1 + .../011-refs/100-branch-list-color.json | 1 + .../tests/main-set/011-refs/101-tag-list.json | 1 + .../main-set/011-refs/102-branch-current.json | 7 ++----- .../011-refs/103-branch-only-feat.json | 1 + .../011-refs/104-branch-force-delete.json | 1 + .../011-refs/105-branch-two-commands.json | 1 + .../106-A-branch-create-start-point.json | 1 + ...6-B-branch-create-invalid-start-point.json | 1 + .../main-set/011-refs/106-branch-create.json | 7 ++----- .../011-refs/107-branch-create-forced.json | 7 ++----- .../011-refs/108-branch-create-existing.json | 1 + .../109-branch-create-three-at-a-time.json | 1 + .../011-refs/110-branch-create-unborn.json | 1 + .../011-refs/111-branch-delete-nothing.json | 1 + .../011-refs/112-branch-delete-main.json | 1 + .../011-refs/113-branch-delete-other.json | 7 ++----- .../114-branch-delete-nonexisting.json | 1 + .../main-set/011-refs/115-tag-create.json | 7 ++----- .../011-refs/116-tag-create-forced.json | 7 ++----- .../011-refs/117-tag-create-existing.json | 1 + .../118-tag-create-three-at-a-time.json | 1 + .../011-refs/119-tag-create-unborn.json | 1 + .../main-set/011-refs/120-tag-delete-tag.json | 7 ++----- .../011-refs/121-tag-delete-nonexisting.json | 1 + .../011-refs/122-branch-create-invalid.json | 1 + .../011-refs/123-tag-create-invalid.json | 3 ++- .../011-refs/124-branch-list-detached.json | 1 + .../012-checkout/125-checkout-no-args.json | 5 ++--- .../012-checkout/126-checkout-no-cov.json | 5 ++--- .../012-checkout/127-checkout-help.json | 5 ++--- .../012-checkout/128-checkout-two-names.json | 1 + .../129-checkout-too-many-for-branching.json | 1 + ...130-checkout-too-little-for-branching.json | 1 + .../131-checkout-two-commands.json | 1 + .../012-checkout/132-checkout-branch.json | 1 + .../012-checkout/133-checkout-orphan.json | 1 + .../134-checkout-orphan-main.json | 1 + .../135-checkout-orphan-invalid-spec.json | 1 + .../012-checkout/136-checkout-existing.json | 1 + .../012-checkout/137-checkout-tag.json | 1 + .../138-checkout-without-HEAD.json | 1 + .../139-checkout-start-point.json | 1 + .../main-set/013-reset/140-reset-help.json | 5 ++--- .../main-set/013-reset/141-reset-no-args.json | 2 ++ .../013-reset/142-reset-no-cov-HEAD.json | 1 + .../013-reset/143-reset-switch-to-a-tag.json | 9 +++++---- .../144-reset-switch-detached-HEAD.json | 9 +++++---- .../main-set/014-show/145-show-help.json | 5 ++--- .../014-show/146-show-no-args-unborn.json | 1 + .../main-set/014-show/147-show-no-args.json | 6 +++--- .../014-show/148-show-no-args-module.json | 6 +++--- .../main-set/014-show/149-show-directory.json | 1 + .../main-set/014-show/150-A-show-file.json | 1 + .../014-show/150-B-show-file-color.json | 1 + .../014-show/150-C-show-file-many-chunks.json | 1 + .../main-set/014-show/151-show-module.json | 1 + .../main-set/014-show/152-show-range.json | 6 +++--- .../014-show/153-show-not-a-covmodule.json | 6 +++--- .../014-show/154-show-HEAD..HEAD.json | 6 +++--- .../014-show/155-show-module-props.json | 1 + .../156-show-module-props-colors.json | 1 + .../157-show-module-props-colors-empty.json | 1 + .../main-set/014-show/158-show-functions.json | 4 ++-- .../014-show/159-show-functions-log.json | 6 +++--- .../014-show/160-show-functions-log.json | 4 ++-- .../main-set/014-show/161-show-no-chunks.json | 4 ++-- .../162-show-module-props-indented.json | 8 +++----- .../014-show/163-show-file-in-build.json | 1 + .../014-show/163-show-file-in-files.json | 6 ++---- .../015-filters-A/01-strip-excludes.json | 10 ++++------ .../015-filters-A/02-strip-excludes-osOS.json | 14 ++++---------- .../03-A-strip-excludes-llvm.json | 11 ++++------- .../03-B-strip-excludes-clang.json | 11 ++++------- .../04-strip-excludes-compilerA-OS.json | 14 ++++---------- .../05-strip-excludes-multi.json | 11 ++++------- .../06-strip-excludes-no-such.json | 2 +- .../07-A-strip-excludes-broken.json | 2 +- .../07-B-strip-excludes-broken.json | 2 +- .../07-C-strip-excludes-broken.json | 16 ++++++++++++++++ .../main-set/016-collect/01-collect-help.json | 6 ++---- .../016-collect/02-collect-unborn.json | 2 +- .../016-collect/03-collect-no-HEAD.json | 2 +- .../016-collect/04-collect-too-many-args.json | 2 +- .../05-collect-too-little-args.json | 2 +- .../016-collect/06-collect-observe.json | 3 ++- .../016-collect/07-collect-clang.json | 4 ++-- .../main-set/016-collect/08-collect-gcc.json | 4 ++-- .../016-collect/09-collect-gcc-triple.json | 2 +- .../016-collect/10-collect-clean.json | 8 ++------ .../016-collect/11-collect-no-output.json | 4 ++-- .../main-set/016-collect/12-collect-msvc.json | 5 ++--- .../messages-pl/001-cov/001-version.json | 1 + apps/tests/messages-pl/001-cov/002-help.json | 1 + .../001-cov/003-unknown-option.json | 1 + apps/tests/messages-pl/001-cov/004-alias.json | 1 + .../001-cov/005-alias-short-help.json | 1 + .../001-cov/007-alias-to-nothing.json | 1 + .../messages-pl/001-cov/008-bad-alias.json | 16 +++------------- .../001-cov/013-bad-alias-full-output.json | 1 + .../002-init/015-init-no-args.json | 1 + .../002-init/020-init-no-gitrepo.json | 1 + .../002-init/021-init-no-args-no-cwd.json | 5 ++--- .../002-init/023-init-no-force.json | 1 + .../messages-pl/002-init/024-init-force.json | 1 + .../003-config/025-config-no-args.json | 1 + .../003-config/031-config-list-after-get.json | 1 + .../032-config-unset-after-list.json | 1 + .../033-config-add-after-unset-all.json | 1 + .../034-config-get-all-after-get.json | 1 + .../035-config-list-local-no-cov.json | 1 + .../003-config/036-config-add-one-arg.json | 1 + .../003-config/037-config-unset-too-many.json | 1 + .../038-config-set-but-multivar.json | 5 ++--- .../039-config-set-but-include.json | 1 + .../040-config-unset-but-multivar.json | 5 ++--- .../041-config-unset-but-not-there.json | 5 ++--- .../042-config-unset-but-no-a-key.json | 5 ++--- .../004-module/047-module-help.json | 1 + .../051-module-modify-in-bare-git.json | 1 + .../004-module/052-module-add-duplicate.json | 1 + .../053-module-remove-from-nothing.json | 1 + .../056-module-open_from_ref-range.json | 1 + .../057-module-open_from_ref-tree.json | 1 + .../004-module/058-module-no-git.json | 1 + .../004-module/059-module-excl-show.json | 1 + .../004-module/060-module-excl-show-sep.json | 1 + .../004-module/061-module-too-many-refs.json | 1 + .../062-module-too-little-args.json | 1 + .../004-module/062-module-too-many-args.json | 1 + .../064-module-no-covmodule-add.json | 1 + .../005-report/066-report-no-args.json | 1 + .../005-report/067-report-help.json | 1 + .../005-report/068-report-no-cov.json | 1 + .../005-report/069-report-no-commit.json | 1 + .../005-report/070-report-failing-filter.json | 1 + .../005-report/071-report-no-filter.json | 1 + .../005-report/072-report-not-the-json.json | 1 + .../073-report-not-the-json-filtered.json | 1 + .../005-report/074-report-no-file.json | 1 + .../005-report/075-report-empty.json | 1 + .../005-report/076-report-one-file.json | 1 + .../005-report/077-report-amend-on-empty.json | 5 ++--- .../005-report/078-D-report-with-props.json | 1 + .../078-report-amend-on-parentless.json | 1 + .../079-B-report-the-same-twice.json | 1 + .../005-report/079-report-with-parent.json | 1 + .../005-report/080-report-on-detached.json | 1 + .../005-report/081-report-hash-bang-less.json | 1 + .../messages-pl/006-log/082-log-no-args.json | 5 ++--- .../006-log/083-log-no-args-inited.json | 1 + .../006-log/084-log-no-args-Dmain.json | 5 ++--- .../messages-pl/006-log/092-log-help.json | 1 + .../006-log/093-log-two-HEADs.json | 1 + .../006-log/094-log-123456789.json | 1 + .../006-log/095-log-try-non-report.json | 1 + .../007-refs/095-branch-no-args.json | 5 ++--- .../messages-pl/007-refs/096-tag-no-args.json | 5 ++--- .../messages-pl/007-refs/097-branch-help.json | 5 ++--- .../messages-pl/007-refs/098-tag-help.json | 5 ++--- .../007-refs/104-branch-force-delete.json | 1 + .../007-refs/105-branch-two-commands.json | 1 + .../007-refs/108-branch-create-existing.json | 1 + .../109-branch-create-three-at-a-time.json | 1 + .../007-refs/110-branch-create-unborn.json | 1 + .../007-refs/111-branch-delete-nothing.json | 1 + .../007-refs/112-branch-delete-main.json | 1 + .../114-branch-delete-nonexisting.json | 1 + .../007-refs/117-tag-create-existing.json | 1 + .../118-tag-create-three-at-a-time.json | 1 + .../007-refs/119-tag-create-unborn.json | 1 + .../007-refs/121-tag-delete-nonexisting.json | 1 + .../007-refs/122-branch-create-invalid.json | 1 + .../007-refs/123-tag-create-invalid.json | 1 + .../012-checkout/125-checkout-no-args.json | 5 ++--- .../012-checkout/126-checkout-no-cov.json | 5 ++--- .../012-checkout/127-checkout-help.json | 5 ++--- .../012-checkout/128-checkout-two-names.json | 1 + .../129-checkout-too-many-for-branching.json | 1 + ...130-checkout-too-little-for-branching.json | 1 + .../131-checkout-two-commands.json | 1 + .../012-checkout/133-checkout-orphan.json | 1 + .../134-checkout-orphan-main.json | 1 + .../135-checkout-orphan-invalid-spec.json | 1 + .../138-checkout-without-HEAD.json | 1 + .../messages-pl/014-show/145-show-help.json | 5 ++--- .../014-show/146-show-no-args-unborn.json | 1 + 293 files changed, 428 insertions(+), 362 deletions(-) create mode 100644 apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json diff --git a/apps/tests/main-set/001-cov/001-version.json b/apps/tests/main-set/001-cov/001-version.json index 9064245f..a62883df 100644 --- a/apps/tests/main-set/001-cov/001-version.json +++ b/apps/tests/main-set/001-cov/001-version.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "--version", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/002-help.json b/apps/tests/main-set/001-cov/002-help.json index f9378478..dd8cd8cd 100644 --- a/apps/tests/main-set/001-cov/002-help.json +++ b/apps/tests/main-set/001-cov/002-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "--help", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/003-unknown-option.json b/apps/tests/main-set/001-cov/003-unknown-option.json index 67bf2596..2a81a3fa 100644 --- a/apps/tests/main-set/001-cov/003-unknown-option.json +++ b/apps/tests/main-set/001-cov/003-unknown-option.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "--versions", "expected": [ 2, diff --git a/apps/tests/main-set/001-cov/004-alias.json b/apps/tests/main-set/001-cov/004-alias.json index d9a85cc3..c8a07eac 100644 --- a/apps/tests/main-set/001-cov/004-alias.json +++ b/apps/tests/main-set/001-cov/004-alias.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C recurse first -D", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/005-alias-short-help.json b/apps/tests/main-set/001-cov/005-alias-short-help.json index 4ae44444..8890e6b3 100644 --- a/apps/tests/main-set/001-cov/005-alias-short-help.json +++ b/apps/tests/main-set/001-cov/005-alias-short-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C recurse second -h", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/006-alias-long-help.json b/apps/tests/main-set/001-cov/006-alias-long-help.json index 24e2530e..1ab593a3 100644 --- a/apps/tests/main-set/001-cov/006-alias-long-help.json +++ b/apps/tests/main-set/001-cov/006-alias-long-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C recurse second --not-help --help", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/007-alias-to-nothing.json b/apps/tests/main-set/001-cov/007-alias-to-nothing.json index 117e9833..13f51280 100644 --- a/apps/tests/main-set/001-cov/007-alias-to-nothing.json +++ b/apps/tests/main-set/001-cov/007-alias-to-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C bad-recurse start-bad", "expected": [ 22, diff --git a/apps/tests/main-set/001-cov/008-bad-alias.json b/apps/tests/main-set/001-cov/008-bad-alias.json index 26902b17..901bf202 100644 --- a/apps/tests/main-set/001-cov/008-bad-alias.json +++ b/apps/tests/main-set/001-cov/008-bad-alias.json @@ -1,8 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "-C bad-recurse first -D", - "check": { - "stderr": "begin" - }, + "check": {"stderr": "begin"}, "expected": [ 1, "", diff --git a/apps/tests/main-set/001-cov/009-external-tool.json b/apps/tests/main-set/001-cov/009-external-tool.json index a2e266c0..54b1deca 100644 --- a/apps/tests/main-set/001-cov/009-external-tool.json +++ b/apps/tests/main-set/001-cov/009-external-tool.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "echo arg1 arg2 ...", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/010-escaped-arguments.json b/apps/tests/main-set/001-cov/010-escaped-arguments.json index 07bbd438..4f5930b6 100644 --- a/apps/tests/main-set/001-cov/010-escaped-arguments.json +++ b/apps/tests/main-set/001-cov/010-escaped-arguments.json @@ -1,5 +1,5 @@ { - "os": "nt", + "$schema": "../../runner-schema.json", "args": "echo 'argument with space' 'argument with \\ backslash' 'argument with \"quotes\"' 'argument with '\"'\"'apos'\"'\"'' 'this thing: \\\"' 'that thing: \\\\'", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/011-multiple-aliases.json b/apps/tests/main-set/001-cov/011-multiple-aliases.json index e21b1837..cfa5c908 100644 --- a/apps/tests/main-set/001-cov/011-multiple-aliases.json +++ b/apps/tests/main-set/001-cov/011-multiple-aliases.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C recurse name", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/012-list-cmds.json b/apps/tests/main-set/001-cov/012-list-cmds.json index fefc8f7b..437a1eb6 100644 --- a/apps/tests/main-set/001-cov/012-list-cmds.json +++ b/apps/tests/main-set/001-cov/012-list-cmds.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": null, "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/001-cov/013-bad-alias-full-output.json b/apps/tests/main-set/001-cov/013-bad-alias-full-output.json index 9cbc4496..ac33dbcf 100644 --- a/apps/tests/main-set/001-cov/013-bad-alias-full-output.json +++ b/apps/tests/main-set/001-cov/013-bad-alias-full-output.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "definitely-not-a-tool", "expected": [ 1, diff --git a/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json b/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json index 3a6c59fb..955e1a21 100644 --- a/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json +++ b/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "-C 'utf8-αβγδε' first '--hjälp'", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/015-bad-alias-with-env.json b/apps/tests/main-set/001-cov/015-bad-alias-with-env.json index 5655ac8f..ef96777e 100644 --- a/apps/tests/main-set/001-cov/015-bad-alias-with-env.json +++ b/apps/tests/main-set/001-cov/015-bad-alias-with-env.json @@ -1,16 +1,13 @@ { + "$schema": "../../runner-schema.json", "args": "-C bad-recurse first -D", - "env": { - "COV_PATH": [ - "$TMP", - "", - "$TMP/tools", - "" - ] - }, - "check": { - "stderr": "begin" - }, + "env": {"COV_PATH": [ + "$TMP", + "", + "$TMP/tools", + "" + ]}, + "check": {"stderr": "begin"}, "expected": [ 1, "", diff --git a/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json b/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json index 33a16972..1f395f3e 100644 --- a/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json +++ b/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "pwd", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/015-init-no-args.json b/apps/tests/main-set/002-init/015-init-no-args.json index 491cf484..b53ea1e5 100644 --- a/apps/tests/main-set/002-init/015-init-no-args.json +++ b/apps/tests/main-set/002-init/015-init-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/016-init-git-dir.json b/apps/tests/main-set/002-init/016-init-git-dir.json index 0769dbf6..a0929165 100644 --- a/apps/tests/main-set/002-init/016-init-git-dir.json +++ b/apps/tests/main-set/002-init/016-init-git-dir.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --git-dir '$TMP'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/017-init-directory.json b/apps/tests/main-set/002-init/017-init-directory.json index be99b50a..447cc956 100644 --- a/apps/tests/main-set/002-init/017-init-directory.json +++ b/apps/tests/main-set/002-init/017-init-directory.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init '$TMP/subdir'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/018-init-dependent.json b/apps/tests/main-set/002-init/018-init-dependent.json index b934f15a..663b7106 100644 --- a/apps/tests/main-set/002-init/018-init-dependent.json +++ b/apps/tests/main-set/002-init/018-init-dependent.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --git-dir '$TMP' '$TMP/subdir'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/019-init-independent.json b/apps/tests/main-set/002-init/019-init-independent.json index e7d97c7e..949ba272 100644 --- a/apps/tests/main-set/002-init/019-init-independent.json +++ b/apps/tests/main-set/002-init/019-init-independent.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --git-dir '$TMP/repo.git' '$TMP/repo.covdata'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/020-init-no-gitrepo.json b/apps/tests/main-set/002-init/020-init-no-gitrepo.json index b0021343..5395a489 100644 --- a/apps/tests/main-set/002-init/020-init-no-gitrepo.json +++ b/apps/tests/main-set/002-init/020-init-no-gitrepo.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --git-dir '$TMP/repo.git' '$TMP/repo.covdata'", "expected": [ 2, diff --git a/apps/tests/main-set/002-init/021-init-no-args-no-cwd.json b/apps/tests/main-set/002-init/021-init-no-args-no-cwd.json index 2de4034f..836bd7e9 100644 --- a/apps/tests/main-set/002-init/021-init-no-args-no-cwd.json +++ b/apps/tests/main-set/002-init/021-init-no-args-no-cwd.json @@ -1,8 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "init", - "patches": { - "cov init: error: argument -C: .*": "cov init: error: argument -C: ERROR MESSAGE" - }, + "patches": {"cov init: error: argument -C: .*": "cov init: error: argument -C: ERROR MESSAGE"}, "expected": [ 2, "", diff --git a/apps/tests/main-set/002-init/022-init-git-dir-relative.json b/apps/tests/main-set/002-init/022-init-git-dir-relative.json index 33476d33..99eb87a5 100644 --- a/apps/tests/main-set/002-init/022-init-git-dir-relative.json +++ b/apps/tests/main-set/002-init/022-init-git-dir-relative.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --git-dir ../.git", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/023-init-no-force.json b/apps/tests/main-set/002-init/023-init-no-force.json index 98f6d691..b6f46f5a 100644 --- a/apps/tests/main-set/002-init/023-init-no-force.json +++ b/apps/tests/main-set/002-init/023-init-no-force.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init", "expected": [ 1, diff --git a/apps/tests/main-set/002-init/024-init-force.json b/apps/tests/main-set/002-init/024-init-force.json index 666c28b1..392b78db 100644 --- a/apps/tests/main-set/002-init/024-init-force.json +++ b/apps/tests/main-set/002-init/024-init-force.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "init --force", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/025-config-no-args.json b/apps/tests/main-set/003-config-A/025-config-no-args.json index 3d5506d6..8e1ed9b9 100644 --- a/apps/tests/main-set/003-config-A/025-config-no-args.json +++ b/apps/tests/main-set/003-config-A/025-config-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/026-config-list-local.json b/apps/tests/main-set/003-config-A/026-config-list-local.json index 6587c137..9d4b8040 100644 --- a/apps/tests/main-set/003-config-A/026-config-list-local.json +++ b/apps/tests/main-set/003-config-A/026-config-list-local.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --local --list", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/027-config-list-global.json b/apps/tests/main-set/003-config-A/027-config-list-global.json index f8125c56..6f699794 100644 --- a/apps/tests/main-set/003-config-A/027-config-list-global.json +++ b/apps/tests/main-set/003-config-A/027-config-list-global.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, @@ -11,7 +12,7 @@ "" ], "prepare": [ - "touch '$DATA/../copy/etc/covconfig' '[group]\nkey = system\n'", + "touch '$INST/../etc/covconfig' '[group]\nkey = system\n'", "touch '$TMP/home/.config/cov/config' '[group]\nkey = global\n'", "cd $TMP" ] diff --git a/apps/tests/main-set/003-config-A/028-config-list-system.json b/apps/tests/main-set/003-config-A/028-config-list-system.json index 051f3b67..3cad9f5f 100644 --- a/apps/tests/main-set/003-config-A/028-config-list-system.json +++ b/apps/tests/main-set/003-config-A/028-config-list-system.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, @@ -11,7 +12,7 @@ "" ], "prepare": [ - "touch '$DATA/../copy/etc/covconfig' '[group]\nkey = system\n'", + "touch '$INST/../etc/covconfig' '[group]\nkey = system\n'", "touch '$TMP/home/.config/cov/config' '[group]\nkey = global\n'", "cd $TMP" ] diff --git a/apps/tests/main-set/003-config-A/029-config-list-file.json b/apps/tests/main-set/003-config-A/029-config-list-file.json index 0ffa8c2d..21ef43fb 100644 --- a/apps/tests/main-set/003-config-A/029-config-list-file.json +++ b/apps/tests/main-set/003-config-A/029-config-list-file.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config -f '$TMP/some.file' --list", "expected": [ 0, diff --git a/apps/tests/main-set/004-config-B/030-config-list-any.json b/apps/tests/main-set/004-config-B/030-config-list-any.json index 986f9253..4a91637c 100644 --- a/apps/tests/main-set/004-config-B/030-config-list-any.json +++ b/apps/tests/main-set/004-config-B/030-config-list-any.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, @@ -21,7 +22,7 @@ "cd $TMP/repo.covdata", "git init --bare $TMP/repo.git", "cov init --git-dir $TMP/repo.git .", - "touch '$DATA/../copy/etc/covconfig' '[group]\nkey = system\n'", + "touch '$INST/../etc/covconfig' '[group]\nkey = system\n'", "touch '$TMP/home/.config/cov/config' '[group]\nkey = global\n'", "cd $TMP/repo.covdata", "cov config --local group.key local" diff --git a/apps/tests/main-set/004-config-B/031-config-list-after-get.json b/apps/tests/main-set/004-config-B/031-config-list-after-get.json index 8a1eed9c..1940fff7 100644 --- a/apps/tests/main-set/004-config-B/031-config-list-after-get.json +++ b/apps/tests/main-set/004-config-B/031-config-list-after-get.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/032-config-unset-after-list.json b/apps/tests/main-set/004-config-B/032-config-unset-after-list.json index b99f5183..df622918 100644 --- a/apps/tests/main-set/004-config-B/032-config-unset-after-list.json +++ b/apps/tests/main-set/004-config-B/032-config-unset-after-list.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json b/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json index 0bd70d7d..ff5e8347 100644 --- a/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json +++ b/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json b/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json index 1d7afb2e..dc8fc5fd 100644 --- a/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json +++ b/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json b/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json index dd87d7d4..d3d8ea16 100644 --- a/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json +++ b/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --local --list", "expected": [ 2, diff --git a/apps/tests/main-set/004-config-B/036-config-add-one-arg.json b/apps/tests/main-set/004-config-B/036-config-add-one-arg.json index 7e55b355..7b69d96e 100644 --- a/apps/tests/main-set/004-config-B/036-config-add-one-arg.json +++ b/apps/tests/main-set/004-config-B/036-config-add-one-arg.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --add group.key", "expected": [ 2, diff --git a/apps/tests/main-set/004-config-B/037-config-unset-too-many.json b/apps/tests/main-set/004-config-B/037-config-unset-too-many.json index 665bd853..d9d6aca4 100644 --- a/apps/tests/main-set/004-config-B/037-config-unset-too-many.json +++ b/apps/tests/main-set/004-config-B/037-config-unset-too-many.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --unset group.key value", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json index acf3ffd1..b6cb8007 100644 --- a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json +++ b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json @@ -1,11 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ 2, "", "cov config: error: entry is not unique due to being a multivar\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/039-config-set-but-include.json b/apps/tests/main-set/005-config-C/039-config-set-but-include.json index 530f6f0b..059baf8e 100644 --- a/apps/tests/main-set/005-config-C/039-config-set-but-include.json +++ b/apps/tests/main-set/005-config-C/039-config-set-but-include.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json index cf8cdbe1..143ce636 100644 --- a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json +++ b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json @@ -1,11 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --unset group.key", "expected": [ 2, "", "cov config: error: entry is not unique due to being a multivar\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json index e2be14b4..971a7dd2 100644 --- a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json +++ b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json @@ -1,11 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --unset group.other", "expected": [ 2, "", "cov config: error: could not find key 'group.other' to delete\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json index 7c0cf06a..e8e3f68b 100644 --- a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json +++ b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json @@ -1,11 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --unset group-other", "expected": [ 2, "", "cov config: error: invalid config item name 'group-other'\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/043-config-get.json b/apps/tests/main-set/005-config-C/043-config-get.json index 034c7ec4..d4c4c70a 100644 --- a/apps/tests/main-set/005-config-C/043-config-get.json +++ b/apps/tests/main-set/005-config-C/043-config-get.json @@ -1,11 +1,6 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config group.key", - "expected": [ - 0, - "value 2\n", - "" - ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "expected": [0, "value 2\n", ""], + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/044-config-get-all.json b/apps/tests/main-set/005-config-C/044-config-get-all.json index ce2f77e8..fb09f500 100644 --- a/apps/tests/main-set/005-config-C/044-config-get-all.json +++ b/apps/tests/main-set/005-config-C/044-config-get-all.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --get-all group.key", "expected": [ 0, @@ -8,7 +9,5 @@ ], "" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/main-set/005-config-C/045-config-add.json b/apps/tests/main-set/005-config-C/045-config-add.json index 315af9a1..6fabd3ff 100644 --- a/apps/tests/main-set/005-config-C/045-config-add.json +++ b/apps/tests/main-set/005-config-C/045-config-add.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --get-all group.key", "expected": [ 0, diff --git a/apps/tests/main-set/005-config-C/046-config-unset-all.json b/apps/tests/main-set/005-config-C/046-config-unset-all.json index 6b716c83..eeca0ad6 100644 --- a/apps/tests/main-set/005-config-C/046-config-unset-all.json +++ b/apps/tests/main-set/005-config-C/046-config-unset-all.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "config --file $TMP/config --list", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/047-module-help.json b/apps/tests/main-set/006-module-A/047-module-help.json index 7ca73419..994d7985 100644 --- a/apps/tests/main-set/006-module-A/047-module-help.json +++ b/apps/tests/main-set/006-module-A/047-module-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --help", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/048-module-build-and-print.json b/apps/tests/main-set/006-module-A/048-module-build-and-print.json index 9c8c19b3..ad900dd2 100644 --- a/apps/tests/main-set/006-module-A/048-module-build-and-print.json +++ b/apps/tests/main-set/006-module-A/048-module-build-and-print.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json b/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json index 618bce18..0076fe17 100644 --- a/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json +++ b/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "module --show-sep", - "expected": [ - 0, - " :: \n", - "" - ], + "expected": [0, " :: \n", ""], "prepare": [ "mkdirs $TMP/repo.git", "mkdirs $TMP/repo.covdata", diff --git a/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json b/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json index cdc1cbf9..915b752c 100644 --- a/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json +++ b/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json b/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json index 432f025a..ac20be96 100644 --- a/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json +++ b/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --remove-all \"doesn't matter\"", "expected": [ 2, diff --git a/apps/tests/main-set/006-module-A/052-module-add-duplicate.json b/apps/tests/main-set/006-module-A/052-module-add-duplicate.json index bd5e6010..9d6f3f05 100644 --- a/apps/tests/main-set/006-module-A/052-module-add-duplicate.json +++ b/apps/tests/main-set/006-module-A/052-module-add-duplicate.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --add module 'dir 1'", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json b/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json index 3eaac4ce..625276d7 100644 --- a/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json +++ b/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --remove some-name 'dir 1'", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json b/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json index 5f0112fd..ed085bfd 100644 --- a/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json +++ b/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module HEAD", "expected": [ 0, diff --git a/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json b/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json index 97a074f4..8a196a57 100644 --- a/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json +++ b/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "module --show-sep HEAD", - "expected": [ - 0, - "::\n", - "" - ], + "expected": [0, "::\n", ""], "prepare": [ "mkdirs $TMP/repo.covdata", "unpack $DATA/repo.covmodules.tar $TMP", diff --git a/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json b/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json index 26b13cdb..56b9451c 100644 --- a/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json +++ b/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module v1.0.0..HEAD", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json b/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json index 78f7bf53..653e5281 100644 --- a/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json +++ b/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module 2559ccfa6", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/058-module-no-git.json b/apps/tests/main-set/007-module-B/058-module-no-git.json index 7709fbe3..3d3fc081 100644 --- a/apps/tests/main-set/007-module-B/058-module-no-git.json +++ b/apps/tests/main-set/007-module-B/058-module-no-git.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/059-module-excl-show.json b/apps/tests/main-set/007-module-B/059-module-excl-show.json index ae909b47..dbf77386 100644 --- a/apps/tests/main-set/007-module-B/059-module-excl-show.json +++ b/apps/tests/main-set/007-module-B/059-module-excl-show.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module HEAD --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json b/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json index 42e6abca..b34e7a3e 100644 --- a/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json +++ b/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --show-sep --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/061-module-too-many-refs.json b/apps/tests/main-set/007-module-B/061-module-too-many-refs.json index f38a11d7..8f5d6300 100644 --- a/apps/tests/main-set/007-module-B/061-module-too-many-refs.json +++ b/apps/tests/main-set/007-module-B/061-module-too-many-refs.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module HEAD ANOTHER_HEAD main v1.0.0", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/062-module-too-little-args.json b/apps/tests/main-set/007-module-B/062-module-too-little-args.json index bbd86d9c..0a4abdc4 100644 --- a/apps/tests/main-set/007-module-B/062-module-too-little-args.json +++ b/apps/tests/main-set/007-module-B/062-module-too-little-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --add module", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/062-module-too-many-args.json b/apps/tests/main-set/007-module-B/062-module-too-many-args.json index 7c04b542..44d13a91 100644 --- a/apps/tests/main-set/007-module-B/062-module-too-many-args.json +++ b/apps/tests/main-set/007-module-B/062-module-too-many-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --remove-all module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/063-module-no-covmodule.json b/apps/tests/main-set/007-module-B/063-module-no-covmodule.json index 119ab8db..ead98881 100644 --- a/apps/tests/main-set/007-module-B/063-module-no-covmodule.json +++ b/apps/tests/main-set/007-module-B/063-module-no-covmodule.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "module", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "git init $TMP/repo", "mkdirs $TMP/repo/.covmodules/nope", diff --git a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json index 7fe219c1..303d2b7d 100644 --- a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json +++ b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "module --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json b/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json index ba3a69f5..b210c73d 100644 --- a/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json +++ b/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "module nonexistent-ref", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/repo.git.tar $TMP", "cd $TMP/repo.git" diff --git a/apps/tests/main-set/008-report-A/066-report-no-args.json b/apps/tests/main-set/008-report-A/066-report-no-args.json index 948b301f..e300f5f2 100644 --- a/apps/tests/main-set/008-report-A/066-report-no-args.json +++ b/apps/tests/main-set/008-report-A/066-report-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/067-report-help.json b/apps/tests/main-set/008-report-A/067-report-help.json index 25f0b3b2..43a0f0e9 100644 --- a/apps/tests/main-set/008-report-A/067-report-help.json +++ b/apps/tests/main-set/008-report-A/067-report-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report -h", "expected": [ 0, diff --git a/apps/tests/main-set/008-report-A/068-report-no-cov.json b/apps/tests/main-set/008-report-A/068-report-no-cov.json index ac2f529d..41efd184 100644 --- a/apps/tests/main-set/008-report-A/068-report-no-cov.json +++ b/apps/tests/main-set/008-report-A/068-report-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/basic-coverage.json", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/069-report-no-commit.json b/apps/tests/main-set/008-report-A/069-report-no-commit.json index 2a5769ae..f3998807 100644 --- a/apps/tests/main-set/008-report-A/069-report-no-commit.json +++ b/apps/tests/main-set/008-report-A/069-report-no-commit.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/basic-coverage.json", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/070-report-failing-filter.json b/apps/tests/main-set/008-report-A/070-report-failing-filter.json index 6f57db1d..906df327 100644 --- a/apps/tests/main-set/008-report-A/070-report-failing-filter.json +++ b/apps/tests/main-set/008-report-A/070-report-failing-filter.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/basic-coverage.json -f echo-to-stderr", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/071-report-no-filter.json b/apps/tests/main-set/008-report-A/071-report-no-filter.json index 221fadd9..c7b9f9a3 100644 --- a/apps/tests/main-set/008-report-A/071-report-no-filter.json +++ b/apps/tests/main-set/008-report-A/071-report-no-filter.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/basic-coverage.json -f no-filter", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/072-report-not-the-json.json b/apps/tests/main-set/008-report-A/072-report-not-the-json.json index 6d7cbd49..59180b65 100644 --- a/apps/tests/main-set/008-report-A/072-report-not-the-json.json +++ b/apps/tests/main-set/008-report-A/072-report-not-the-json.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/no-git-coverage.json", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index 4607645b..8d171f92 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/no-git-coverage.json -f echo-to-stdout", "expected": [ 2, diff --git a/apps/tests/main-set/009-report-B/074-report-no-file.json b/apps/tests/main-set/009-report-B/074-report-no-file.json index 37de75b3..c412a7f7 100644 --- a/apps/tests/main-set/009-report-B/074-report-no-file.json +++ b/apps/tests/main-set/009-report-B/074-report-no-file.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/basic-coverage.json -f replace-head", "expected": [ 1, diff --git a/apps/tests/main-set/009-report-B/075-report-empty.json b/apps/tests/main-set/009-report-B/075-report-empty.json index 259511a7..e664ae35 100644 --- a/apps/tests/main-set/009-report-B/075-report-empty.json +++ b/apps/tests/main-set/009-report-B/075-report-empty.json @@ -1,15 +1,12 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/empty-coverage.json -f replace-head", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m second", " 0 files, \u001b[31m 0%\u001b[m (0/0)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m384512442@main\u001b[m", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m\n" ], "" diff --git a/apps/tests/main-set/009-report-B/076-report-one-file.json b/apps/tests/main-set/009-report-B/076-report-one-file.json index 20baee88..40297e22 100644 --- a/apps/tests/main-set/009-report-B/076-report-one-file.json +++ b/apps/tests/main-set/009-report-B/076-report-one-file.json @@ -1,15 +1,12 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m second", " one file, \u001b[31m 67%\u001b[m (2/3, -1)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m384512442@main\u001b[m", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 67%\u001b[m\n" ], "[ADD] src/main.cc\n" diff --git a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json index 7dbe9f67..cf4df439 100644 --- a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json +++ b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json @@ -1,8 +1,6 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report --amend", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second" - }, "expected": [ 2, "", diff --git a/apps/tests/main-set/009-report-B/078-D-report-with-props.json b/apps/tests/main-set/009-report-B/078-D-report-with-props.json index 5f967441..b3740d36 100644 --- a/apps/tests/main-set/009-report-B/078-D-report-with-props.json +++ b/apps/tests/main-set/009-report-B/078-D-report-with-props.json @@ -1,15 +1,12 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report -pos=qnx -pdebug=false -pcompiler=javac", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m second", " one file, \u001b[31m 67%\u001b[m (2/3, -1)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m384512442@main\u001b[m", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 67%\u001b[m\u001b[2;33m (\u001b[m\u001b[33mjavac\u001b[m\u001b[2;33m, debug: \u001b[m\u001b[34moff\u001b[m\u001b[2;33m, \u001b[m\u001b[33mqnx\u001b[m\u001b[2;33m)\u001b[m\n" ], "[ADD] src/main.cc\n" diff --git a/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json b/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json index 87efe6ab..f2c3ba21 100644 --- a/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json +++ b/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json @@ -1,15 +1,12 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report --amend", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m second", " one file, \u001b[31m 67%\u001b[m (2/3, -1)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m384512442@main\u001b[m", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 67%\u001b[m\n" ], "[ADD] src/main.cc\n" diff --git a/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json b/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json index 1b5dbfae..8edc3333 100644 --- a/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json +++ b/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json b/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json index 64243de9..321ed12e 100644 --- a/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json +++ b/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage-same-stats-diff-visits.json -f create-report", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/079-report-with-parent.json b/apps/tests/main-set/009-report-B/079-report-with-parent.json index 60d1a8b2..65d6be5e 100644 --- a/apps/tests/main-set/009-report-B/079-report-with-parent.json +++ b/apps/tests/main-set/009-report-B/079-report-with-parent.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f create-report", "patches": { "\u001b\\[0;49;90m\\[master [0-9a-fA-F]+\\] reported files\u001b\\[m": "\u001b[0;49;90m[master $COMMIT] reported files\u001b[m", diff --git a/apps/tests/main-set/009-report-B/080-report-on-detached.json b/apps/tests/main-set/009-report-B/080-report-on-detached.json index 61624cfb..c8432e39 100644 --- a/apps/tests/main-set/009-report-B/080-report-on-detached.json +++ b/apps/tests/main-set/009-report-B/080-report-on-detached.json @@ -1,12 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f create-report", - "patches": { - "\u001b\\[0;49;90m\\[master [0-9a-fA-F]+\\] reported files\u001b\\[m": "\u001b[0;49;90m[master $COMMIT] reported files\u001b[m", - "\u001b\\[31m\\[detached HEAD [0-9a-fA-F]+\\]\u001b\\[m reported files": "\u001b[31m[detached HEAD $REPORT]\u001b[m reported files", - " \u001b\\[2;37mbased on\u001b\\[m \u001b\\[2;33m[0-9a-fA-F]+@main\u001b\\[m": " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", - " parent [0-9a-fA-F]+": " parent $PARENT", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, + "patches": {"\u001b\\[0;49;90m\\[master [0-9a-fA-F]+\\] (.+)": "\u001b[0;49;90m[master $COMMIT] \\1"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json b/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json index 4e515983..98f77f9d 100644 --- a/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json +++ b/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f hash-bang-less", "expected": [ 1, diff --git a/apps/tests/main-set/010-log/082-log-no-args.json b/apps/tests/main-set/010-log/082-log-no-args.json index a67211ed..cc0cc37f 100644 --- a/apps/tests/main-set/010-log/082-log-no-args.json +++ b/apps/tests/main-set/010-log/082-log-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log", "expected": [ 2, @@ -8,7 +9,5 @@ "cov log: error: Cannot find a Cov repository in $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/010-log/083-log-no-args-inited.json b/apps/tests/main-set/010-log/083-log-no-args-inited.json index 802f2fce..e4f24a59 100644 --- a/apps/tests/main-set/010-log/083-log-no-args-inited.json +++ b/apps/tests/main-set/010-log/083-log-no-args-inited.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/084-log-no-args-Dmain.json b/apps/tests/main-set/010-log/084-log-no-args-Dmain.json index 4bb87ac0..23946ac7 100644 --- a/apps/tests/main-set/010-log/084-log-no-args-Dmain.json +++ b/apps/tests/main-set/010-log/084-log-no-args-Dmain.json @@ -1,11 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "log", - "check": { - "stderr": "begin" - }, - "patches": { - "Added: .*": "Added: $DATE" - }, + "check": {"stderr": "begin"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/085-log-G..K-oneline.json b/apps/tests/main-set/010-log/085-log-G..K-oneline.json index 51a8fd61..abbeaace 100644 --- a/apps/tests/main-set/010-log/085-log-G..K-oneline.json +++ b/apps/tests/main-set/010-log/085-log-G..K-oneline.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log --oneline G..K", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json b/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json index eea02e7a..0e16412c 100644 --- a/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json +++ b/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log --format=raw --decorate=short cov-separate", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json b/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json index c3595a0c..d6365699 100644 --- a/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json +++ b/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json @@ -1,12 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "log --format=fuller --decorate=short feat/cov-3", - "check": { - "stderr": "begin" - }, - "patches": { - "CommitDate: .*": "CommitDate: $DATE", - "Added: .*": "Added: $DATE" - }, + "check": {"stderr": "begin"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json b/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json index a823657d..4d2e41cc 100644 --- a/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json +++ b/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log --oneline --color always --decorate short G..K", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json b/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json index 182483ea..17f5cc81 100644 --- a/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json +++ b/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json @@ -1,8 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "log '--format=pretty:%C(yellow)%hR%Creset (%s, %rs) %C(red)%hG@%rD%Creset' --color always --decorate short Q..M", - "check": { - "stderr": "begin" - }, + "check": {"stderr": "begin"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json b/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json index e888754b..763aca5f 100644 --- a/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json +++ b/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json @@ -1,8 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "log '--format=%C(yellow)%hR%Creset (%s, %rs) %C(red)%hG@%rD%Creset' --color always --decorate short Q..M", - "check": { - "stderr": "begin" - }, + "check": {"stderr": "begin"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json b/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json index fd759569..8a9b8a27 100644 --- a/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json +++ b/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json @@ -1,8 +1,6 @@ { + "$schema": "../../runner-schema.json", "args": "log '--format= - %mD(4)' --color always --decorate short", - "patches": { - "Added: .*": "Added: $DATE" - }, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json b/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json index 3e48dc4e..1af3065a 100644 --- a/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json +++ b/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json @@ -1,8 +1,6 @@ { + "$schema": "../../runner-schema.json", "args": "log --format=unknown --color always --decorate short Q..M", - "patches": { - "Added: .*": "Added: $DATE" - }, "expected": [ 0, [ diff --git a/apps/tests/main-set/010-log/092-log-help.json b/apps/tests/main-set/010-log/092-log-help.json index e995f69a..688ccf68 100644 --- a/apps/tests/main-set/010-log/092-log-help.json +++ b/apps/tests/main-set/010-log/092-log-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log --help", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/093-log-two-HEADs.json b/apps/tests/main-set/010-log/093-log-two-HEADs.json index 2d0744c8..1575f400 100644 --- a/apps/tests/main-set/010-log/093-log-two-HEADs.json +++ b/apps/tests/main-set/010-log/093-log-two-HEADs.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log ..", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/094-log-123456789.json b/apps/tests/main-set/010-log/094-log-123456789.json index aab86d49..091e5ef6 100644 --- a/apps/tests/main-set/010-log/094-log-123456789.json +++ b/apps/tests/main-set/010-log/094-log-123456789.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log 123456789", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/095-log-try-non-report.json b/apps/tests/main-set/010-log/095-log-try-non-report.json index e152f2c3..786f3ff9 100644 --- a/apps/tests/main-set/010-log/095-log-try-non-report.json +++ b/apps/tests/main-set/010-log/095-log-try-non-report.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log $BUILD --prop-names --decorate short", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/095-branch-no-args.json b/apps/tests/main-set/011-refs/095-branch-no-args.json index 372174ac..b7dfd9ca 100644 --- a/apps/tests/main-set/011-refs/095-branch-no-args.json +++ b/apps/tests/main-set/011-refs/095-branch-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch", "expected": [ 2, @@ -8,7 +9,5 @@ "cov branch: error: Cannot find a Cov repository in $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/011-refs/096-tag-no-args.json b/apps/tests/main-set/011-refs/096-tag-no-args.json index 7f5d0795..3ddd669a 100644 --- a/apps/tests/main-set/011-refs/096-tag-no-args.json +++ b/apps/tests/main-set/011-refs/096-tag-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag", "expected": [ 2, @@ -8,7 +9,5 @@ "cov tag: error: Cannot find a Cov repository in $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/011-refs/097-branch-help.json b/apps/tests/main-set/011-refs/097-branch-help.json index 587994e2..6bc429c0 100644 --- a/apps/tests/main-set/011-refs/097-branch-help.json +++ b/apps/tests/main-set/011-refs/097-branch-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch --help", "expected": [ 0, @@ -20,7 +21,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/011-refs/098-tag-help.json b/apps/tests/main-set/011-refs/098-tag-help.json index 10da3ac6..9c637b4f 100644 --- a/apps/tests/main-set/011-refs/098-tag-help.json +++ b/apps/tests/main-set/011-refs/098-tag-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag --help", "expected": [ 0, @@ -17,7 +18,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/011-refs/099-branch-list.json b/apps/tests/main-set/011-refs/099-branch-list.json index c9ffe385..016833d5 100644 --- a/apps/tests/main-set/011-refs/099-branch-list.json +++ b/apps/tests/main-set/011-refs/099-branch-list.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/100-branch-list-color.json b/apps/tests/main-set/011-refs/100-branch-list-color.json index 3ec24a20..284e71dc 100644 --- a/apps/tests/main-set/011-refs/100-branch-list-color.json +++ b/apps/tests/main-set/011-refs/100-branch-list-color.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch --color=always", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/101-tag-list.json b/apps/tests/main-set/011-refs/101-tag-list.json index a569357d..5c35231d 100644 --- a/apps/tests/main-set/011-refs/101-tag-list.json +++ b/apps/tests/main-set/011-refs/101-tag-list.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/102-branch-current.json b/apps/tests/main-set/011-refs/102-branch-current.json index d2bb46b9..e1290279 100644 --- a/apps/tests/main-set/011-refs/102-branch-current.json +++ b/apps/tests/main-set/011-refs/102-branch-current.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "branch --show-current", - "expected": [ - 0, - "main\n", - "" - ], + "expected": [0, "main\n", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/103-branch-only-feat.json b/apps/tests/main-set/011-refs/103-branch-only-feat.json index 0873cb1b..54f098f1 100644 --- a/apps/tests/main-set/011-refs/103-branch-only-feat.json +++ b/apps/tests/main-set/011-refs/103-branch-only-feat.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch -l feat/cov-*", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/104-branch-force-delete.json b/apps/tests/main-set/011-refs/104-branch-force-delete.json index f0fab12c..857ee429 100644 --- a/apps/tests/main-set/011-refs/104-branch-force-delete.json +++ b/apps/tests/main-set/011-refs/104-branch-force-delete.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch --delete main --force", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/105-branch-two-commands.json b/apps/tests/main-set/011-refs/105-branch-two-commands.json index 1b56a8ce..2483cc2f 100644 --- a/apps/tests/main-set/011-refs/105-branch-two-commands.json +++ b/apps/tests/main-set/011-refs/105-branch-two-commands.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch --show-current -l feat/cov-*", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json b/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json index 4e6bfc43..20620f9c 100644 --- a/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json +++ b/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch feat/cov-4 G~2", "post": "log --oneline -n1", "expected": [ diff --git a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json index 22d9cc20..110b9527 100644 --- a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json +++ b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch feat/cov-4 non-existing", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/106-branch-create.json b/apps/tests/main-set/011-refs/106-branch-create.json index 2c4f59f1..4a713a73 100644 --- a/apps/tests/main-set/011-refs/106-branch-create.json +++ b/apps/tests/main-set/011-refs/106-branch-create.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "branch feat/cov-4", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/107-branch-create-forced.json b/apps/tests/main-set/011-refs/107-branch-create-forced.json index fd1b6747..6a6b1ede 100644 --- a/apps/tests/main-set/011-refs/107-branch-create-forced.json +++ b/apps/tests/main-set/011-refs/107-branch-create-forced.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "branch cov-separate --force", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/108-branch-create-existing.json b/apps/tests/main-set/011-refs/108-branch-create-existing.json index 2f23258e..adce3f3a 100644 --- a/apps/tests/main-set/011-refs/108-branch-create-existing.json +++ b/apps/tests/main-set/011-refs/108-branch-create-existing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch cov-separate", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json b/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json index 4f4189f9..09474296 100644 --- a/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json +++ b/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch branch-1 branch-2 branch-3", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/110-branch-create-unborn.json b/apps/tests/main-set/011-refs/110-branch-create-unborn.json index f0f59442..f06bb7f8 100644 --- a/apps/tests/main-set/011-refs/110-branch-create-unborn.json +++ b/apps/tests/main-set/011-refs/110-branch-create-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch name", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/111-branch-delete-nothing.json b/apps/tests/main-set/011-refs/111-branch-delete-nothing.json index 00fb3e0c..4047b714 100644 --- a/apps/tests/main-set/011-refs/111-branch-delete-nothing.json +++ b/apps/tests/main-set/011-refs/111-branch-delete-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch --delete", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/112-branch-delete-main.json b/apps/tests/main-set/011-refs/112-branch-delete-main.json index df54e941..d3242f01 100644 --- a/apps/tests/main-set/011-refs/112-branch-delete-main.json +++ b/apps/tests/main-set/011-refs/112-branch-delete-main.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch -d main", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/113-branch-delete-other.json b/apps/tests/main-set/011-refs/113-branch-delete-other.json index 5d51ed42..e2564874 100644 --- a/apps/tests/main-set/011-refs/113-branch-delete-other.json +++ b/apps/tests/main-set/011-refs/113-branch-delete-other.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "branch -d feat/cov-2", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json index 8664b64a..9da7b863 100644 --- a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch -d feat/cov-22", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/115-tag-create.json b/apps/tests/main-set/011-refs/115-tag-create.json index b6f27fb0..98635025 100644 --- a/apps/tests/main-set/011-refs/115-tag-create.json +++ b/apps/tests/main-set/011-refs/115-tag-create.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "tag feat/cov-4", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/116-tag-create-forced.json b/apps/tests/main-set/011-refs/116-tag-create-forced.json index f6207d82..5073490c 100644 --- a/apps/tests/main-set/011-refs/116-tag-create-forced.json +++ b/apps/tests/main-set/011-refs/116-tag-create-forced.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "tag H --force", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/117-tag-create-existing.json b/apps/tests/main-set/011-refs/117-tag-create-existing.json index b507edad..ffd034ad 100644 --- a/apps/tests/main-set/011-refs/117-tag-create-existing.json +++ b/apps/tests/main-set/011-refs/117-tag-create-existing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag H", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json b/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json index 8422f095..6701938f 100644 --- a/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json +++ b/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag tag-1 tag-2 tag-3", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/119-tag-create-unborn.json b/apps/tests/main-set/011-refs/119-tag-create-unborn.json index b607e588..1640f5a7 100644 --- a/apps/tests/main-set/011-refs/119-tag-create-unborn.json +++ b/apps/tests/main-set/011-refs/119-tag-create-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag name", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/120-tag-delete-tag.json b/apps/tests/main-set/011-refs/120-tag-delete-tag.json index a6d69073..3a10aa0e 100644 --- a/apps/tests/main-set/011-refs/120-tag-delete-tag.json +++ b/apps/tests/main-set/011-refs/120-tag-delete-tag.json @@ -1,10 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "tag -d H", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "unpack $DATA/revparse.tar $TMP", "cd $TMP/revparse" diff --git a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json index 2cb3d9ea..15705dc8 100644 --- a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "tag -d nonexisting", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/122-branch-create-invalid.json b/apps/tests/main-set/011-refs/122-branch-create-invalid.json index dd807f5f..9ebaa508 100644 --- a/apps/tests/main-set/011-refs/122-branch-create-invalid.json +++ b/apps/tests/main-set/011-refs/122-branch-create-invalid.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch \"bad:name\"", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/123-tag-create-invalid.json b/apps/tests/main-set/011-refs/123-tag-create-invalid.json index 945e9428..bda4e507 100644 --- a/apps/tests/main-set/011-refs/123-tag-create-invalid.json +++ b/apps/tests/main-set/011-refs/123-tag-create-invalid.json @@ -1,5 +1,6 @@ { - "args": "tag \"bad:name\"", + "$schema": "../../runner-schema.json", + "args": "tag bad\\:name", "expected": [ 2, "", diff --git a/apps/tests/main-set/011-refs/124-branch-list-detached.json b/apps/tests/main-set/011-refs/124-branch-list-detached.json index d36502b5..6cca0747 100644 --- a/apps/tests/main-set/011-refs/124-branch-list-detached.json +++ b/apps/tests/main-set/011-refs/124-branch-list-detached.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "branch", "expected": [ 0, diff --git a/apps/tests/main-set/012-checkout/125-checkout-no-args.json b/apps/tests/main-set/012-checkout/125-checkout-no-args.json index 6f370426..54c27e02 100644 --- a/apps/tests/main-set/012-checkout/125-checkout-no-args.json +++ b/apps/tests/main-set/012-checkout/125-checkout-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout", "expected": [ 2, @@ -8,7 +9,5 @@ "cov checkout: error: at least one argument is needed\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/012-checkout/126-checkout-no-cov.json b/apps/tests/main-set/012-checkout/126-checkout-no-cov.json index 905fa7e1..ec503e4b 100644 --- a/apps/tests/main-set/012-checkout/126-checkout-no-cov.json +++ b/apps/tests/main-set/012-checkout/126-checkout-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout main", "expected": [ 2, @@ -8,7 +9,5 @@ "cov checkout: error: Cannot find a Cov repository in $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/012-checkout/127-checkout-help.json b/apps/tests/main-set/012-checkout/127-checkout-help.json index f0df4acd..3df821dd 100644 --- a/apps/tests/main-set/012-checkout/127-checkout-help.json +++ b/apps/tests/main-set/012-checkout/127-checkout-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -h", "expected": [ 0, @@ -21,7 +22,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/012-checkout/128-checkout-two-names.json b/apps/tests/main-set/012-checkout/128-checkout-two-names.json index 1e8bee2d..6018ea38 100644 --- a/apps/tests/main-set/012-checkout/128-checkout-two-names.json +++ b/apps/tests/main-set/012-checkout/128-checkout-two-names.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout two names", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json b/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json index e8eca639..114b5eef 100644 --- a/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json +++ b/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -b result starting-point something else", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json b/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json index dd45c94a..45bb0225 100644 --- a/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json +++ b/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -b", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/131-checkout-two-commands.json b/apps/tests/main-set/012-checkout/131-checkout-two-commands.json index 6c13a08c..3bf04359 100644 --- a/apps/tests/main-set/012-checkout/131-checkout-two-commands.json +++ b/apps/tests/main-set/012-checkout/131-checkout-two-commands.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -b --orphan", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/132-checkout-branch.json b/apps/tests/main-set/012-checkout/132-checkout-branch.json index 90bdd5fa..cace2059 100644 --- a/apps/tests/main-set/012-checkout/132-checkout-branch.json +++ b/apps/tests/main-set/012-checkout/132-checkout-branch.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -b branch-name", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/133-checkout-orphan.json b/apps/tests/main-set/012-checkout/133-checkout-orphan.json index ac401621..9a806c6f 100644 --- a/apps/tests/main-set/012-checkout/133-checkout-orphan.json +++ b/apps/tests/main-set/012-checkout/133-checkout-orphan.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout --orphan branch-name", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json index add9350d..ba26330f 100644 --- a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json +++ b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout --orphan main", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json index 9e935956..1211ad67 100644 --- a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json +++ b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout --orphan 'invalid:spec'", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/136-checkout-existing.json b/apps/tests/main-set/012-checkout/136-checkout-existing.json index 4dfd1ff6..4de740b8 100644 --- a/apps/tests/main-set/012-checkout/136-checkout-existing.json +++ b/apps/tests/main-set/012-checkout/136-checkout-existing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout feat/cov-3", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/137-checkout-tag.json b/apps/tests/main-set/012-checkout/137-checkout-tag.json index 97ee05b7..f1382211 100644 --- a/apps/tests/main-set/012-checkout/137-checkout-tag.json +++ b/apps/tests/main-set/012-checkout/137-checkout-tag.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout G", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json b/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json index 7d32e838..59d171f7 100644 --- a/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json +++ b/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout --detach", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/139-checkout-start-point.json b/apps/tests/main-set/012-checkout/139-checkout-start-point.json index 62b1c57f..30ed6aa2 100644 --- a/apps/tests/main-set/012-checkout/139-checkout-start-point.json +++ b/apps/tests/main-set/012-checkout/139-checkout-start-point.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "checkout -b branch-name G~", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/013-reset/140-reset-help.json b/apps/tests/main-set/013-reset/140-reset-help.json index d86b8c78..54a66eb7 100644 --- a/apps/tests/main-set/013-reset/140-reset-help.json +++ b/apps/tests/main-set/013-reset/140-reset-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "reset -h", "expected": [ 0, @@ -13,7 +14,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/013-reset/141-reset-no-args.json b/apps/tests/main-set/013-reset/141-reset-no-args.json index 2b838b42..86e3f486 100644 --- a/apps/tests/main-set/013-reset/141-reset-no-args.json +++ b/apps/tests/main-set/013-reset/141-reset-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "reset", "expected": [ 2, @@ -10,6 +11,7 @@ ], "prepare": [ "cd '$TMP'", + "git init", "cov init" ] } diff --git a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json index 302a79c3..374cd333 100644 --- a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json +++ b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "reset HEAD", "expected": [ 2, diff --git a/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json b/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json index 3c9a5be3..b9461a44 100644 --- a/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json +++ b/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json @@ -1,14 +1,15 @@ { + "$schema": "../../runner-schema.json", "args": "reset F", "expected": [ 0, [ "Tip of 'main' branch now points to ebadfd936a9b1a7822bbe35de47122b879fa48bb", - "\u001b[31m[main ebadfd936]\u001b[m Commit F", + "\u001b[31m[main $REPORT]\u001b[m Commit F", " 0 files, \u001b[31m 0%\u001b[m (0/0)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m366f0b00e@main\u001b[m", - " parent 3dda7ce58", - " \u001b[2;37mcontains e7a2b8532:\u001b[m \u001b[31m 0%\u001b[m\n" + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m\n" ], "" ], diff --git a/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json b/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json index cb27a564..59466c79 100644 --- a/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json +++ b/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json @@ -1,14 +1,15 @@ { + "$schema": "../../runner-schema.json", "args": "reset F", "expected": [ 0, [ "Detached HEAD now points to ebadfd936a9b1a7822bbe35de47122b879fa48bb", - "\u001b[31m[detached HEAD ebadfd936]\u001b[m Commit F", + "\u001b[31m[detached HEAD $REPORT]\u001b[m Commit F", " 0 files, \u001b[31m 0%\u001b[m (0/0)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m366f0b00e@main\u001b[m", - " parent 3dda7ce58", - " \u001b[2;37mcontains e7a2b8532:\u001b[m \u001b[31m 0%\u001b[m\n" + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", + " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m\n" ], "" ], diff --git a/apps/tests/main-set/014-show/145-show-help.json b/apps/tests/main-set/014-show/145-show-help.json index 83f28660..70d1e7b3 100644 --- a/apps/tests/main-set/014-show/145-show-help.json +++ b/apps/tests/main-set/014-show/145-show-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show -h", "expected": [ 0, @@ -21,7 +22,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/014-show/146-show-no-args-unborn.json b/apps/tests/main-set/014-show/146-show-no-args-unborn.json index ba04e475..2ae4af76 100644 --- a/apps/tests/main-set/014-show/146-show-no-args-unborn.json +++ b/apps/tests/main-set/014-show/146-show-no-args-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show", "expected": [ 2, diff --git a/apps/tests/main-set/014-show/147-show-no-args.json b/apps/tests/main-set/014-show/147-show-no-args.json index 4173d870..77b06a0f 100644 --- a/apps/tests/main-set/014-show/147-show-no-args.json +++ b/apps/tests/main-set/014-show/147-show-no-args.json @@ -1,9 +1,9 @@ { + "$schema": "../../runner-schema.json", "args": "show", "patches": { "report [0-9a-f]{40}": "report $OID", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -14,7 +14,7 @@ "GitBranch: main", "Coverage: [ 67%] 2/3 (fail)", "Author: Johnny Appleseeed ", - "Added: $NOW", + "Added: $DATE", "", " second", "", diff --git a/apps/tests/main-set/014-show/148-show-no-args-module.json b/apps/tests/main-set/014-show/148-show-no-args-module.json index 2dfaf1b2..9be4b5bd 100644 --- a/apps/tests/main-set/014-show/148-show-no-args-module.json +++ b/apps/tests/main-set/014-show/148-show-no-args-module.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show --color=always", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -15,7 +15,7 @@ "GitBranch: main", "Coverage: [ 86%] \u001b[2;37m6/7\u001b[m \u001b[2;33m(incomplete)\u001b[m", "Author: Johnny Appleseed ", - "Added: $NOW", + "Added: $DATE", "", " reported files", "", diff --git a/apps/tests/main-set/014-show/149-show-directory.json b/apps/tests/main-set/014-show/149-show-directory.json index 9814f661..3dae2255 100644 --- a/apps/tests/main-set/014-show/149-show-directory.json +++ b/apps/tests/main-set/014-show/149-show-directory.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-A-show-file.json b/apps/tests/main-set/014-show/150-A-show-file.json index 2c881744..e9d4d01a 100644 --- a/apps/tests/main-set/014-show/150-A-show-file.json +++ b/apps/tests/main-set/014-show/150-A-show-file.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src/main.cc", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-B-show-file-color.json b/apps/tests/main-set/014-show/150-B-show-file-color.json index 359ab8bd..5e53f17b 100644 --- a/apps/tests/main-set/014-show/150-B-show-file-color.json +++ b/apps/tests/main-set/014-show/150-B-show-file-color.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src/main.cc --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json b/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json index 24300efe..6f52cb47 100644 --- a/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json +++ b/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src/main.cc --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/151-show-module.json b/apps/tests/main-set/014-show/151-show-module.json index 3b7365f0..d2e59e05 100644 --- a/apps/tests/main-set/014-show/151-show-module.json +++ b/apps/tests/main-set/014-show/151-show-module.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show -m MAIN", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/152-show-range.json b/apps/tests/main-set/014-show/152-show-range.json index 52763cf9..8b1300ab 100644 --- a/apps/tests/main-set/014-show/152-show-range.json +++ b/apps/tests/main-set/014-show/152-show-range.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show then..", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -15,7 +15,7 @@ "GitBranch: main", "Coverage: [ 86%] 6/7 (incomplete)", "Author: Johnny Appleseed ", - "Added: $NOW", + "Added: $DATE", "", " reported files", "", diff --git a/apps/tests/main-set/014-show/153-show-not-a-covmodule.json b/apps/tests/main-set/014-show/153-show-not-a-covmodule.json index 7ca8e6e7..582b8ceb 100644 --- a/apps/tests/main-set/014-show/153-show-not-a-covmodule.json +++ b/apps/tests/main-set/014-show/153-show-not-a-covmodule.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -15,7 +15,7 @@ "GitBranch: main", "Coverage: [ 86%] 6/7 (incomplete)", "Author: Johnny Appleseed ", - "Added: $NOW", + "Added: $DATE", "", " reported files", "", diff --git a/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json b/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json index 00dca68f..661419d7 100644 --- a/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json +++ b/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show same..sies", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -15,7 +15,7 @@ "GitBranch: main", "Coverage: [ 86%] 6/7 (incomplete)", "Author: Johnny Appleseed ", - "Added: $NOW", + "Added: $DATE", "", " reported files", "", diff --git a/apps/tests/main-set/014-show/155-show-module-props.json b/apps/tests/main-set/014-show/155-show-module-props.json index 9111ec0d..abc0c12d 100644 --- a/apps/tests/main-set/014-show/155-show-module-props.json +++ b/apps/tests/main-set/014-show/155-show-module-props.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show -m MAIN", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/156-show-module-props-colors.json b/apps/tests/main-set/014-show/156-show-module-props-colors.json index 5f58225d..891ab6e8 100644 --- a/apps/tests/main-set/014-show/156-show-module-props-colors.json +++ b/apps/tests/main-set/014-show/156-show-module-props-colors.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show -m MAIN --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json b/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json index 4f0c8ef3..3ac85c98 100644 --- a/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json +++ b/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show -m MAIN --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/158-show-functions.json b/apps/tests/main-set/014-show/158-show-functions.json index 9d356bf1..95c6a177 100644 --- a/apps/tests/main-set/014-show/158-show-functions.json +++ b/apps/tests/main-set/014-show/158-show-functions.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src/main.cc --color always", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, diff --git a/apps/tests/main-set/014-show/159-show-functions-log.json b/apps/tests/main-set/014-show/159-show-functions-log.json index 567b06a6..2509a993 100644 --- a/apps/tests/main-set/014-show/159-show-functions-log.json +++ b/apps/tests/main-set/014-show/159-show-functions-log.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show --color always", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, @@ -16,7 +16,7 @@ "Coverage: [ 67%] \u001b[2;37m6/9\u001b[m \u001b[2;31m(fail)\u001b[m", "Functions: [ 50%] \u001b[2;37m1/2\u001b[m \u001b[2;31m(fail)\u001b[m", "Author: Johnny Appleseed ", - "Added: $NOW", + "Added: $DATE", "", " function coverage (1)", "", diff --git a/apps/tests/main-set/014-show/160-show-functions-log.json b/apps/tests/main-set/014-show/160-show-functions-log.json index 5b337e5a..e811ccf8 100644 --- a/apps/tests/main-set/014-show/160-show-functions-log.json +++ b/apps/tests/main-set/014-show/160-show-functions-log.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show --color always HEAD:src", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, diff --git a/apps/tests/main-set/014-show/161-show-no-chunks.json b/apps/tests/main-set/014-show/161-show-no-chunks.json index c66d53b8..0732fb0f 100644 --- a/apps/tests/main-set/014-show/161-show-no-chunks.json +++ b/apps/tests/main-set/014-show/161-show-no-chunks.json @@ -1,10 +1,10 @@ { + "$schema": "../../runner-schema.json", "args": "show HEAD:src/main.cc", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", "commit [0-9a-f]{40}": "commit $COMMIT_HASH", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, diff --git a/apps/tests/main-set/014-show/162-show-module-props-indented.json b/apps/tests/main-set/014-show/162-show-module-props-indented.json index 94f09e24..b5bd6e85 100644 --- a/apps/tests/main-set/014-show/162-show-module-props-indented.json +++ b/apps/tests/main-set/014-show/162-show-module-props-indented.json @@ -1,15 +1,13 @@ { + "$schema": "../../runner-schema.json", "args": "show $BUILD --format=fuller --prop-names --decorate short", - "patches": { - "build [0-9a-f]{40}": "build $BUILD_HASH", - "Added: .*": "Added: $NOW" - }, + "patches": {"build [0-9a-f]{40}": "build $BUILD_HASH"}, "expected": [ 0, [ "build $BUILD_HASH", "Coverage: [ 67%] 2/3 (fail)", - "Added: $NOW", + "Added: $DATE", "Config: build_type: Debug,", " flag: on,", " os: qnx", diff --git a/apps/tests/main-set/014-show/163-show-file-in-build.json b/apps/tests/main-set/014-show/163-show-file-in-build.json index 9377208d..cacdadfd 100644 --- a/apps/tests/main-set/014-show/163-show-file-in-build.json +++ b/apps/tests/main-set/014-show/163-show-file-in-build.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "show $BUILD:src/main.cc", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/163-show-file-in-files.json b/apps/tests/main-set/014-show/163-show-file-in-files.json index 8eaaff86..59460b54 100644 --- a/apps/tests/main-set/014-show/163-show-file-in-files.json +++ b/apps/tests/main-set/014-show/163-show-file-in-files.json @@ -1,9 +1,7 @@ { + "$schema": "../../runner-schema.json", "args": "show $FILES:src/main.cc", - "patches": { - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $NOW" - }, + "patches": {"build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1"}, "expected": [ 0, [ diff --git a/apps/tests/main-set/015-filters-A/01-strip-excludes.json b/apps/tests/main-set/015-filters-A/01-strip-excludes.json index beb55dd8..3bebbb5d 100644 --- a/apps/tests/main-set/015-filters-A/01-strip-excludes.json +++ b/apps/tests/main-set/015-filters-A/01-strip-excludes.json @@ -1,9 +1,7 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json'", - "post": [ - "show HEAD:main.cc" - ], + "post": ["show HEAD:main.cc"], "patches": { "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" @@ -13,8 +11,8 @@ [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " one file, \u001b[31m 33%\u001b[m (5/15, -10), Fn\u001b[31m 40%\u001b[m (2/5)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 33%\u001b[m", "", "file main.cc", diff --git a/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json index 3ed91f30..989bfcd3 100644 --- a/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json +++ b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json @@ -1,20 +1,14 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS", - "post": [ - "show HEAD:main.cc" - ], - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, + "post": ["show HEAD:main.cc"], "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " one file, \u001b[31m 50%\u001b[m (5/10, -5), Fn\u001b[31m 40%\u001b[m (2/5)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 50%\u001b[m", "", "file main.cc", diff --git a/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json index 6308eda9..364b73f0 100644 --- a/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json +++ b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json @@ -1,21 +1,18 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler llvm", "post": "show", "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", "report [0-9a-f]{40}": "report $OID", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $DATE" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " 2 files, \u001b[31m 0%\u001b[m (0/0), Fn\u001b[31m 0%\u001b[m (0/2)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m", "", "report $OID", diff --git a/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json index 228b1b53..cd814419 100644 --- a/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json +++ b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json @@ -1,21 +1,18 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler clang", "post": "show", "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", "report [0-9a-f]{40}": "report $OID", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $DATE" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " 2 files, \u001b[31m 0%\u001b[m (0/0), Fn\u001b[31m 0%\u001b[m (0/2)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 0%\u001b[m", "", "report $OID", diff --git a/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json index a4166838..6196a4b7 100644 --- a/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json +++ b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json @@ -1,20 +1,14 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS --compiler compilerA", - "post": [ - "show HEAD:main.cc" - ], - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1" - }, + "post": ["show HEAD:main.cc"], "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " one file, \u001b[31m 29%\u001b[m (2/7, -5), Fn\u001b[31m 25%\u001b[m (1/4)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[31m 29%\u001b[m", "", "file main.cc", diff --git a/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json index 1822f36a..dfc4e211 100644 --- a/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json +++ b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json @@ -1,21 +1,18 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-multi.json'", "post": "show", "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m (.*)": "\u001b[31m[main $REPORT]\u001b[m \\1", - " \u001b\\[2;37mcontains [0-9a-fA-F]+:\u001b\\[m (.+)": " \u001b[2;37mcontains $BUILD:\u001b[m \\1", "report [0-9a-f]{40}": "report $OID", - "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1", - "Added: .*": "Added: $DATE" + "build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1" }, "expected": [ 0, [ "\u001b[31m[main $REPORT]\u001b[m Commit \"extensions\"", " 4 files, \u001b[32m100%\u001b[m (9/9), Fn\u001b[32m100%\u001b[m (4/4)", - " \u001b[2;37mbased on\u001b[m \u001b[2;33m98d4978ec@main\u001b[m", - " parent 45c01b5bd", + " \u001b[2;37mbased on\u001b[m \u001b[2;33m$HEAD@main\u001b[m", + " parent $PARENT", " \u001b[2;37mcontains $BUILD:\u001b[m \u001b[32m100%\u001b[m", "", "report $OID", diff --git a/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json index 891f1ec8..43a1b13f 100644 --- a/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json +++ b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-no-such.json'", "expected": [ 1, diff --git a/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json index 0ed7efc4..3bcf3ea9 100644 --- a/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json +++ b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-A.json'", "expected": [ 2, diff --git a/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json index 7304077b..a618b0d7 100644 --- a/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json +++ b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-B.json'", "expected": [ 2, diff --git a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json new file mode 100644 index 00000000..c2e08758 --- /dev/null +++ b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../runner-schema.json", + "args": "report -f strip-excludes '$DATA/extensions/report-broken-C.json'", + "expected": [ + 2, + "", + [ + "cov report: /files[0]/line_coverage (main.cc): undefined", + "cov report: error: there were issues with $DATA/extensions/report-broken-C.json processed by strip-excludes filter\n" + ] + ], + "prepare": [ + "unpack $DATA/extensions.tar $TMP", + "cd '$TMP/extensions'" + ] +} diff --git a/apps/tests/main-set/016-collect/01-collect-help.json b/apps/tests/main-set/016-collect/01-collect-help.json index 1b956e80..866b9734 100644 --- a/apps/tests/main-set/016-collect/01-collect-help.json +++ b/apps/tests/main-set/016-collect/01-collect-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect -h", "expected": [ 0, @@ -14,7 +14,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/main-set/016-collect/02-collect-unborn.json b/apps/tests/main-set/016-collect/02-collect-unborn.json index 653d5a42..dc5e36eb 100644 --- a/apps/tests/main-set/016-collect/02-collect-unborn.json +++ b/apps/tests/main-set/016-collect/02-collect-unborn.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "expected": [ 1, diff --git a/apps/tests/main-set/016-collect/03-collect-no-HEAD.json b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json index 3168845c..9f3f31ab 100644 --- a/apps/tests/main-set/016-collect/03-collect-no-HEAD.json +++ b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../schema.json", "disabled": true, "args": "collect", "expected": [ diff --git a/apps/tests/main-set/016-collect/04-collect-too-many-args.json b/apps/tests/main-set/016-collect/04-collect-too-many-args.json index c1384656..10d61f0a 100644 --- a/apps/tests/main-set/016-collect/04-collect-too-many-args.json +++ b/apps/tests/main-set/016-collect/04-collect-too-many-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect ctest -C Debug .", "expected": [ 2, diff --git a/apps/tests/main-set/016-collect/05-collect-too-little-args.json b/apps/tests/main-set/016-collect/05-collect-too-little-args.json index fdc4c3bb..15b27913 100644 --- a/apps/tests/main-set/016-collect/05-collect-too-little-args.json +++ b/apps/tests/main-set/016-collect/05-collect-too-little-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect --observe", "expected": [ 2, diff --git a/apps/tests/main-set/016-collect/06-collect-observe.json b/apps/tests/main-set/016-collect/06-collect-observe.json index 10edff9b..a1778b0c 100644 --- a/apps/tests/main-set/016-collect/06-collect-observe.json +++ b/apps/tests/main-set/016-collect/06-collect-observe.json @@ -1,5 +1,6 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", + "linear": true, "args": "collect --observe ctest -C Debug .", "expected": [ 0, diff --git a/apps/tests/main-set/016-collect/07-collect-clang.json b/apps/tests/main-set/016-collect/07-collect-clang.json index 5096d244..6c72866d 100644 --- a/apps/tests/main-set/016-collect/07-collect-clang.json +++ b/apps/tests/main-set/016-collect/07-collect-clang.json @@ -1,8 +1,8 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", "(.+)\\.exe": "\\1" }, "expected": [ diff --git a/apps/tests/main-set/016-collect/08-collect-gcc.json b/apps/tests/main-set/016-collect/08-collect-gcc.json index cc583378..90c0e894 100644 --- a/apps/tests/main-set/016-collect/08-collect-gcc.json +++ b/apps/tests/main-set/016-collect/08-collect-gcc.json @@ -1,8 +1,8 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", "(.+)\\.exe": "\\1" }, "expected": [ diff --git a/apps/tests/main-set/016-collect/09-collect-gcc-triple.json b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json index b5812f8f..8e1b13d1 100644 --- a/apps/tests/main-set/016-collect/09-collect-gcc-triple.json +++ b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../schema.json", "args": "collect", "disabled": true, "patches": { diff --git a/apps/tests/main-set/016-collect/10-collect-clean.json b/apps/tests/main-set/016-collect/10-collect-clean.json index a3e3ce24..b925e850 100644 --- a/apps/tests/main-set/016-collect/10-collect-clean.json +++ b/apps/tests/main-set/016-collect/10-collect-clean.json @@ -1,11 +1,7 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect --clean", - "expected": [ - 0, - "", - "" - ], + "expected": [0, "", ""], "prepare": [ "mkdirs '$TMP/collect'", "cd '$TMP/collect'", diff --git a/apps/tests/main-set/016-collect/11-collect-no-output.json b/apps/tests/main-set/016-collect/11-collect-no-output.json index 42678563..fcf7cfde 100644 --- a/apps/tests/main-set/016-collect/11-collect-no-output.json +++ b/apps/tests/main-set/016-collect/11-collect-no-output.json @@ -1,8 +1,8 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", "(.+)\\.exe": "\\1" }, "expected": [ diff --git a/apps/tests/main-set/016-collect/12-collect-msvc.json b/apps/tests/main-set/016-collect/12-collect-msvc.json index 5cf56454..8c664797 100644 --- a/apps/tests/main-set/016-collect/12-collect-msvc.json +++ b/apps/tests/main-set/016-collect/12-collect-msvc.json @@ -1,8 +1,8 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "patches": { - "\\[([^]]+)\\] [0-9.]+ s": "[\\1] #.## s", + "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", " \\[occ\\] C:\\\\+Program Files(:? \\(x86\\))?\\\\+OpenCppCoverage\\\\+OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", " \\[occ\\] \\$TMP\\/+mocks\\/+OpenCppCoverage\\.exe": " [occ] $TMP/mocks/OpenCppCoverage", " \\[outfile\\] \\\\OpenCppCoverage\\\\cobertura\\.xml": " [outfile] /OpenCppCoverage/cobertura.xml" @@ -29,7 +29,6 @@ "cov init", "git commit -m 'initial' --allow-empty", "mkdirs build/OpenCppCoverage", - "cp '$DATA/covcollect/OpenCppCoverage.xml' build/OpenCppCoverage/cobertura.xml", "touch src/main.cc", "mock cl.exe cl.exe", "mock OpenCppCoverage OpenCppCoverage", diff --git a/apps/tests/messages-pl/001-cov/001-version.json b/apps/tests/messages-pl/001-cov/001-version.json index 13e8c814..45fc2efc 100644 --- a/apps/tests/messages-pl/001-cov/001-version.json +++ b/apps/tests/messages-pl/001-cov/001-version.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "--version", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/002-help.json b/apps/tests/messages-pl/001-cov/002-help.json index 8c6d7fac..94d6c405 100644 --- a/apps/tests/messages-pl/001-cov/002-help.json +++ b/apps/tests/messages-pl/001-cov/002-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "--help", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/003-unknown-option.json b/apps/tests/messages-pl/001-cov/003-unknown-option.json index 21ece8bd..e391e7d8 100644 --- a/apps/tests/messages-pl/001-cov/003-unknown-option.json +++ b/apps/tests/messages-pl/001-cov/003-unknown-option.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "--versions", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/004-alias.json b/apps/tests/messages-pl/001-cov/004-alias.json index 7d652362..28e26eac 100644 --- a/apps/tests/messages-pl/001-cov/004-alias.json +++ b/apps/tests/messages-pl/001-cov/004-alias.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "-C recurse first -D", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/005-alias-short-help.json b/apps/tests/messages-pl/001-cov/005-alias-short-help.json index 400c1880..526be30f 100644 --- a/apps/tests/messages-pl/001-cov/005-alias-short-help.json +++ b/apps/tests/messages-pl/001-cov/005-alias-short-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "-C recurse second -h", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/007-alias-to-nothing.json b/apps/tests/messages-pl/001-cov/007-alias-to-nothing.json index 43851181..6327f39f 100644 --- a/apps/tests/messages-pl/001-cov/007-alias-to-nothing.json +++ b/apps/tests/messages-pl/001-cov/007-alias-to-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "-C bad-recurse start-bad", "expected": [ diff --git a/apps/tests/messages-pl/001-cov/008-bad-alias.json b/apps/tests/messages-pl/001-cov/008-bad-alias.json index 729b479a..cd856c50 100644 --- a/apps/tests/messages-pl/001-cov/008-bad-alias.json +++ b/apps/tests/messages-pl/001-cov/008-bad-alias.json @@ -1,24 +1,14 @@ { + "$schema": "../../runner-schema.json", "args": "-C bad-recurse first -D", - "check": { - "stderr": "begin" - }, + "check": {"stderr": "begin"}, "expected": [ 1, "", [ "użycie: cov [-h] [-C ] []", "cov: „fourth” nie jest poleceniem cov", - "", - "typowe polecenia:", - " init tworzy nowe repozytorium cov", - " config pokazuje i/lub ustawia różne ustawienia", - " module definiuje grupy plików", - " report dołącza raport do repozytorium", - " remove usuwa określony raport z repozytorium", - " log drukuje listę raportów", - " show pokazuje konkretny raport", - " serve uruchamia lokalny serwer WWW raportów\n" + "\n" ] ], "prepare": [ diff --git a/apps/tests/messages-pl/001-cov/013-bad-alias-full-output.json b/apps/tests/messages-pl/001-cov/013-bad-alias-full-output.json index 40d5b57a..83211276 100644 --- a/apps/tests/messages-pl/001-cov/013-bad-alias-full-output.json +++ b/apps/tests/messages-pl/001-cov/013-bad-alias-full-output.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "definitely-not-a-tool", "expected": [ diff --git a/apps/tests/messages-pl/002-init/015-init-no-args.json b/apps/tests/messages-pl/002-init/015-init-no-args.json index 3e664961..31c8b6b7 100644 --- a/apps/tests/messages-pl/002-init/015-init-no-args.json +++ b/apps/tests/messages-pl/002-init/015-init-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "init", "expected": [ diff --git a/apps/tests/messages-pl/002-init/020-init-no-gitrepo.json b/apps/tests/messages-pl/002-init/020-init-no-gitrepo.json index 1ecc6a30..2c3c9b6f 100644 --- a/apps/tests/messages-pl/002-init/020-init-no-gitrepo.json +++ b/apps/tests/messages-pl/002-init/020-init-no-gitrepo.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "init --git-dir '$TMP/repo.git' '$TMP/repo.covdata'", "expected": [ diff --git a/apps/tests/messages-pl/002-init/021-init-no-args-no-cwd.json b/apps/tests/messages-pl/002-init/021-init-no-args-no-cwd.json index ec27f440..2030e7bf 100644 --- a/apps/tests/messages-pl/002-init/021-init-no-args-no-cwd.json +++ b/apps/tests/messages-pl/002-init/021-init-no-args-no-cwd.json @@ -1,9 +1,8 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "init", - "patches": { - "cov init: błąd: argument -C: .*": "cov init: błąd: argument -C: ERROR MESSAGE" - }, + "patches": {"cov init: błąd: argument -C: .*": "cov init: błąd: argument -C: ERROR MESSAGE"}, "expected": [ 2, "", diff --git a/apps/tests/messages-pl/002-init/023-init-no-force.json b/apps/tests/messages-pl/002-init/023-init-no-force.json index a9c8b8f5..21fb1877 100644 --- a/apps/tests/messages-pl/002-init/023-init-no-force.json +++ b/apps/tests/messages-pl/002-init/023-init-no-force.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "init", "expected": [ diff --git a/apps/tests/messages-pl/002-init/024-init-force.json b/apps/tests/messages-pl/002-init/024-init-force.json index 44e5ee91..32733c6b 100644 --- a/apps/tests/messages-pl/002-init/024-init-force.json +++ b/apps/tests/messages-pl/002-init/024-init-force.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "init --force", "expected": [ diff --git a/apps/tests/messages-pl/003-config/025-config-no-args.json b/apps/tests/messages-pl/003-config/025-config-no-args.json index 926890ff..90b171bd 100644 --- a/apps/tests/messages-pl/003-config/025-config-no-args.json +++ b/apps/tests/messages-pl/003-config/025-config-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config", "expected": [ diff --git a/apps/tests/messages-pl/003-config/031-config-list-after-get.json b/apps/tests/messages-pl/003-config/031-config-list-after-get.json index 92861f2f..0264914a 100644 --- a/apps/tests/messages-pl/003-config/031-config-list-after-get.json +++ b/apps/tests/messages-pl/003-config/031-config-list-after-get.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "env": { "HOME": "$TMP/home", diff --git a/apps/tests/messages-pl/003-config/032-config-unset-after-list.json b/apps/tests/messages-pl/003-config/032-config-unset-after-list.json index 87d06ef0..6b9b64cc 100644 --- a/apps/tests/messages-pl/003-config/032-config-unset-after-list.json +++ b/apps/tests/messages-pl/003-config/032-config-unset-after-list.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "env": { "HOME": "$TMP/home", diff --git a/apps/tests/messages-pl/003-config/033-config-add-after-unset-all.json b/apps/tests/messages-pl/003-config/033-config-add-after-unset-all.json index 2358fa58..14a77207 100644 --- a/apps/tests/messages-pl/003-config/033-config-add-after-unset-all.json +++ b/apps/tests/messages-pl/003-config/033-config-add-after-unset-all.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "env": { "HOME": "$TMP/home", diff --git a/apps/tests/messages-pl/003-config/034-config-get-all-after-get.json b/apps/tests/messages-pl/003-config/034-config-get-all-after-get.json index 8bf0530c..34d73732 100644 --- a/apps/tests/messages-pl/003-config/034-config-get-all-after-get.json +++ b/apps/tests/messages-pl/003-config/034-config-get-all-after-get.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "env": { "HOME": "$TMP/home", diff --git a/apps/tests/messages-pl/003-config/035-config-list-local-no-cov.json b/apps/tests/messages-pl/003-config/035-config-list-local-no-cov.json index 6a2607c2..062d13b9 100644 --- a/apps/tests/messages-pl/003-config/035-config-list-local-no-cov.json +++ b/apps/tests/messages-pl/003-config/035-config-list-local-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --local --list", "expected": [ diff --git a/apps/tests/messages-pl/003-config/036-config-add-one-arg.json b/apps/tests/messages-pl/003-config/036-config-add-one-arg.json index 0a611b6a..1bb897b4 100644 --- a/apps/tests/messages-pl/003-config/036-config-add-one-arg.json +++ b/apps/tests/messages-pl/003-config/036-config-add-one-arg.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config --add group.key", "expected": [ diff --git a/apps/tests/messages-pl/003-config/037-config-unset-too-many.json b/apps/tests/messages-pl/003-config/037-config-unset-too-many.json index f0fe6832..62ffbb24 100644 --- a/apps/tests/messages-pl/003-config/037-config-unset-too-many.json +++ b/apps/tests/messages-pl/003-config/037-config-unset-too-many.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config --unset group.key value", "expected": [ diff --git a/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json b/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json index c4f56289..d079933c 100644 --- a/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json +++ b/apps/tests/messages-pl/003-config/038-config-set-but-multivar.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ @@ -6,7 +7,5 @@ "", "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/messages-pl/003-config/039-config-set-but-include.json b/apps/tests/messages-pl/003-config/039-config-set-but-include.json index b389b2d7..d9688e39 100644 --- a/apps/tests/messages-pl/003-config/039-config-set-but-include.json +++ b/apps/tests/messages-pl/003-config/039-config-set-but-include.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ diff --git a/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json b/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json index 7c96b4cf..5ded5a24 100644 --- a/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json +++ b/apps/tests/messages-pl/003-config/040-config-unset-but-multivar.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config --unset group.key", "expected": [ @@ -6,7 +7,5 @@ "", "cov config: błąd: wpis nie jest unikalny ze względu na to, że jest zmienną wielokrotną\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json b/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json index 80091f7e..ddffef59 100644 --- a/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json +++ b/apps/tests/messages-pl/003-config/041-config-unset-but-not-there.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config --unset group.other", "expected": [ @@ -6,7 +7,5 @@ "", "cov config: błąd: nie można odnaleźć klucza „group.other” do usunięcia\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json b/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json index 1ea9a720..e198fff4 100644 --- a/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json +++ b/apps/tests/messages-pl/003-config/042-config-unset-but-no-a-key.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "config --file $TMP/config --unset group-other", "expected": [ @@ -6,7 +7,5 @@ "", "cov config: błąd: nieprawidłowa nazwa elementu konfiguracji „group-other”\n" ], - "prepare": [ - "touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'" - ] + "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] } diff --git a/apps/tests/messages-pl/004-module/047-module-help.json b/apps/tests/messages-pl/004-module/047-module-help.json index 349f0426..c4027273 100644 --- a/apps/tests/messages-pl/004-module/047-module-help.json +++ b/apps/tests/messages-pl/004-module/047-module-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --help", "expected": [ diff --git a/apps/tests/messages-pl/004-module/051-module-modify-in-bare-git.json b/apps/tests/messages-pl/004-module/051-module-modify-in-bare-git.json index 28399599..0d149ee9 100644 --- a/apps/tests/messages-pl/004-module/051-module-modify-in-bare-git.json +++ b/apps/tests/messages-pl/004-module/051-module-modify-in-bare-git.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --remove-all \"doesn't matter\"", "expected": [ diff --git a/apps/tests/messages-pl/004-module/052-module-add-duplicate.json b/apps/tests/messages-pl/004-module/052-module-add-duplicate.json index c997c6eb..b11571e2 100644 --- a/apps/tests/messages-pl/004-module/052-module-add-duplicate.json +++ b/apps/tests/messages-pl/004-module/052-module-add-duplicate.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --add module 'dir 1'", "expected": [ diff --git a/apps/tests/messages-pl/004-module/053-module-remove-from-nothing.json b/apps/tests/messages-pl/004-module/053-module-remove-from-nothing.json index b9db4ca7..af2aab9b 100644 --- a/apps/tests/messages-pl/004-module/053-module-remove-from-nothing.json +++ b/apps/tests/messages-pl/004-module/053-module-remove-from-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --remove some-name 'dir 1'", "expected": [ diff --git a/apps/tests/messages-pl/004-module/056-module-open_from_ref-range.json b/apps/tests/messages-pl/004-module/056-module-open_from_ref-range.json index 058e98c1..644489dd 100644 --- a/apps/tests/messages-pl/004-module/056-module-open_from_ref-range.json +++ b/apps/tests/messages-pl/004-module/056-module-open_from_ref-range.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module v1.0.0..HEAD", "expected": [ diff --git a/apps/tests/messages-pl/004-module/057-module-open_from_ref-tree.json b/apps/tests/messages-pl/004-module/057-module-open_from_ref-tree.json index 9c0fff76..78b14052 100644 --- a/apps/tests/messages-pl/004-module/057-module-open_from_ref-tree.json +++ b/apps/tests/messages-pl/004-module/057-module-open_from_ref-tree.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module 2559ccfa6", "expected": [ diff --git a/apps/tests/messages-pl/004-module/058-module-no-git.json b/apps/tests/messages-pl/004-module/058-module-no-git.json index aa7eed55..e704a773 100644 --- a/apps/tests/messages-pl/004-module/058-module-no-git.json +++ b/apps/tests/messages-pl/004-module/058-module-no-git.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module", "expected": [ diff --git a/apps/tests/messages-pl/004-module/059-module-excl-show.json b/apps/tests/messages-pl/004-module/059-module-excl-show.json index 779681cd..c457d867 100644 --- a/apps/tests/messages-pl/004-module/059-module-excl-show.json +++ b/apps/tests/messages-pl/004-module/059-module-excl-show.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module HEAD --add module dir", "expected": [ diff --git a/apps/tests/messages-pl/004-module/060-module-excl-show-sep.json b/apps/tests/messages-pl/004-module/060-module-excl-show-sep.json index dbdbb60c..f0a03fd8 100644 --- a/apps/tests/messages-pl/004-module/060-module-excl-show-sep.json +++ b/apps/tests/messages-pl/004-module/060-module-excl-show-sep.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --show-sep --add module dir", "expected": [ diff --git a/apps/tests/messages-pl/004-module/061-module-too-many-refs.json b/apps/tests/messages-pl/004-module/061-module-too-many-refs.json index 3cf68d9d..2d9f6a11 100644 --- a/apps/tests/messages-pl/004-module/061-module-too-many-refs.json +++ b/apps/tests/messages-pl/004-module/061-module-too-many-refs.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module HEAD ANOTHER_HEAD main v1.0.0", "expected": [ diff --git a/apps/tests/messages-pl/004-module/062-module-too-little-args.json b/apps/tests/messages-pl/004-module/062-module-too-little-args.json index d9adc26d..ab17fa77 100644 --- a/apps/tests/messages-pl/004-module/062-module-too-little-args.json +++ b/apps/tests/messages-pl/004-module/062-module-too-little-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --add module", "expected": [ diff --git a/apps/tests/messages-pl/004-module/062-module-too-many-args.json b/apps/tests/messages-pl/004-module/062-module-too-many-args.json index 47a823b6..b5deb0f4 100644 --- a/apps/tests/messages-pl/004-module/062-module-too-many-args.json +++ b/apps/tests/messages-pl/004-module/062-module-too-many-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --remove-all module dir", "expected": [ diff --git a/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json b/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json index e775219e..d3edb0b8 100644 --- a/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json +++ b/apps/tests/messages-pl/004-module/064-module-no-covmodule-add.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "module --add module dir", "expected": [ diff --git a/apps/tests/messages-pl/005-report/066-report-no-args.json b/apps/tests/messages-pl/005-report/066-report-no-args.json index 96f57d8f..ef0d2a91 100644 --- a/apps/tests/messages-pl/005-report/066-report-no-args.json +++ b/apps/tests/messages-pl/005-report/066-report-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report", "expected": [ diff --git a/apps/tests/messages-pl/005-report/067-report-help.json b/apps/tests/messages-pl/005-report/067-report-help.json index 99c48a35..883b23d5 100644 --- a/apps/tests/messages-pl/005-report/067-report-help.json +++ b/apps/tests/messages-pl/005-report/067-report-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report -h", "expected": [ diff --git a/apps/tests/messages-pl/005-report/068-report-no-cov.json b/apps/tests/messages-pl/005-report/068-report-no-cov.json index 53e80d29..5bacbfb9 100644 --- a/apps/tests/messages-pl/005-report/068-report-no-cov.json +++ b/apps/tests/messages-pl/005-report/068-report-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/basic-coverage.json", "expected": [ diff --git a/apps/tests/messages-pl/005-report/069-report-no-commit.json b/apps/tests/messages-pl/005-report/069-report-no-commit.json index ea86d916..fe0134de 100644 --- a/apps/tests/messages-pl/005-report/069-report-no-commit.json +++ b/apps/tests/messages-pl/005-report/069-report-no-commit.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/basic-coverage.json", "expected": [ diff --git a/apps/tests/messages-pl/005-report/070-report-failing-filter.json b/apps/tests/messages-pl/005-report/070-report-failing-filter.json index 98b0e799..7e9fe0cc 100644 --- a/apps/tests/messages-pl/005-report/070-report-failing-filter.json +++ b/apps/tests/messages-pl/005-report/070-report-failing-filter.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/basic-coverage.json -f echo-to-stderr", "expected": [ diff --git a/apps/tests/messages-pl/005-report/071-report-no-filter.json b/apps/tests/messages-pl/005-report/071-report-no-filter.json index 6037eba7..cfdfbf1d 100644 --- a/apps/tests/messages-pl/005-report/071-report-no-filter.json +++ b/apps/tests/messages-pl/005-report/071-report-no-filter.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/basic-coverage.json -f no-filter", "expected": [ diff --git a/apps/tests/messages-pl/005-report/072-report-not-the-json.json b/apps/tests/messages-pl/005-report/072-report-not-the-json.json index 71862dad..05d76b78 100644 --- a/apps/tests/messages-pl/005-report/072-report-not-the-json.json +++ b/apps/tests/messages-pl/005-report/072-report-not-the-json.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/no-git-coverage.json", "expected": [ diff --git a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json index 844192fc..6f156b2f 100644 --- a/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json +++ b/apps/tests/messages-pl/005-report/073-report-not-the-json-filtered.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/no-git-coverage.json -f echo-to-stdout", "expected": [ diff --git a/apps/tests/messages-pl/005-report/074-report-no-file.json b/apps/tests/messages-pl/005-report/074-report-no-file.json index c37f55d3..0ba9c8fd 100644 --- a/apps/tests/messages-pl/005-report/074-report-no-file.json +++ b/apps/tests/messages-pl/005-report/074-report-no-file.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/basic-coverage.json -f replace-head", "expected": [ diff --git a/apps/tests/messages-pl/005-report/075-report-empty.json b/apps/tests/messages-pl/005-report/075-report-empty.json index 5f60c00a..2220da74 100644 --- a/apps/tests/messages-pl/005-report/075-report-empty.json +++ b/apps/tests/messages-pl/005-report/075-report-empty.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/empty-coverage.json -f replace-head", "patches": { diff --git a/apps/tests/messages-pl/005-report/076-report-one-file.json b/apps/tests/messages-pl/005-report/076-report-one-file.json index d7d46c21..f0c8ec0b 100644 --- a/apps/tests/messages-pl/005-report/076-report-one-file.json +++ b/apps/tests/messages-pl/005-report/076-report-one-file.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage.json -f create-report", "patches": { diff --git a/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json b/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json index f804214f..7f078e48 100644 --- a/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json +++ b/apps/tests/messages-pl/005-report/077-report-amend-on-empty.json @@ -1,9 +1,8 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage.json -f create-report --amend", - "patches": { - "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second" - }, + "patches": {"\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second"}, "expected": [ 2, "", diff --git a/apps/tests/messages-pl/005-report/078-D-report-with-props.json b/apps/tests/messages-pl/005-report/078-D-report-with-props.json index 2a57b8e1..4c508145 100644 --- a/apps/tests/messages-pl/005-report/078-D-report-with-props.json +++ b/apps/tests/messages-pl/005-report/078-D-report-with-props.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report -pos=qnx -pdebug=false -pcompiler=javac", "patches": { "\u001b\\[31m\\[main [0-9a-fA-F]+\\]\u001b\\[m second": "\u001b[31m[main $REPORT]\u001b[m second", diff --git a/apps/tests/messages-pl/005-report/078-report-amend-on-parentless.json b/apps/tests/messages-pl/005-report/078-report-amend-on-parentless.json index 46f002d7..331fb567 100644 --- a/apps/tests/messages-pl/005-report/078-report-amend-on-parentless.json +++ b/apps/tests/messages-pl/005-report/078-report-amend-on-parentless.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage.json -f create-report --amend", "patches": { diff --git a/apps/tests/messages-pl/005-report/079-B-report-the-same-twice.json b/apps/tests/messages-pl/005-report/079-B-report-the-same-twice.json index e5a48851..4e215834 100644 --- a/apps/tests/messages-pl/005-report/079-B-report-the-same-twice.json +++ b/apps/tests/messages-pl/005-report/079-B-report-the-same-twice.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage.json -f create-report", "expected": [ diff --git a/apps/tests/messages-pl/005-report/079-report-with-parent.json b/apps/tests/messages-pl/005-report/079-report-with-parent.json index 937805e4..f3971057 100644 --- a/apps/tests/messages-pl/005-report/079-report-with-parent.json +++ b/apps/tests/messages-pl/005-report/079-report-with-parent.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage-2-files.json -f create-report", "patches": { diff --git a/apps/tests/messages-pl/005-report/080-report-on-detached.json b/apps/tests/messages-pl/005-report/080-report-on-detached.json index c5516835..9eb1786d 100644 --- a/apps/tests/messages-pl/005-report/080-report-on-detached.json +++ b/apps/tests/messages-pl/005-report/080-report-on-detached.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage-2-files.json -f create-report", "patches": { diff --git a/apps/tests/messages-pl/005-report/081-report-hash-bang-less.json b/apps/tests/messages-pl/005-report/081-report-hash-bang-less.json index 307e3303..d2c00f68 100644 --- a/apps/tests/messages-pl/005-report/081-report-hash-bang-less.json +++ b/apps/tests/messages-pl/005-report/081-report-hash-bang-less.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "report $DATA/build-coverage-2-files.json -f hash-bang-less", "expected": [ diff --git a/apps/tests/messages-pl/006-log/082-log-no-args.json b/apps/tests/messages-pl/006-log/082-log-no-args.json index 4d5de384..888d6042 100644 --- a/apps/tests/messages-pl/006-log/082-log-no-args.json +++ b/apps/tests/messages-pl/006-log/082-log-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log", "expected": [ @@ -9,7 +10,5 @@ "cov log: błąd: Nie można znaleźć repozytorium Cov w $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/006-log/083-log-no-args-inited.json b/apps/tests/messages-pl/006-log/083-log-no-args-inited.json index 7e2187da..fe6434d3 100644 --- a/apps/tests/messages-pl/006-log/083-log-no-args-inited.json +++ b/apps/tests/messages-pl/006-log/083-log-no-args-inited.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log", "expected": [ diff --git a/apps/tests/messages-pl/006-log/084-log-no-args-Dmain.json b/apps/tests/messages-pl/006-log/084-log-no-args-Dmain.json index adb595d5..4ab7e093 100644 --- a/apps/tests/messages-pl/006-log/084-log-no-args-Dmain.json +++ b/apps/tests/messages-pl/006-log/084-log-no-args-Dmain.json @@ -1,9 +1,8 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log", - "patches": { - "Added: .*": "Added: $DATE" - }, + "patches": {"Added: .*": "Added: $DATE"}, "expected": [ 0, [ diff --git a/apps/tests/messages-pl/006-log/092-log-help.json b/apps/tests/messages-pl/006-log/092-log-help.json index 635b5281..e45893cf 100644 --- a/apps/tests/messages-pl/006-log/092-log-help.json +++ b/apps/tests/messages-pl/006-log/092-log-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log --help", "expected": [ diff --git a/apps/tests/messages-pl/006-log/093-log-two-HEADs.json b/apps/tests/messages-pl/006-log/093-log-two-HEADs.json index 3f390cce..93776e06 100644 --- a/apps/tests/messages-pl/006-log/093-log-two-HEADs.json +++ b/apps/tests/messages-pl/006-log/093-log-two-HEADs.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log ..", "expected": [ diff --git a/apps/tests/messages-pl/006-log/094-log-123456789.json b/apps/tests/messages-pl/006-log/094-log-123456789.json index 89cc3ca7..a6baff15 100644 --- a/apps/tests/messages-pl/006-log/094-log-123456789.json +++ b/apps/tests/messages-pl/006-log/094-log-123456789.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "log 123456789", "expected": [ diff --git a/apps/tests/messages-pl/006-log/095-log-try-non-report.json b/apps/tests/messages-pl/006-log/095-log-try-non-report.json index e152f2c3..786f3ff9 100644 --- a/apps/tests/messages-pl/006-log/095-log-try-non-report.json +++ b/apps/tests/messages-pl/006-log/095-log-try-non-report.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "args": "log $BUILD --prop-names --decorate short", "expected": [ 2, diff --git a/apps/tests/messages-pl/007-refs/095-branch-no-args.json b/apps/tests/messages-pl/007-refs/095-branch-no-args.json index 019c5da6..46a6c490 100644 --- a/apps/tests/messages-pl/007-refs/095-branch-no-args.json +++ b/apps/tests/messages-pl/007-refs/095-branch-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch", "expected": [ @@ -9,7 +10,5 @@ "cov branch: błąd: Nie można znaleźć repozytorium Cov w $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/007-refs/096-tag-no-args.json b/apps/tests/messages-pl/007-refs/096-tag-no-args.json index 5876c7a1..9e1e7222 100644 --- a/apps/tests/messages-pl/007-refs/096-tag-no-args.json +++ b/apps/tests/messages-pl/007-refs/096-tag-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag", "expected": [ @@ -9,7 +10,5 @@ "cov tag: błąd: Nie można znaleźć repozytorium Cov w $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/007-refs/097-branch-help.json b/apps/tests/messages-pl/007-refs/097-branch-help.json index 8ce3b786..325e2c6d 100644 --- a/apps/tests/messages-pl/007-refs/097-branch-help.json +++ b/apps/tests/messages-pl/007-refs/097-branch-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch --help", "expected": [ @@ -21,7 +22,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/007-refs/098-tag-help.json b/apps/tests/messages-pl/007-refs/098-tag-help.json index e4c27b19..cbe137d2 100644 --- a/apps/tests/messages-pl/007-refs/098-tag-help.json +++ b/apps/tests/messages-pl/007-refs/098-tag-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag --help", "expected": [ @@ -18,7 +19,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/007-refs/104-branch-force-delete.json b/apps/tests/messages-pl/007-refs/104-branch-force-delete.json index 9702f5c6..e5a7e1d6 100644 --- a/apps/tests/messages-pl/007-refs/104-branch-force-delete.json +++ b/apps/tests/messages-pl/007-refs/104-branch-force-delete.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch --delete main --force", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/105-branch-two-commands.json b/apps/tests/messages-pl/007-refs/105-branch-two-commands.json index 92ae2616..83bd9565 100644 --- a/apps/tests/messages-pl/007-refs/105-branch-two-commands.json +++ b/apps/tests/messages-pl/007-refs/105-branch-two-commands.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch --show-current -l feat/cov-*", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/108-branch-create-existing.json b/apps/tests/messages-pl/007-refs/108-branch-create-existing.json index 8a73b1b2..8fb1a585 100644 --- a/apps/tests/messages-pl/007-refs/108-branch-create-existing.json +++ b/apps/tests/messages-pl/007-refs/108-branch-create-existing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch cov-separate", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/109-branch-create-three-at-a-time.json b/apps/tests/messages-pl/007-refs/109-branch-create-three-at-a-time.json index 4a2806d6..09bda280 100644 --- a/apps/tests/messages-pl/007-refs/109-branch-create-three-at-a-time.json +++ b/apps/tests/messages-pl/007-refs/109-branch-create-three-at-a-time.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch branch-1 branch-2 branch-3", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json b/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json index 8db14751..b397c22a 100644 --- a/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json +++ b/apps/tests/messages-pl/007-refs/110-branch-create-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch name", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/111-branch-delete-nothing.json b/apps/tests/messages-pl/007-refs/111-branch-delete-nothing.json index c908b28e..d0321ebb 100644 --- a/apps/tests/messages-pl/007-refs/111-branch-delete-nothing.json +++ b/apps/tests/messages-pl/007-refs/111-branch-delete-nothing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch --delete", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/112-branch-delete-main.json b/apps/tests/messages-pl/007-refs/112-branch-delete-main.json index 55baa773..4df382a6 100644 --- a/apps/tests/messages-pl/007-refs/112-branch-delete-main.json +++ b/apps/tests/messages-pl/007-refs/112-branch-delete-main.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch -d main", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json b/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json index e7295939..3bd2b421 100644 --- a/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json +++ b/apps/tests/messages-pl/007-refs/114-branch-delete-nonexisting.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch -d feat/cov-22", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/117-tag-create-existing.json b/apps/tests/messages-pl/007-refs/117-tag-create-existing.json index fe9b9876..7738be99 100644 --- a/apps/tests/messages-pl/007-refs/117-tag-create-existing.json +++ b/apps/tests/messages-pl/007-refs/117-tag-create-existing.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag H", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/118-tag-create-three-at-a-time.json b/apps/tests/messages-pl/007-refs/118-tag-create-three-at-a-time.json index 98af328b..ae89649b 100644 --- a/apps/tests/messages-pl/007-refs/118-tag-create-three-at-a-time.json +++ b/apps/tests/messages-pl/007-refs/118-tag-create-three-at-a-time.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag tag-1 tag-2 tag-3", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json b/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json index 715e25d4..8a3ce27f 100644 --- a/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json +++ b/apps/tests/messages-pl/007-refs/119-tag-create-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag name", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json b/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json index 2e6cefd4..98826b7e 100644 --- a/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json +++ b/apps/tests/messages-pl/007-refs/121-tag-delete-nonexisting.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag -d nonexisting", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/122-branch-create-invalid.json b/apps/tests/messages-pl/007-refs/122-branch-create-invalid.json index 563afab3..f2faa146 100644 --- a/apps/tests/messages-pl/007-refs/122-branch-create-invalid.json +++ b/apps/tests/messages-pl/007-refs/122-branch-create-invalid.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "branch \"bad:name\"", "expected": [ diff --git a/apps/tests/messages-pl/007-refs/123-tag-create-invalid.json b/apps/tests/messages-pl/007-refs/123-tag-create-invalid.json index 34b63681..f9331f3f 100644 --- a/apps/tests/messages-pl/007-refs/123-tag-create-invalid.json +++ b/apps/tests/messages-pl/007-refs/123-tag-create-invalid.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "tag \"bad:name\"", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/125-checkout-no-args.json b/apps/tests/messages-pl/012-checkout/125-checkout-no-args.json index 2b2778fe..2cbec13a 100644 --- a/apps/tests/messages-pl/012-checkout/125-checkout-no-args.json +++ b/apps/tests/messages-pl/012-checkout/125-checkout-no-args.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout", "expected": [ @@ -9,7 +10,5 @@ "cov checkout: błąd: potrzebny jest co najmniej jeden argument\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/012-checkout/126-checkout-no-cov.json b/apps/tests/messages-pl/012-checkout/126-checkout-no-cov.json index 2a4993d2..bb4d3e14 100644 --- a/apps/tests/messages-pl/012-checkout/126-checkout-no-cov.json +++ b/apps/tests/messages-pl/012-checkout/126-checkout-no-cov.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout main", "expected": [ @@ -9,7 +10,5 @@ "cov checkout: błąd: Nie można znaleźć repozytorium Cov w $TMP\n" ] ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/012-checkout/127-checkout-help.json b/apps/tests/messages-pl/012-checkout/127-checkout-help.json index cd067158..c39da17b 100644 --- a/apps/tests/messages-pl/012-checkout/127-checkout-help.json +++ b/apps/tests/messages-pl/012-checkout/127-checkout-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout -h", "expected": [ @@ -22,7 +23,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/012-checkout/128-checkout-two-names.json b/apps/tests/messages-pl/012-checkout/128-checkout-two-names.json index 6dbf7529..cf690fc3 100644 --- a/apps/tests/messages-pl/012-checkout/128-checkout-two-names.json +++ b/apps/tests/messages-pl/012-checkout/128-checkout-two-names.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout two names", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/129-checkout-too-many-for-branching.json b/apps/tests/messages-pl/012-checkout/129-checkout-too-many-for-branching.json index 9d61fa5b..95924871 100644 --- a/apps/tests/messages-pl/012-checkout/129-checkout-too-many-for-branching.json +++ b/apps/tests/messages-pl/012-checkout/129-checkout-too-many-for-branching.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout -b result starting-point something else", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/130-checkout-too-little-for-branching.json b/apps/tests/messages-pl/012-checkout/130-checkout-too-little-for-branching.json index c9a8be8b..055c1382 100644 --- a/apps/tests/messages-pl/012-checkout/130-checkout-too-little-for-branching.json +++ b/apps/tests/messages-pl/012-checkout/130-checkout-too-little-for-branching.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout -b", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/131-checkout-two-commands.json b/apps/tests/messages-pl/012-checkout/131-checkout-two-commands.json index ce13dcb7..531eb28a 100644 --- a/apps/tests/messages-pl/012-checkout/131-checkout-two-commands.json +++ b/apps/tests/messages-pl/012-checkout/131-checkout-two-commands.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout -b --orphan", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json b/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json index d37852e9..027478c1 100644 --- a/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json +++ b/apps/tests/messages-pl/012-checkout/133-checkout-orphan.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout --orphan branch-name", "post": [ diff --git a/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json b/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json index fb4460f7..86b573bd 100644 --- a/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json +++ b/apps/tests/messages-pl/012-checkout/134-checkout-orphan-main.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout --orphan main", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json b/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json index cf596610..96355bc0 100644 --- a/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json +++ b/apps/tests/messages-pl/012-checkout/135-checkout-orphan-invalid-spec.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout --orphan 'invalid:spec'", "expected": [ diff --git a/apps/tests/messages-pl/012-checkout/138-checkout-without-HEAD.json b/apps/tests/messages-pl/012-checkout/138-checkout-without-HEAD.json index 7262a27d..a9aec701 100644 --- a/apps/tests/messages-pl/012-checkout/138-checkout-without-HEAD.json +++ b/apps/tests/messages-pl/012-checkout/138-checkout-without-HEAD.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "checkout --detach", "expected": [ diff --git a/apps/tests/messages-pl/014-show/145-show-help.json b/apps/tests/messages-pl/014-show/145-show-help.json index 2662cbbc..df3419fb 100644 --- a/apps/tests/messages-pl/014-show/145-show-help.json +++ b/apps/tests/messages-pl/014-show/145-show-help.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "show -h", "expected": [ @@ -22,7 +23,5 @@ ], "" ], - "prepare": [ - "cd '$TMP'" - ] + "prepare": ["cd '$TMP'"] } diff --git a/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json b/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json index b29acf33..69bc4a50 100644 --- a/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json +++ b/apps/tests/messages-pl/014-show/146-show-no-args-unborn.json @@ -1,4 +1,5 @@ { + "$schema": "../../runner-schema.json", "lang": "pl", "args": "show", "expected": [ From 6c1ea59507f7c514d76b273ad9b83470cde834f9 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 17 Sep 2023 09:47:47 +0200 Subject: [PATCH 36/39] test: update $schema --- apps/tests/main-set/001-cov/001-version.json | 2 +- apps/tests/main-set/001-cov/002-help.json | 2 +- apps/tests/main-set/001-cov/003-unknown-option.json | 2 +- apps/tests/main-set/001-cov/004-alias.json | 2 +- apps/tests/main-set/001-cov/005-alias-short-help.json | 2 +- apps/tests/main-set/001-cov/006-alias-long-help.json | 2 +- apps/tests/main-set/001-cov/007-alias-to-nothing.json | 2 +- apps/tests/main-set/001-cov/008-bad-alias.json | 2 +- apps/tests/main-set/001-cov/009-external-tool.json | 2 +- apps/tests/main-set/001-cov/010-escaped-arguments.json | 2 +- apps/tests/main-set/001-cov/011-multiple-aliases.json | 2 +- apps/tests/main-set/001-cov/012-list-cmds.json | 2 +- apps/tests/main-set/001-cov/013-bad-alias-full-output.json | 2 +- .../main-set/001-cov/014-echo-with-nonascii-arguments.json | 2 +- apps/tests/main-set/001-cov/015-bad-alias-with-env.json | 2 +- .../main-set/001-cov/016-external-tool-outside-libexec.json | 2 +- apps/tests/main-set/002-init/015-init-no-args.json | 2 +- apps/tests/main-set/002-init/016-init-git-dir.json | 2 +- apps/tests/main-set/002-init/017-init-directory.json | 2 +- apps/tests/main-set/002-init/018-init-dependent.json | 2 +- apps/tests/main-set/002-init/019-init-independent.json | 2 +- apps/tests/main-set/002-init/020-init-no-gitrepo.json | 2 +- apps/tests/main-set/002-init/022-init-git-dir-relative.json | 2 +- apps/tests/main-set/002-init/023-init-no-force.json | 2 +- apps/tests/main-set/002-init/024-init-force.json | 2 +- apps/tests/main-set/003-config-A/025-config-no-args.json | 2 +- apps/tests/main-set/003-config-A/026-config-list-local.json | 2 +- apps/tests/main-set/003-config-A/027-config-list-global.json | 2 +- apps/tests/main-set/003-config-A/028-config-list-system.json | 2 +- apps/tests/main-set/003-config-A/029-config-list-file.json | 2 +- apps/tests/main-set/004-config-B/030-config-list-any.json | 2 +- .../main-set/004-config-B/031-config-list-after-get.json | 2 +- .../main-set/004-config-B/032-config-unset-after-list.json | 2 +- .../004-config-B/033-config-add-after-unset-all.json | 2 +- .../main-set/004-config-B/034-config-get-all-after-get.json | 2 +- .../main-set/004-config-B/035-config-list-local-no-cov.json | 2 +- apps/tests/main-set/004-config-B/036-config-add-one-arg.json | 2 +- .../main-set/004-config-B/037-config-unset-too-many.json | 2 +- .../main-set/005-config-C/038-config-set-but-multivar.json | 2 +- .../main-set/005-config-C/039-config-set-but-include.json | 2 +- .../main-set/005-config-C/040-config-unset-but-multivar.json | 2 +- .../005-config-C/041-config-unset-but-not-there.json | 2 +- .../main-set/005-config-C/042-config-unset-but-no-a-key.json | 2 +- apps/tests/main-set/005-config-C/043-config-get.json | 2 +- apps/tests/main-set/005-config-C/044-config-get-all.json | 2 +- apps/tests/main-set/005-config-C/045-config-add.json | 2 +- apps/tests/main-set/005-config-C/046-config-unset-all.json | 2 +- apps/tests/main-set/006-module-A/047-module-help.json | 2 +- .../main-set/006-module-A/048-module-build-and-print.json | 2 +- .../006-module-A/049-module-build-and-print-sep.json | 2 +- .../006-module-A/050-module-deconstruct-and-print.json | 2 +- .../main-set/006-module-A/051-module-modify-in-bare-git.json | 2 +- .../main-set/006-module-A/052-module-add-duplicate.json | 2 +- .../007-module-B/053-module-remove-from-nothing.json | 2 +- .../main-set/007-module-B/054-module-print-from-HEAD.json | 2 +- .../007-module-B/055-module-print-sep-from-HEAD.json | 2 +- .../007-module-B/056-module-open_from_ref-range.json | 2 +- .../main-set/007-module-B/057-module-open_from_ref-tree.json | 2 +- apps/tests/main-set/007-module-B/058-module-no-git.json | 2 +- apps/tests/main-set/007-module-B/059-module-excl-show.json | 2 +- .../main-set/007-module-B/060-module-excl-show-sep.json | 2 +- .../main-set/007-module-B/061-module-too-many-refs.json | 2 +- .../main-set/007-module-B/062-module-too-little-args.json | 2 +- .../main-set/007-module-B/062-module-too-many-args.json | 2 +- .../tests/main-set/007-module-B/063-module-no-covmodule.json | 2 +- .../main-set/007-module-B/064-module-no-covmodule-add.json | 2 +- .../065-module-open_from_ref-no-such-object.json | 2 +- apps/tests/main-set/008-report-A/066-report-no-args.json | 2 +- apps/tests/main-set/008-report-A/067-report-help.json | 2 +- apps/tests/main-set/008-report-A/068-report-no-cov.json | 2 +- apps/tests/main-set/008-report-A/069-report-no-commit.json | 2 +- .../main-set/008-report-A/070-report-failing-filter.json | 2 +- apps/tests/main-set/008-report-A/071-report-no-filter.json | 2 +- .../tests/main-set/008-report-A/072-report-not-the-json.json | 2 +- .../008-report-A/073-report-not-the-json-filtered.json | 3 ++- apps/tests/main-set/009-report-B/074-report-no-file.json | 2 +- apps/tests/main-set/009-report-B/075-report-empty.json | 2 +- apps/tests/main-set/009-report-B/076-report-one-file.json | 2 +- .../main-set/009-report-B/077-report-amend-on-empty.json | 2 +- .../tests/main-set/009-report-B/078-D-report-with-props.json | 2 +- .../009-report-B/078-report-amend-on-parentless.json | 2 +- .../main-set/009-report-B/079-B-report-the-same-twice.json | 2 +- .../009-report-B/079-C-report-almost-the-same-twice.json | 2 +- apps/tests/main-set/009-report-B/079-report-with-parent.json | 2 +- apps/tests/main-set/009-report-B/080-report-on-detached.json | 2 +- .../main-set/009-report-B/081-report-hash-bang-less.json | 2 +- apps/tests/main-set/010-log/082-log-no-args.json | 2 +- apps/tests/main-set/010-log/083-log-no-args-inited.json | 2 +- apps/tests/main-set/010-log/084-log-no-args-Dmain.json | 2 +- apps/tests/main-set/010-log/085-log-G..K-oneline.json | 2 +- .../main-set/010-log/086-log-separate-raw-decorate.json | 2 +- .../main-set/010-log/087-log-feat3-fuller-decorate.json | 2 +- apps/tests/main-set/010-log/088-log-G..K-oneline-color.json | 2 +- apps/tests/main-set/010-log/089-log-B..K-format-pretty.json | 2 +- .../main-set/010-log/090-log-B..K-no-format-but-pretty.json | 2 +- .../tests/main-set/010-log/091-2-log-HEAD-format-custom.json | 2 +- apps/tests/main-set/010-log/091-log-B..K-format-unknown.json | 2 +- apps/tests/main-set/010-log/092-log-help.json | 2 +- apps/tests/main-set/010-log/093-log-two-HEADs.json | 2 +- apps/tests/main-set/010-log/094-log-123456789.json | 2 +- apps/tests/main-set/010-log/095-log-try-non-report.json | 2 +- apps/tests/main-set/011-refs/095-branch-no-args.json | 2 +- apps/tests/main-set/011-refs/096-tag-no-args.json | 2 +- apps/tests/main-set/011-refs/097-branch-help.json | 2 +- apps/tests/main-set/011-refs/098-tag-help.json | 2 +- apps/tests/main-set/011-refs/099-branch-list.json | 2 +- apps/tests/main-set/011-refs/100-branch-list-color.json | 2 +- apps/tests/main-set/011-refs/101-tag-list.json | 2 +- apps/tests/main-set/011-refs/102-branch-current.json | 2 +- apps/tests/main-set/011-refs/103-branch-only-feat.json | 2 +- apps/tests/main-set/011-refs/104-branch-force-delete.json | 2 +- apps/tests/main-set/011-refs/105-branch-two-commands.json | 2 +- .../main-set/011-refs/106-A-branch-create-start-point.json | 2 +- .../011-refs/106-B-branch-create-invalid-start-point.json | 2 +- apps/tests/main-set/011-refs/106-branch-create.json | 2 +- apps/tests/main-set/011-refs/107-branch-create-forced.json | 2 +- apps/tests/main-set/011-refs/108-branch-create-existing.json | 2 +- .../main-set/011-refs/109-branch-create-three-at-a-time.json | 2 +- apps/tests/main-set/011-refs/110-branch-create-unborn.json | 2 +- apps/tests/main-set/011-refs/111-branch-delete-nothing.json | 2 +- apps/tests/main-set/011-refs/112-branch-delete-main.json | 2 +- apps/tests/main-set/011-refs/113-branch-delete-other.json | 2 +- .../main-set/011-refs/114-branch-delete-nonexisting.json | 2 +- apps/tests/main-set/011-refs/115-tag-create.json | 2 +- apps/tests/main-set/011-refs/116-tag-create-forced.json | 2 +- apps/tests/main-set/011-refs/117-tag-create-existing.json | 2 +- .../main-set/011-refs/118-tag-create-three-at-a-time.json | 2 +- apps/tests/main-set/011-refs/119-tag-create-unborn.json | 2 +- apps/tests/main-set/011-refs/120-tag-delete-tag.json | 2 +- apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json | 2 +- apps/tests/main-set/011-refs/122-branch-create-invalid.json | 2 +- apps/tests/main-set/011-refs/123-tag-create-invalid.json | 2 +- apps/tests/main-set/011-refs/124-branch-list-detached.json | 2 +- apps/tests/main-set/012-checkout/125-checkout-no-args.json | 2 +- apps/tests/main-set/012-checkout/126-checkout-no-cov.json | 2 +- apps/tests/main-set/012-checkout/127-checkout-help.json | 2 +- apps/tests/main-set/012-checkout/128-checkout-two-names.json | 2 +- .../012-checkout/129-checkout-too-many-for-branching.json | 2 +- .../012-checkout/130-checkout-too-little-for-branching.json | 2 +- .../main-set/012-checkout/131-checkout-two-commands.json | 2 +- apps/tests/main-set/012-checkout/132-checkout-branch.json | 2 +- apps/tests/main-set/012-checkout/133-checkout-orphan.json | 2 +- .../main-set/012-checkout/134-checkout-orphan-main.json | 2 +- .../012-checkout/135-checkout-orphan-invalid-spec.json | 2 +- apps/tests/main-set/012-checkout/136-checkout-existing.json | 2 +- apps/tests/main-set/012-checkout/137-checkout-tag.json | 2 +- .../main-set/012-checkout/138-checkout-without-HEAD.json | 2 +- .../main-set/012-checkout/139-checkout-start-point.json | 2 +- apps/tests/main-set/013-reset/140-reset-help.json | 2 +- apps/tests/main-set/013-reset/141-reset-no-args.json | 2 +- apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json | 2 +- apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json | 2 +- .../main-set/013-reset/144-reset-switch-detached-HEAD.json | 2 +- apps/tests/main-set/014-show/145-show-help.json | 2 +- apps/tests/main-set/014-show/146-show-no-args-unborn.json | 2 +- apps/tests/main-set/014-show/147-show-no-args.json | 2 +- apps/tests/main-set/014-show/148-show-no-args-module.json | 2 +- apps/tests/main-set/014-show/149-show-directory.json | 2 +- apps/tests/main-set/014-show/150-A-show-file.json | 2 +- apps/tests/main-set/014-show/150-B-show-file-color.json | 2 +- .../tests/main-set/014-show/150-C-show-file-many-chunks.json | 2 +- apps/tests/main-set/014-show/151-show-module.json | 2 +- apps/tests/main-set/014-show/152-show-range.json | 2 +- apps/tests/main-set/014-show/153-show-not-a-covmodule.json | 2 +- apps/tests/main-set/014-show/154-show-HEAD..HEAD.json | 2 +- apps/tests/main-set/014-show/155-show-module-props.json | 2 +- .../main-set/014-show/156-show-module-props-colors.json | 2 +- .../014-show/157-show-module-props-colors-empty.json | 2 +- apps/tests/main-set/014-show/158-show-functions.json | 2 +- apps/tests/main-set/014-show/159-show-functions-log.json | 2 +- apps/tests/main-set/014-show/160-show-functions-log.json | 2 +- apps/tests/main-set/014-show/161-show-no-chunks.json | 2 +- .../main-set/014-show/162-show-module-props-indented.json | 2 +- apps/tests/main-set/014-show/163-show-file-in-build.json | 2 +- apps/tests/main-set/014-show/163-show-file-in-files.json | 2 +- apps/tests/main-set/015-filters-A/01-strip-excludes.json | 2 +- .../tests/main-set/015-filters-A/02-strip-excludes-osOS.json | 2 +- .../main-set/015-filters-A/03-A-strip-excludes-llvm.json | 2 +- .../main-set/015-filters-A/03-B-strip-excludes-clang.json | 2 +- .../015-filters-A/04-strip-excludes-compilerA-OS.json | 2 +- .../main-set/015-filters-A/05-strip-excludes-multi.json | 2 +- .../main-set/015-filters-A/06-strip-excludes-no-such.json | 2 +- .../main-set/015-filters-A/07-A-strip-excludes-broken.json | 2 +- .../main-set/015-filters-A/07-B-strip-excludes-broken.json | 2 +- .../main-set/015-filters-A/07-C-strip-excludes-broken.json | 2 +- .../main-set/015-filters-A/07-C-strip-excludes-brokenjson | 2 +- apps/tests/main-set/016-collect/01-collect-help.json | 2 +- apps/tests/main-set/016-collect/02-collect-unborn.json | 2 +- apps/tests/main-set/016-collect/03-collect-no-HEAD.json | 2 +- .../tests/main-set/016-collect/04-collect-too-many-args.json | 2 +- .../main-set/016-collect/05-collect-too-little-args.json | 2 +- apps/tests/main-set/016-collect/06-collect-observe.json | 5 ++++- apps/tests/main-set/016-collect/07-collect-clang.json | 2 +- apps/tests/main-set/016-collect/08-collect-gcc.json | 2 +- apps/tests/main-set/016-collect/09-collect-gcc-triple.json | 2 +- apps/tests/main-set/016-collect/10-collect-clean.json | 2 +- apps/tests/main-set/016-collect/11-collect-no-output.json | 2 +- apps/tests/main-set/016-collect/12-collect-msvc.json | 2 +- 198 files changed, 202 insertions(+), 198 deletions(-) diff --git a/apps/tests/main-set/001-cov/001-version.json b/apps/tests/main-set/001-cov/001-version.json index a62883df..4d76fd89 100644 --- a/apps/tests/main-set/001-cov/001-version.json +++ b/apps/tests/main-set/001-cov/001-version.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "--version", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/002-help.json b/apps/tests/main-set/001-cov/002-help.json index dd8cd8cd..5dca87d4 100644 --- a/apps/tests/main-set/001-cov/002-help.json +++ b/apps/tests/main-set/001-cov/002-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "--help", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/003-unknown-option.json b/apps/tests/main-set/001-cov/003-unknown-option.json index 2a81a3fa..1129451f 100644 --- a/apps/tests/main-set/001-cov/003-unknown-option.json +++ b/apps/tests/main-set/001-cov/003-unknown-option.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "--versions", "expected": [ 2, diff --git a/apps/tests/main-set/001-cov/004-alias.json b/apps/tests/main-set/001-cov/004-alias.json index c8a07eac..34794a4d 100644 --- a/apps/tests/main-set/001-cov/004-alias.json +++ b/apps/tests/main-set/001-cov/004-alias.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C recurse first -D", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/005-alias-short-help.json b/apps/tests/main-set/001-cov/005-alias-short-help.json index 8890e6b3..3e8ae39c 100644 --- a/apps/tests/main-set/001-cov/005-alias-short-help.json +++ b/apps/tests/main-set/001-cov/005-alias-short-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C recurse second -h", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/006-alias-long-help.json b/apps/tests/main-set/001-cov/006-alias-long-help.json index 1ab593a3..db02145a 100644 --- a/apps/tests/main-set/001-cov/006-alias-long-help.json +++ b/apps/tests/main-set/001-cov/006-alias-long-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C recurse second --not-help --help", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/007-alias-to-nothing.json b/apps/tests/main-set/001-cov/007-alias-to-nothing.json index 13f51280..aa03e781 100644 --- a/apps/tests/main-set/001-cov/007-alias-to-nothing.json +++ b/apps/tests/main-set/001-cov/007-alias-to-nothing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C bad-recurse start-bad", "expected": [ 22, diff --git a/apps/tests/main-set/001-cov/008-bad-alias.json b/apps/tests/main-set/001-cov/008-bad-alias.json index 901bf202..8983fa26 100644 --- a/apps/tests/main-set/001-cov/008-bad-alias.json +++ b/apps/tests/main-set/001-cov/008-bad-alias.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C bad-recurse first -D", "check": {"stderr": "begin"}, "expected": [ diff --git a/apps/tests/main-set/001-cov/009-external-tool.json b/apps/tests/main-set/001-cov/009-external-tool.json index 54b1deca..946667df 100644 --- a/apps/tests/main-set/001-cov/009-external-tool.json +++ b/apps/tests/main-set/001-cov/009-external-tool.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "echo arg1 arg2 ...", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/010-escaped-arguments.json b/apps/tests/main-set/001-cov/010-escaped-arguments.json index 4f5930b6..a9ed897b 100644 --- a/apps/tests/main-set/001-cov/010-escaped-arguments.json +++ b/apps/tests/main-set/001-cov/010-escaped-arguments.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "echo 'argument with space' 'argument with \\ backslash' 'argument with \"quotes\"' 'argument with '\"'\"'apos'\"'\"'' 'this thing: \\\"' 'that thing: \\\\'", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/011-multiple-aliases.json b/apps/tests/main-set/001-cov/011-multiple-aliases.json index cfa5c908..10bd7988 100644 --- a/apps/tests/main-set/001-cov/011-multiple-aliases.json +++ b/apps/tests/main-set/001-cov/011-multiple-aliases.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C recurse name", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/012-list-cmds.json b/apps/tests/main-set/001-cov/012-list-cmds.json index 437a1eb6..e001880a 100644 --- a/apps/tests/main-set/001-cov/012-list-cmds.json +++ b/apps/tests/main-set/001-cov/012-list-cmds.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": null, "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/001-cov/013-bad-alias-full-output.json b/apps/tests/main-set/001-cov/013-bad-alias-full-output.json index ac33dbcf..1924339d 100644 --- a/apps/tests/main-set/001-cov/013-bad-alias-full-output.json +++ b/apps/tests/main-set/001-cov/013-bad-alias-full-output.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "definitely-not-a-tool", "expected": [ 1, diff --git a/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json b/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json index 955e1a21..14503997 100644 --- a/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json +++ b/apps/tests/main-set/001-cov/014-echo-with-nonascii-arguments.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C 'utf8-αβγδε' first '--hjälp'", "expected": [ 0, diff --git a/apps/tests/main-set/001-cov/015-bad-alias-with-env.json b/apps/tests/main-set/001-cov/015-bad-alias-with-env.json index ef96777e..f896fcc5 100644 --- a/apps/tests/main-set/001-cov/015-bad-alias-with-env.json +++ b/apps/tests/main-set/001-cov/015-bad-alias-with-env.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "-C bad-recurse first -D", "env": {"COV_PATH": [ "$TMP", diff --git a/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json b/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json index 1f395f3e..531aed56 100644 --- a/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json +++ b/apps/tests/main-set/001-cov/016-external-tool-outside-libexec.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "pwd", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/015-init-no-args.json b/apps/tests/main-set/002-init/015-init-no-args.json index b53ea1e5..3d07de45 100644 --- a/apps/tests/main-set/002-init/015-init-no-args.json +++ b/apps/tests/main-set/002-init/015-init-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/016-init-git-dir.json b/apps/tests/main-set/002-init/016-init-git-dir.json index a0929165..37fd171b 100644 --- a/apps/tests/main-set/002-init/016-init-git-dir.json +++ b/apps/tests/main-set/002-init/016-init-git-dir.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --git-dir '$TMP'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/017-init-directory.json b/apps/tests/main-set/002-init/017-init-directory.json index 447cc956..ef44f771 100644 --- a/apps/tests/main-set/002-init/017-init-directory.json +++ b/apps/tests/main-set/002-init/017-init-directory.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init '$TMP/subdir'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/018-init-dependent.json b/apps/tests/main-set/002-init/018-init-dependent.json index 663b7106..62a0d879 100644 --- a/apps/tests/main-set/002-init/018-init-dependent.json +++ b/apps/tests/main-set/002-init/018-init-dependent.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --git-dir '$TMP' '$TMP/subdir'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/019-init-independent.json b/apps/tests/main-set/002-init/019-init-independent.json index 949ba272..1fe971b6 100644 --- a/apps/tests/main-set/002-init/019-init-independent.json +++ b/apps/tests/main-set/002-init/019-init-independent.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --git-dir '$TMP/repo.git' '$TMP/repo.covdata'", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/020-init-no-gitrepo.json b/apps/tests/main-set/002-init/020-init-no-gitrepo.json index 5395a489..23cffec3 100644 --- a/apps/tests/main-set/002-init/020-init-no-gitrepo.json +++ b/apps/tests/main-set/002-init/020-init-no-gitrepo.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --git-dir '$TMP/repo.git' '$TMP/repo.covdata'", "expected": [ 2, diff --git a/apps/tests/main-set/002-init/022-init-git-dir-relative.json b/apps/tests/main-set/002-init/022-init-git-dir-relative.json index 99eb87a5..1483d254 100644 --- a/apps/tests/main-set/002-init/022-init-git-dir-relative.json +++ b/apps/tests/main-set/002-init/022-init-git-dir-relative.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --git-dir ../.git", "expected": [ 0, diff --git a/apps/tests/main-set/002-init/023-init-no-force.json b/apps/tests/main-set/002-init/023-init-no-force.json index b6f46f5a..74243c45 100644 --- a/apps/tests/main-set/002-init/023-init-no-force.json +++ b/apps/tests/main-set/002-init/023-init-no-force.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init", "expected": [ 1, diff --git a/apps/tests/main-set/002-init/024-init-force.json b/apps/tests/main-set/002-init/024-init-force.json index 392b78db..265a7d8b 100644 --- a/apps/tests/main-set/002-init/024-init-force.json +++ b/apps/tests/main-set/002-init/024-init-force.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "init --force", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/025-config-no-args.json b/apps/tests/main-set/003-config-A/025-config-no-args.json index 8e1ed9b9..7dc1f144 100644 --- a/apps/tests/main-set/003-config-A/025-config-no-args.json +++ b/apps/tests/main-set/003-config-A/025-config-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/026-config-list-local.json b/apps/tests/main-set/003-config-A/026-config-list-local.json index 9d4b8040..e25281e7 100644 --- a/apps/tests/main-set/003-config-A/026-config-list-local.json +++ b/apps/tests/main-set/003-config-A/026-config-list-local.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --local --list", "expected": [ 0, diff --git a/apps/tests/main-set/003-config-A/027-config-list-global.json b/apps/tests/main-set/003-config-A/027-config-list-global.json index 6f699794..413f7ff6 100644 --- a/apps/tests/main-set/003-config-A/027-config-list-global.json +++ b/apps/tests/main-set/003-config-A/027-config-list-global.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/003-config-A/028-config-list-system.json b/apps/tests/main-set/003-config-A/028-config-list-system.json index 3cad9f5f..69817bde 100644 --- a/apps/tests/main-set/003-config-A/028-config-list-system.json +++ b/apps/tests/main-set/003-config-A/028-config-list-system.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/003-config-A/029-config-list-file.json b/apps/tests/main-set/003-config-A/029-config-list-file.json index 21ef43fb..cae4ca31 100644 --- a/apps/tests/main-set/003-config-A/029-config-list-file.json +++ b/apps/tests/main-set/003-config-A/029-config-list-file.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config -f '$TMP/some.file' --list", "expected": [ 0, diff --git a/apps/tests/main-set/004-config-B/030-config-list-any.json b/apps/tests/main-set/004-config-B/030-config-list-any.json index 4a91637c..76d3fb6a 100644 --- a/apps/tests/main-set/004-config-B/030-config-list-any.json +++ b/apps/tests/main-set/004-config-B/030-config-list-any.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/031-config-list-after-get.json b/apps/tests/main-set/004-config-B/031-config-list-after-get.json index 1940fff7..a1b6f9ad 100644 --- a/apps/tests/main-set/004-config-B/031-config-list-after-get.json +++ b/apps/tests/main-set/004-config-B/031-config-list-after-get.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/032-config-unset-after-list.json b/apps/tests/main-set/004-config-B/032-config-unset-after-list.json index df622918..2eb47d1e 100644 --- a/apps/tests/main-set/004-config-B/032-config-unset-after-list.json +++ b/apps/tests/main-set/004-config-B/032-config-unset-after-list.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json b/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json index ff5e8347..ab32f794 100644 --- a/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json +++ b/apps/tests/main-set/004-config-B/033-config-add-after-unset-all.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json b/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json index dc8fc5fd..6844e17b 100644 --- a/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json +++ b/apps/tests/main-set/004-config-B/034-config-get-all-after-get.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "env": { "HOME": "$TMP/home", "XDG_CONFIG_HOME": null, diff --git a/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json b/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json index d3d8ea16..19a056c8 100644 --- a/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json +++ b/apps/tests/main-set/004-config-B/035-config-list-local-no-cov.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --local --list", "expected": [ 2, diff --git a/apps/tests/main-set/004-config-B/036-config-add-one-arg.json b/apps/tests/main-set/004-config-B/036-config-add-one-arg.json index 7b69d96e..4b76ef69 100644 --- a/apps/tests/main-set/004-config-B/036-config-add-one-arg.json +++ b/apps/tests/main-set/004-config-B/036-config-add-one-arg.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --add group.key", "expected": [ 2, diff --git a/apps/tests/main-set/004-config-B/037-config-unset-too-many.json b/apps/tests/main-set/004-config-B/037-config-unset-too-many.json index d9d6aca4..29f5a47d 100644 --- a/apps/tests/main-set/004-config-B/037-config-unset-too-many.json +++ b/apps/tests/main-set/004-config-B/037-config-unset-too-many.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --unset group.key value", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json index b6cb8007..d9ab571b 100644 --- a/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json +++ b/apps/tests/main-set/005-config-C/038-config-set-but-multivar.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/039-config-set-but-include.json b/apps/tests/main-set/005-config-C/039-config-set-but-include.json index 059baf8e..0abb9a72 100644 --- a/apps/tests/main-set/005-config-C/039-config-set-but-include.json +++ b/apps/tests/main-set/005-config-C/039-config-set-but-include.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config group.key 'value 3'", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json index 143ce636..84860c80 100644 --- a/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json +++ b/apps/tests/main-set/005-config-C/040-config-unset-but-multivar.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --unset group.key", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json index 971a7dd2..944eb612 100644 --- a/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json +++ b/apps/tests/main-set/005-config-C/041-config-unset-but-not-there.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --unset group.other", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json index e8e3f68b..641ea9b1 100644 --- a/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json +++ b/apps/tests/main-set/005-config-C/042-config-unset-but-no-a-key.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --unset group-other", "expected": [ 2, diff --git a/apps/tests/main-set/005-config-C/043-config-get.json b/apps/tests/main-set/005-config-C/043-config-get.json index d4c4c70a..c234a22e 100644 --- a/apps/tests/main-set/005-config-C/043-config-get.json +++ b/apps/tests/main-set/005-config-C/043-config-get.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config group.key", "expected": [0, "value 2\n", ""], "prepare": ["touch '$TMP/config' '[group]\nkey = value 1\nkey = value 2'"] diff --git a/apps/tests/main-set/005-config-C/044-config-get-all.json b/apps/tests/main-set/005-config-C/044-config-get-all.json index fb09f500..bb8655f2 100644 --- a/apps/tests/main-set/005-config-C/044-config-get-all.json +++ b/apps/tests/main-set/005-config-C/044-config-get-all.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --get-all group.key", "expected": [ 0, diff --git a/apps/tests/main-set/005-config-C/045-config-add.json b/apps/tests/main-set/005-config-C/045-config-add.json index 6fabd3ff..1c084c3a 100644 --- a/apps/tests/main-set/005-config-C/045-config-add.json +++ b/apps/tests/main-set/005-config-C/045-config-add.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --get-all group.key", "expected": [ 0, diff --git a/apps/tests/main-set/005-config-C/046-config-unset-all.json b/apps/tests/main-set/005-config-C/046-config-unset-all.json index eeca0ad6..fd5108c7 100644 --- a/apps/tests/main-set/005-config-C/046-config-unset-all.json +++ b/apps/tests/main-set/005-config-C/046-config-unset-all.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "config --file $TMP/config --list", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/047-module-help.json b/apps/tests/main-set/006-module-A/047-module-help.json index 994d7985..b3989694 100644 --- a/apps/tests/main-set/006-module-A/047-module-help.json +++ b/apps/tests/main-set/006-module-A/047-module-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --help", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/048-module-build-and-print.json b/apps/tests/main-set/006-module-A/048-module-build-and-print.json index ad900dd2..4f961e84 100644 --- a/apps/tests/main-set/006-module-A/048-module-build-and-print.json +++ b/apps/tests/main-set/006-module-A/048-module-build-and-print.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json b/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json index 0076fe17..a1b1b3d2 100644 --- a/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json +++ b/apps/tests/main-set/006-module-A/049-module-build-and-print-sep.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --show-sep", "expected": [0, " :: \n", ""], "prepare": [ diff --git a/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json b/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json index 915b752c..49d2b953 100644 --- a/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json +++ b/apps/tests/main-set/006-module-A/050-module-deconstruct-and-print.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module", "expected": [ 0, diff --git a/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json b/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json index ac20be96..5534de1e 100644 --- a/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json +++ b/apps/tests/main-set/006-module-A/051-module-modify-in-bare-git.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --remove-all \"doesn't matter\"", "expected": [ 2, diff --git a/apps/tests/main-set/006-module-A/052-module-add-duplicate.json b/apps/tests/main-set/006-module-A/052-module-add-duplicate.json index 9d6f3f05..61af1a77 100644 --- a/apps/tests/main-set/006-module-A/052-module-add-duplicate.json +++ b/apps/tests/main-set/006-module-A/052-module-add-duplicate.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --add module 'dir 1'", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json b/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json index 625276d7..aea193fd 100644 --- a/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json +++ b/apps/tests/main-set/007-module-B/053-module-remove-from-nothing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --remove some-name 'dir 1'", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json b/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json index ed085bfd..1bddc48a 100644 --- a/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json +++ b/apps/tests/main-set/007-module-B/054-module-print-from-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module HEAD", "expected": [ 0, diff --git a/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json b/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json index 8a196a57..82520a87 100644 --- a/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json +++ b/apps/tests/main-set/007-module-B/055-module-print-sep-from-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --show-sep HEAD", "expected": [0, "::\n", ""], "prepare": [ diff --git a/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json b/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json index 56b9451c..a47912c3 100644 --- a/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json +++ b/apps/tests/main-set/007-module-B/056-module-open_from_ref-range.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module v1.0.0..HEAD", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json b/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json index 653e5281..a831880b 100644 --- a/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json +++ b/apps/tests/main-set/007-module-B/057-module-open_from_ref-tree.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module 2559ccfa6", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/058-module-no-git.json b/apps/tests/main-set/007-module-B/058-module-no-git.json index 3d3fc081..ad90fcaf 100644 --- a/apps/tests/main-set/007-module-B/058-module-no-git.json +++ b/apps/tests/main-set/007-module-B/058-module-no-git.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/059-module-excl-show.json b/apps/tests/main-set/007-module-B/059-module-excl-show.json index dbf77386..70e9ae1a 100644 --- a/apps/tests/main-set/007-module-B/059-module-excl-show.json +++ b/apps/tests/main-set/007-module-B/059-module-excl-show.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module HEAD --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json b/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json index b34e7a3e..f64934ba 100644 --- a/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json +++ b/apps/tests/main-set/007-module-B/060-module-excl-show-sep.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --show-sep --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/061-module-too-many-refs.json b/apps/tests/main-set/007-module-B/061-module-too-many-refs.json index 8f5d6300..de8785cb 100644 --- a/apps/tests/main-set/007-module-B/061-module-too-many-refs.json +++ b/apps/tests/main-set/007-module-B/061-module-too-many-refs.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module HEAD ANOTHER_HEAD main v1.0.0", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/062-module-too-little-args.json b/apps/tests/main-set/007-module-B/062-module-too-little-args.json index 0a4abdc4..67b80eb7 100644 --- a/apps/tests/main-set/007-module-B/062-module-too-little-args.json +++ b/apps/tests/main-set/007-module-B/062-module-too-little-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --add module", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/062-module-too-many-args.json b/apps/tests/main-set/007-module-B/062-module-too-many-args.json index 44d13a91..def4a894 100644 --- a/apps/tests/main-set/007-module-B/062-module-too-many-args.json +++ b/apps/tests/main-set/007-module-B/062-module-too-many-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --remove-all module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/063-module-no-covmodule.json b/apps/tests/main-set/007-module-B/063-module-no-covmodule.json index ead98881..75e741be 100644 --- a/apps/tests/main-set/007-module-B/063-module-no-covmodule.json +++ b/apps/tests/main-set/007-module-B/063-module-no-covmodule.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json index 303d2b7d..1ad2ddaa 100644 --- a/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json +++ b/apps/tests/main-set/007-module-B/064-module-no-covmodule-add.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module --add module dir", "expected": [ 2, diff --git a/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json b/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json index b210c73d..d0bb69c5 100644 --- a/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json +++ b/apps/tests/main-set/007-module-B/065-module-open_from_ref-no-such-object.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "module nonexistent-ref", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/008-report-A/066-report-no-args.json b/apps/tests/main-set/008-report-A/066-report-no-args.json index e300f5f2..c68ebf9f 100644 --- a/apps/tests/main-set/008-report-A/066-report-no-args.json +++ b/apps/tests/main-set/008-report-A/066-report-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/067-report-help.json b/apps/tests/main-set/008-report-A/067-report-help.json index 43a0f0e9..46617db8 100644 --- a/apps/tests/main-set/008-report-A/067-report-help.json +++ b/apps/tests/main-set/008-report-A/067-report-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -h", "expected": [ 0, diff --git a/apps/tests/main-set/008-report-A/068-report-no-cov.json b/apps/tests/main-set/008-report-A/068-report-no-cov.json index 41efd184..d061f124 100644 --- a/apps/tests/main-set/008-report-A/068-report-no-cov.json +++ b/apps/tests/main-set/008-report-A/068-report-no-cov.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/basic-coverage.json", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/069-report-no-commit.json b/apps/tests/main-set/008-report-A/069-report-no-commit.json index f3998807..4a8c2487 100644 --- a/apps/tests/main-set/008-report-A/069-report-no-commit.json +++ b/apps/tests/main-set/008-report-A/069-report-no-commit.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/basic-coverage.json", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/070-report-failing-filter.json b/apps/tests/main-set/008-report-A/070-report-failing-filter.json index 906df327..5901629c 100644 --- a/apps/tests/main-set/008-report-A/070-report-failing-filter.json +++ b/apps/tests/main-set/008-report-A/070-report-failing-filter.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/basic-coverage.json -f echo-to-stderr", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/071-report-no-filter.json b/apps/tests/main-set/008-report-A/071-report-no-filter.json index c7b9f9a3..ad821610 100644 --- a/apps/tests/main-set/008-report-A/071-report-no-filter.json +++ b/apps/tests/main-set/008-report-A/071-report-no-filter.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/basic-coverage.json -f no-filter", "expected": [ 1, diff --git a/apps/tests/main-set/008-report-A/072-report-not-the-json.json b/apps/tests/main-set/008-report-A/072-report-not-the-json.json index 59180b65..4fa28d1a 100644 --- a/apps/tests/main-set/008-report-A/072-report-not-the-json.json +++ b/apps/tests/main-set/008-report-A/072-report-not-the-json.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/no-git-coverage.json", "expected": [ 2, diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index 8d171f92..37ac0d78 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -1,11 +1,12 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/no-git-coverage.json -f echo-to-stdout", "expected": [ 2, "", [ "cov report: /git: undefined", + "cov report: /files: undefined", "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter\n" ] ], diff --git a/apps/tests/main-set/009-report-B/074-report-no-file.json b/apps/tests/main-set/009-report-B/074-report-no-file.json index c412a7f7..165d71cd 100644 --- a/apps/tests/main-set/009-report-B/074-report-no-file.json +++ b/apps/tests/main-set/009-report-B/074-report-no-file.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/basic-coverage.json -f replace-head", "expected": [ 1, diff --git a/apps/tests/main-set/009-report-B/075-report-empty.json b/apps/tests/main-set/009-report-B/075-report-empty.json index e664ae35..454c2c0c 100644 --- a/apps/tests/main-set/009-report-B/075-report-empty.json +++ b/apps/tests/main-set/009-report-B/075-report-empty.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/empty-coverage.json -f replace-head", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/076-report-one-file.json b/apps/tests/main-set/009-report-B/076-report-one-file.json index 40297e22..eacce6e2 100644 --- a/apps/tests/main-set/009-report-B/076-report-one-file.json +++ b/apps/tests/main-set/009-report-B/076-report-one-file.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json index cf4df439..87b638a0 100644 --- a/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json +++ b/apps/tests/main-set/009-report-B/077-report-amend-on-empty.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report --amend", "expected": [ 2, diff --git a/apps/tests/main-set/009-report-B/078-D-report-with-props.json b/apps/tests/main-set/009-report-B/078-D-report-with-props.json index b3740d36..280c6435 100644 --- a/apps/tests/main-set/009-report-B/078-D-report-with-props.json +++ b/apps/tests/main-set/009-report-B/078-D-report-with-props.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report -pos=qnx -pdebug=false -pcompiler=javac", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json b/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json index f2c3ba21..12b32df7 100644 --- a/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json +++ b/apps/tests/main-set/009-report-B/078-report-amend-on-parentless.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report --amend", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json b/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json index 8edc3333..a4dfb349 100644 --- a/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json +++ b/apps/tests/main-set/009-report-B/079-B-report-the-same-twice.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage.json -f create-report", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json b/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json index 321ed12e..c7cd0e56 100644 --- a/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json +++ b/apps/tests/main-set/009-report-B/079-C-report-almost-the-same-twice.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage-same-stats-diff-visits.json -f create-report", "expected": [ 0, diff --git a/apps/tests/main-set/009-report-B/079-report-with-parent.json b/apps/tests/main-set/009-report-B/079-report-with-parent.json index 65d6be5e..b8998ee4 100644 --- a/apps/tests/main-set/009-report-B/079-report-with-parent.json +++ b/apps/tests/main-set/009-report-B/079-report-with-parent.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f create-report", "patches": { "\u001b\\[0;49;90m\\[master [0-9a-fA-F]+\\] reported files\u001b\\[m": "\u001b[0;49;90m[master $COMMIT] reported files\u001b[m", diff --git a/apps/tests/main-set/009-report-B/080-report-on-detached.json b/apps/tests/main-set/009-report-B/080-report-on-detached.json index c8432e39..f1c08679 100644 --- a/apps/tests/main-set/009-report-B/080-report-on-detached.json +++ b/apps/tests/main-set/009-report-B/080-report-on-detached.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f create-report", "patches": {"\u001b\\[0;49;90m\\[master [0-9a-fA-F]+\\] (.+)": "\u001b[0;49;90m[master $COMMIT] \\1"}, "expected": [ diff --git a/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json b/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json index 98f77f9d..3f76db65 100644 --- a/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json +++ b/apps/tests/main-set/009-report-B/081-report-hash-bang-less.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report $DATA/build-coverage-2-files.json -f hash-bang-less", "expected": [ 1, diff --git a/apps/tests/main-set/010-log/082-log-no-args.json b/apps/tests/main-set/010-log/082-log-no-args.json index cc0cc37f..db429304 100644 --- a/apps/tests/main-set/010-log/082-log-no-args.json +++ b/apps/tests/main-set/010-log/082-log-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/083-log-no-args-inited.json b/apps/tests/main-set/010-log/083-log-no-args-inited.json index e4f24a59..093771af 100644 --- a/apps/tests/main-set/010-log/083-log-no-args-inited.json +++ b/apps/tests/main-set/010-log/083-log-no-args-inited.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/084-log-no-args-Dmain.json b/apps/tests/main-set/010-log/084-log-no-args-Dmain.json index 23946ac7..39658837 100644 --- a/apps/tests/main-set/010-log/084-log-no-args-Dmain.json +++ b/apps/tests/main-set/010-log/084-log-no-args-Dmain.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log", "check": {"stderr": "begin"}, "expected": [ diff --git a/apps/tests/main-set/010-log/085-log-G..K-oneline.json b/apps/tests/main-set/010-log/085-log-G..K-oneline.json index abbeaace..ccded4b1 100644 --- a/apps/tests/main-set/010-log/085-log-G..K-oneline.json +++ b/apps/tests/main-set/010-log/085-log-G..K-oneline.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --oneline G..K", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json b/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json index 0e16412c..fb5425c2 100644 --- a/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json +++ b/apps/tests/main-set/010-log/086-log-separate-raw-decorate.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --format=raw --decorate=short cov-separate", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json b/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json index d6365699..c98d58e4 100644 --- a/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json +++ b/apps/tests/main-set/010-log/087-log-feat3-fuller-decorate.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --format=fuller --decorate=short feat/cov-3", "check": {"stderr": "begin"}, "expected": [ diff --git a/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json b/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json index 4d2e41cc..f808d38c 100644 --- a/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json +++ b/apps/tests/main-set/010-log/088-log-G..K-oneline-color.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --oneline --color always --decorate short G..K", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json b/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json index 17f5cc81..327ac7b7 100644 --- a/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json +++ b/apps/tests/main-set/010-log/089-log-B..K-format-pretty.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log '--format=pretty:%C(yellow)%hR%Creset (%s, %rs) %C(red)%hG@%rD%Creset' --color always --decorate short Q..M", "check": {"stderr": "begin"}, "expected": [ diff --git a/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json b/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json index 763aca5f..3a3b9f00 100644 --- a/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json +++ b/apps/tests/main-set/010-log/090-log-B..K-no-format-but-pretty.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log '--format=%C(yellow)%hR%Creset (%s, %rs) %C(red)%hG@%rD%Creset' --color always --decorate short Q..M", "check": {"stderr": "begin"}, "expected": [ diff --git a/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json b/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json index 8a9b8a27..6536cb7b 100644 --- a/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json +++ b/apps/tests/main-set/010-log/091-2-log-HEAD-format-custom.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log '--format= - %mD(4)' --color always --decorate short", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json b/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json index 1af3065a..9563293a 100644 --- a/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json +++ b/apps/tests/main-set/010-log/091-log-B..K-format-unknown.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --format=unknown --color always --decorate short Q..M", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/092-log-help.json b/apps/tests/main-set/010-log/092-log-help.json index 688ccf68..7ecaf437 100644 --- a/apps/tests/main-set/010-log/092-log-help.json +++ b/apps/tests/main-set/010-log/092-log-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log --help", "expected": [ 0, diff --git a/apps/tests/main-set/010-log/093-log-two-HEADs.json b/apps/tests/main-set/010-log/093-log-two-HEADs.json index 1575f400..38dc84ed 100644 --- a/apps/tests/main-set/010-log/093-log-two-HEADs.json +++ b/apps/tests/main-set/010-log/093-log-two-HEADs.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log ..", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/094-log-123456789.json b/apps/tests/main-set/010-log/094-log-123456789.json index 091e5ef6..6eb5f166 100644 --- a/apps/tests/main-set/010-log/094-log-123456789.json +++ b/apps/tests/main-set/010-log/094-log-123456789.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log 123456789", "expected": [ 2, diff --git a/apps/tests/main-set/010-log/095-log-try-non-report.json b/apps/tests/main-set/010-log/095-log-try-non-report.json index 786f3ff9..2f539230 100644 --- a/apps/tests/main-set/010-log/095-log-try-non-report.json +++ b/apps/tests/main-set/010-log/095-log-try-non-report.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "log $BUILD --prop-names --decorate short", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/095-branch-no-args.json b/apps/tests/main-set/011-refs/095-branch-no-args.json index b7dfd9ca..661e4464 100644 --- a/apps/tests/main-set/011-refs/095-branch-no-args.json +++ b/apps/tests/main-set/011-refs/095-branch-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/096-tag-no-args.json b/apps/tests/main-set/011-refs/096-tag-no-args.json index 3ddd669a..27c269e1 100644 --- a/apps/tests/main-set/011-refs/096-tag-no-args.json +++ b/apps/tests/main-set/011-refs/096-tag-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/097-branch-help.json b/apps/tests/main-set/011-refs/097-branch-help.json index 6bc429c0..37d19fa0 100644 --- a/apps/tests/main-set/011-refs/097-branch-help.json +++ b/apps/tests/main-set/011-refs/097-branch-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --help", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/098-tag-help.json b/apps/tests/main-set/011-refs/098-tag-help.json index 9c637b4f..f093a8aa 100644 --- a/apps/tests/main-set/011-refs/098-tag-help.json +++ b/apps/tests/main-set/011-refs/098-tag-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag --help", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/099-branch-list.json b/apps/tests/main-set/011-refs/099-branch-list.json index 016833d5..f35601cf 100644 --- a/apps/tests/main-set/011-refs/099-branch-list.json +++ b/apps/tests/main-set/011-refs/099-branch-list.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/100-branch-list-color.json b/apps/tests/main-set/011-refs/100-branch-list-color.json index 284e71dc..dcc9eb63 100644 --- a/apps/tests/main-set/011-refs/100-branch-list-color.json +++ b/apps/tests/main-set/011-refs/100-branch-list-color.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --color=always", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/101-tag-list.json b/apps/tests/main-set/011-refs/101-tag-list.json index 5c35231d..07bc3fd9 100644 --- a/apps/tests/main-set/011-refs/101-tag-list.json +++ b/apps/tests/main-set/011-refs/101-tag-list.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/102-branch-current.json b/apps/tests/main-set/011-refs/102-branch-current.json index e1290279..5846917c 100644 --- a/apps/tests/main-set/011-refs/102-branch-current.json +++ b/apps/tests/main-set/011-refs/102-branch-current.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --show-current", "expected": [0, "main\n", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/103-branch-only-feat.json b/apps/tests/main-set/011-refs/103-branch-only-feat.json index 54f098f1..31e131b4 100644 --- a/apps/tests/main-set/011-refs/103-branch-only-feat.json +++ b/apps/tests/main-set/011-refs/103-branch-only-feat.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch -l feat/cov-*", "expected": [ 0, diff --git a/apps/tests/main-set/011-refs/104-branch-force-delete.json b/apps/tests/main-set/011-refs/104-branch-force-delete.json index 857ee429..c3bdce3a 100644 --- a/apps/tests/main-set/011-refs/104-branch-force-delete.json +++ b/apps/tests/main-set/011-refs/104-branch-force-delete.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --delete main --force", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/105-branch-two-commands.json b/apps/tests/main-set/011-refs/105-branch-two-commands.json index 2483cc2f..40e562df 100644 --- a/apps/tests/main-set/011-refs/105-branch-two-commands.json +++ b/apps/tests/main-set/011-refs/105-branch-two-commands.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --show-current -l feat/cov-*", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json b/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json index 20620f9c..1a06b092 100644 --- a/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json +++ b/apps/tests/main-set/011-refs/106-A-branch-create-start-point.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch feat/cov-4 G~2", "post": "log --oneline -n1", "expected": [ diff --git a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json index 110b9527..3e8d7c41 100644 --- a/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json +++ b/apps/tests/main-set/011-refs/106-B-branch-create-invalid-start-point.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch feat/cov-4 non-existing", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/106-branch-create.json b/apps/tests/main-set/011-refs/106-branch-create.json index 4a713a73..86cfc17b 100644 --- a/apps/tests/main-set/011-refs/106-branch-create.json +++ b/apps/tests/main-set/011-refs/106-branch-create.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch feat/cov-4", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/107-branch-create-forced.json b/apps/tests/main-set/011-refs/107-branch-create-forced.json index 6a6b1ede..ba1a85c2 100644 --- a/apps/tests/main-set/011-refs/107-branch-create-forced.json +++ b/apps/tests/main-set/011-refs/107-branch-create-forced.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch cov-separate --force", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/108-branch-create-existing.json b/apps/tests/main-set/011-refs/108-branch-create-existing.json index adce3f3a..7e6af3a5 100644 --- a/apps/tests/main-set/011-refs/108-branch-create-existing.json +++ b/apps/tests/main-set/011-refs/108-branch-create-existing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch cov-separate", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json b/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json index 09474296..9ec65951 100644 --- a/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json +++ b/apps/tests/main-set/011-refs/109-branch-create-three-at-a-time.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch branch-1 branch-2 branch-3", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/110-branch-create-unborn.json b/apps/tests/main-set/011-refs/110-branch-create-unborn.json index f06bb7f8..02b3daef 100644 --- a/apps/tests/main-set/011-refs/110-branch-create-unborn.json +++ b/apps/tests/main-set/011-refs/110-branch-create-unborn.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch name", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/111-branch-delete-nothing.json b/apps/tests/main-set/011-refs/111-branch-delete-nothing.json index 4047b714..213447da 100644 --- a/apps/tests/main-set/011-refs/111-branch-delete-nothing.json +++ b/apps/tests/main-set/011-refs/111-branch-delete-nothing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch --delete", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/112-branch-delete-main.json b/apps/tests/main-set/011-refs/112-branch-delete-main.json index d3242f01..c65f4ae0 100644 --- a/apps/tests/main-set/011-refs/112-branch-delete-main.json +++ b/apps/tests/main-set/011-refs/112-branch-delete-main.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch -d main", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/113-branch-delete-other.json b/apps/tests/main-set/011-refs/113-branch-delete-other.json index e2564874..98e2fff2 100644 --- a/apps/tests/main-set/011-refs/113-branch-delete-other.json +++ b/apps/tests/main-set/011-refs/113-branch-delete-other.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch -d feat/cov-2", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json index 9da7b863..d613f77c 100644 --- a/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/114-branch-delete-nonexisting.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch -d feat/cov-22", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/115-tag-create.json b/apps/tests/main-set/011-refs/115-tag-create.json index 98635025..4c3d1fdc 100644 --- a/apps/tests/main-set/011-refs/115-tag-create.json +++ b/apps/tests/main-set/011-refs/115-tag-create.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag feat/cov-4", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/116-tag-create-forced.json b/apps/tests/main-set/011-refs/116-tag-create-forced.json index 5073490c..4a993659 100644 --- a/apps/tests/main-set/011-refs/116-tag-create-forced.json +++ b/apps/tests/main-set/011-refs/116-tag-create-forced.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag H --force", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/117-tag-create-existing.json b/apps/tests/main-set/011-refs/117-tag-create-existing.json index ffd034ad..0eba1b98 100644 --- a/apps/tests/main-set/011-refs/117-tag-create-existing.json +++ b/apps/tests/main-set/011-refs/117-tag-create-existing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag H", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json b/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json index 6701938f..82dfc821 100644 --- a/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json +++ b/apps/tests/main-set/011-refs/118-tag-create-three-at-a-time.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag tag-1 tag-2 tag-3", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/119-tag-create-unborn.json b/apps/tests/main-set/011-refs/119-tag-create-unborn.json index 1640f5a7..259e7b1f 100644 --- a/apps/tests/main-set/011-refs/119-tag-create-unborn.json +++ b/apps/tests/main-set/011-refs/119-tag-create-unborn.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag name", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/120-tag-delete-tag.json b/apps/tests/main-set/011-refs/120-tag-delete-tag.json index 3a10aa0e..56fe3f78 100644 --- a/apps/tests/main-set/011-refs/120-tag-delete-tag.json +++ b/apps/tests/main-set/011-refs/120-tag-delete-tag.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag -d H", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json index 15705dc8..13431949 100644 --- a/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json +++ b/apps/tests/main-set/011-refs/121-tag-delete-nonexisting.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag -d nonexisting", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/122-branch-create-invalid.json b/apps/tests/main-set/011-refs/122-branch-create-invalid.json index 9ebaa508..63424a9f 100644 --- a/apps/tests/main-set/011-refs/122-branch-create-invalid.json +++ b/apps/tests/main-set/011-refs/122-branch-create-invalid.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch \"bad:name\"", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/123-tag-create-invalid.json b/apps/tests/main-set/011-refs/123-tag-create-invalid.json index bda4e507..ed0d27d2 100644 --- a/apps/tests/main-set/011-refs/123-tag-create-invalid.json +++ b/apps/tests/main-set/011-refs/123-tag-create-invalid.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "tag bad\\:name", "expected": [ 2, diff --git a/apps/tests/main-set/011-refs/124-branch-list-detached.json b/apps/tests/main-set/011-refs/124-branch-list-detached.json index 6cca0747..0de9b4ca 100644 --- a/apps/tests/main-set/011-refs/124-branch-list-detached.json +++ b/apps/tests/main-set/011-refs/124-branch-list-detached.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "branch", "expected": [ 0, diff --git a/apps/tests/main-set/012-checkout/125-checkout-no-args.json b/apps/tests/main-set/012-checkout/125-checkout-no-args.json index 54c27e02..620a9701 100644 --- a/apps/tests/main-set/012-checkout/125-checkout-no-args.json +++ b/apps/tests/main-set/012-checkout/125-checkout-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/126-checkout-no-cov.json b/apps/tests/main-set/012-checkout/126-checkout-no-cov.json index ec503e4b..fafd80c5 100644 --- a/apps/tests/main-set/012-checkout/126-checkout-no-cov.json +++ b/apps/tests/main-set/012-checkout/126-checkout-no-cov.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout main", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/127-checkout-help.json b/apps/tests/main-set/012-checkout/127-checkout-help.json index 3df821dd..a04852e5 100644 --- a/apps/tests/main-set/012-checkout/127-checkout-help.json +++ b/apps/tests/main-set/012-checkout/127-checkout-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -h", "expected": [ 0, diff --git a/apps/tests/main-set/012-checkout/128-checkout-two-names.json b/apps/tests/main-set/012-checkout/128-checkout-two-names.json index 6018ea38..54e26cd8 100644 --- a/apps/tests/main-set/012-checkout/128-checkout-two-names.json +++ b/apps/tests/main-set/012-checkout/128-checkout-two-names.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout two names", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json b/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json index 114b5eef..0e8ce3b9 100644 --- a/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json +++ b/apps/tests/main-set/012-checkout/129-checkout-too-many-for-branching.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -b result starting-point something else", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json b/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json index 45bb0225..3c409e0a 100644 --- a/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json +++ b/apps/tests/main-set/012-checkout/130-checkout-too-little-for-branching.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -b", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/131-checkout-two-commands.json b/apps/tests/main-set/012-checkout/131-checkout-two-commands.json index 3bf04359..41d68267 100644 --- a/apps/tests/main-set/012-checkout/131-checkout-two-commands.json +++ b/apps/tests/main-set/012-checkout/131-checkout-two-commands.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -b --orphan", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/132-checkout-branch.json b/apps/tests/main-set/012-checkout/132-checkout-branch.json index cace2059..597caec9 100644 --- a/apps/tests/main-set/012-checkout/132-checkout-branch.json +++ b/apps/tests/main-set/012-checkout/132-checkout-branch.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -b branch-name", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/133-checkout-orphan.json b/apps/tests/main-set/012-checkout/133-checkout-orphan.json index 9a806c6f..20157490 100644 --- a/apps/tests/main-set/012-checkout/133-checkout-orphan.json +++ b/apps/tests/main-set/012-checkout/133-checkout-orphan.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout --orphan branch-name", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json index ba26330f..739a7122 100644 --- a/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json +++ b/apps/tests/main-set/012-checkout/134-checkout-orphan-main.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout --orphan main", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json index 1211ad67..afe8af85 100644 --- a/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json +++ b/apps/tests/main-set/012-checkout/135-checkout-orphan-invalid-spec.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout --orphan 'invalid:spec'", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/136-checkout-existing.json b/apps/tests/main-set/012-checkout/136-checkout-existing.json index 4de740b8..f40e0c1f 100644 --- a/apps/tests/main-set/012-checkout/136-checkout-existing.json +++ b/apps/tests/main-set/012-checkout/136-checkout-existing.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout feat/cov-3", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/137-checkout-tag.json b/apps/tests/main-set/012-checkout/137-checkout-tag.json index f1382211..ba3fa42a 100644 --- a/apps/tests/main-set/012-checkout/137-checkout-tag.json +++ b/apps/tests/main-set/012-checkout/137-checkout-tag.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout G", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json b/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json index 59d171f7..729a258e 100644 --- a/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json +++ b/apps/tests/main-set/012-checkout/138-checkout-without-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout --detach", "expected": [ 2, diff --git a/apps/tests/main-set/012-checkout/139-checkout-start-point.json b/apps/tests/main-set/012-checkout/139-checkout-start-point.json index 30ed6aa2..ce937554 100644 --- a/apps/tests/main-set/012-checkout/139-checkout-start-point.json +++ b/apps/tests/main-set/012-checkout/139-checkout-start-point.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "checkout -b branch-name G~", "post": [ "branch --show-current", diff --git a/apps/tests/main-set/013-reset/140-reset-help.json b/apps/tests/main-set/013-reset/140-reset-help.json index 54a66eb7..69308e85 100644 --- a/apps/tests/main-set/013-reset/140-reset-help.json +++ b/apps/tests/main-set/013-reset/140-reset-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "reset -h", "expected": [ 0, diff --git a/apps/tests/main-set/013-reset/141-reset-no-args.json b/apps/tests/main-set/013-reset/141-reset-no-args.json index 86e3f486..6aaca174 100644 --- a/apps/tests/main-set/013-reset/141-reset-no-args.json +++ b/apps/tests/main-set/013-reset/141-reset-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "reset", "expected": [ 2, diff --git a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json index 374cd333..68740711 100644 --- a/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json +++ b/apps/tests/main-set/013-reset/142-reset-no-cov-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "reset HEAD", "expected": [ 2, diff --git a/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json b/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json index b9461a44..edff5598 100644 --- a/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json +++ b/apps/tests/main-set/013-reset/143-reset-switch-to-a-tag.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "reset F", "expected": [ 0, diff --git a/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json b/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json index 59466c79..b4effd94 100644 --- a/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json +++ b/apps/tests/main-set/013-reset/144-reset-switch-detached-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "reset F", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/145-show-help.json b/apps/tests/main-set/014-show/145-show-help.json index 70d1e7b3..daabef6f 100644 --- a/apps/tests/main-set/014-show/145-show-help.json +++ b/apps/tests/main-set/014-show/145-show-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show -h", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/146-show-no-args-unborn.json b/apps/tests/main-set/014-show/146-show-no-args-unborn.json index 2ae4af76..2bcfd13b 100644 --- a/apps/tests/main-set/014-show/146-show-no-args-unborn.json +++ b/apps/tests/main-set/014-show/146-show-no-args-unborn.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show", "expected": [ 2, diff --git a/apps/tests/main-set/014-show/147-show-no-args.json b/apps/tests/main-set/014-show/147-show-no-args.json index 77b06a0f..25105c0f 100644 --- a/apps/tests/main-set/014-show/147-show-no-args.json +++ b/apps/tests/main-set/014-show/147-show-no-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show", "patches": { "report [0-9a-f]{40}": "report $OID", diff --git a/apps/tests/main-set/014-show/148-show-no-args-module.json b/apps/tests/main-set/014-show/148-show-no-args-module.json index 9be4b5bd..89cffb54 100644 --- a/apps/tests/main-set/014-show/148-show-no-args-module.json +++ b/apps/tests/main-set/014-show/148-show-no-args-module.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show --color=always", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", diff --git a/apps/tests/main-set/014-show/149-show-directory.json b/apps/tests/main-set/014-show/149-show-directory.json index 3dae2255..29e06be5 100644 --- a/apps/tests/main-set/014-show/149-show-directory.json +++ b/apps/tests/main-set/014-show/149-show-directory.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-A-show-file.json b/apps/tests/main-set/014-show/150-A-show-file.json index e9d4d01a..4c8c5c87 100644 --- a/apps/tests/main-set/014-show/150-A-show-file.json +++ b/apps/tests/main-set/014-show/150-A-show-file.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src/main.cc", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-B-show-file-color.json b/apps/tests/main-set/014-show/150-B-show-file-color.json index 5e53f17b..e9c73537 100644 --- a/apps/tests/main-set/014-show/150-B-show-file-color.json +++ b/apps/tests/main-set/014-show/150-B-show-file-color.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src/main.cc --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json b/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json index 6f52cb47..911e7e86 100644 --- a/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json +++ b/apps/tests/main-set/014-show/150-C-show-file-many-chunks.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src/main.cc --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/151-show-module.json b/apps/tests/main-set/014-show/151-show-module.json index d2e59e05..1de21584 100644 --- a/apps/tests/main-set/014-show/151-show-module.json +++ b/apps/tests/main-set/014-show/151-show-module.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show -m MAIN", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/152-show-range.json b/apps/tests/main-set/014-show/152-show-range.json index 8b1300ab..7abab82a 100644 --- a/apps/tests/main-set/014-show/152-show-range.json +++ b/apps/tests/main-set/014-show/152-show-range.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show then..", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", diff --git a/apps/tests/main-set/014-show/153-show-not-a-covmodule.json b/apps/tests/main-set/014-show/153-show-not-a-covmodule.json index 582b8ceb..58591b36 100644 --- a/apps/tests/main-set/014-show/153-show-not-a-covmodule.json +++ b/apps/tests/main-set/014-show/153-show-not-a-covmodule.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", diff --git a/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json b/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json index 661419d7..2d8f286a 100644 --- a/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json +++ b/apps/tests/main-set/014-show/154-show-HEAD..HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show same..sies", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", diff --git a/apps/tests/main-set/014-show/155-show-module-props.json b/apps/tests/main-set/014-show/155-show-module-props.json index abc0c12d..89074a27 100644 --- a/apps/tests/main-set/014-show/155-show-module-props.json +++ b/apps/tests/main-set/014-show/155-show-module-props.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show -m MAIN", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/156-show-module-props-colors.json b/apps/tests/main-set/014-show/156-show-module-props-colors.json index 891ab6e8..d03e88d3 100644 --- a/apps/tests/main-set/014-show/156-show-module-props-colors.json +++ b/apps/tests/main-set/014-show/156-show-module-props-colors.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show -m MAIN --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json b/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json index 3ac85c98..256b25a4 100644 --- a/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json +++ b/apps/tests/main-set/014-show/157-show-module-props-colors-empty.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show -m MAIN --color always", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/158-show-functions.json b/apps/tests/main-set/014-show/158-show-functions.json index 95c6a177..5c1f9f77 100644 --- a/apps/tests/main-set/014-show/158-show-functions.json +++ b/apps/tests/main-set/014-show/158-show-functions.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src/main.cc --color always", "patches": { "report [0-9a-f]{40}": "report $REPORT_HASH", diff --git a/apps/tests/main-set/014-show/159-show-functions-log.json b/apps/tests/main-set/014-show/159-show-functions-log.json index 2509a993..908b7c6d 100644 --- a/apps/tests/main-set/014-show/159-show-functions-log.json +++ b/apps/tests/main-set/014-show/159-show-functions-log.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show --color always", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", diff --git a/apps/tests/main-set/014-show/160-show-functions-log.json b/apps/tests/main-set/014-show/160-show-functions-log.json index e811ccf8..d596d0f1 100644 --- a/apps/tests/main-set/014-show/160-show-functions-log.json +++ b/apps/tests/main-set/014-show/160-show-functions-log.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show --color always HEAD:src", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", diff --git a/apps/tests/main-set/014-show/161-show-no-chunks.json b/apps/tests/main-set/014-show/161-show-no-chunks.json index 0732fb0f..ee5c4903 100644 --- a/apps/tests/main-set/014-show/161-show-no-chunks.json +++ b/apps/tests/main-set/014-show/161-show-no-chunks.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show HEAD:src/main.cc", "patches": { "\u001b\\[33mreport [0-9a-f]{40}\u001b\\[m": "\u001b[33mreport $REPORT_HASH\u001b[m", diff --git a/apps/tests/main-set/014-show/162-show-module-props-indented.json b/apps/tests/main-set/014-show/162-show-module-props-indented.json index b5bd6e85..a40389ec 100644 --- a/apps/tests/main-set/014-show/162-show-module-props-indented.json +++ b/apps/tests/main-set/014-show/162-show-module-props-indented.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show $BUILD --format=fuller --prop-names --decorate short", "patches": {"build [0-9a-f]{40}": "build $BUILD_HASH"}, "expected": [ diff --git a/apps/tests/main-set/014-show/163-show-file-in-build.json b/apps/tests/main-set/014-show/163-show-file-in-build.json index cacdadfd..2b712d96 100644 --- a/apps/tests/main-set/014-show/163-show-file-in-build.json +++ b/apps/tests/main-set/014-show/163-show-file-in-build.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show $BUILD:src/main.cc", "expected": [ 0, diff --git a/apps/tests/main-set/014-show/163-show-file-in-files.json b/apps/tests/main-set/014-show/163-show-file-in-files.json index 59460b54..44dc757e 100644 --- a/apps/tests/main-set/014-show/163-show-file-in-files.json +++ b/apps/tests/main-set/014-show/163-show-file-in-files.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "show $FILES:src/main.cc", "patches": {"build [0-9a-f]{40} (.*)": "build $BUILD_HASH \\1"}, "expected": [ diff --git a/apps/tests/main-set/015-filters-A/01-strip-excludes.json b/apps/tests/main-set/015-filters-A/01-strip-excludes.json index 3bebbb5d..6babc0c9 100644 --- a/apps/tests/main-set/015-filters-A/01-strip-excludes.json +++ b/apps/tests/main-set/015-filters-A/01-strip-excludes.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json'", "post": ["show HEAD:main.cc"], "patches": { diff --git a/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json index 989bfcd3..7672a1fd 100644 --- a/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json +++ b/apps/tests/main-set/015-filters-A/02-strip-excludes-osOS.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS", "post": ["show HEAD:main.cc"], "expected": [ diff --git a/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json index 364b73f0..ea9130ec 100644 --- a/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json +++ b/apps/tests/main-set/015-filters-A/03-A-strip-excludes-llvm.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler llvm", "post": "show", "patches": { diff --git a/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json index cd814419..5b68375f 100644 --- a/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json +++ b/apps/tests/main-set/015-filters-A/03-B-strip-excludes-clang.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-llvm.json' -- --os OS --compiler clang", "post": "show", "patches": { diff --git a/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json index 6196a4b7..91925153 100644 --- a/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json +++ b/apps/tests/main-set/015-filters-A/04-strip-excludes-compilerA-OS.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-strip.json' -- --os OS --compiler compilerA", "post": ["show HEAD:main.cc"], "expected": [ diff --git a/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json index dfc4e211..68455d31 100644 --- a/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json +++ b/apps/tests/main-set/015-filters-A/05-strip-excludes-multi.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-multi.json'", "post": "show", "patches": { diff --git a/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json index 43a1b13f..fd469d56 100644 --- a/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json +++ b/apps/tests/main-set/015-filters-A/06-strip-excludes-no-such.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-no-such.json'", "expected": [ 1, diff --git a/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json index 3bcf3ea9..139b6939 100644 --- a/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json +++ b/apps/tests/main-set/015-filters-A/07-A-strip-excludes-broken.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-A.json'", "expected": [ 2, diff --git a/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json index a618b0d7..79cf4c9c 100644 --- a/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json +++ b/apps/tests/main-set/015-filters-A/07-B-strip-excludes-broken.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-B.json'", "expected": [ 2, diff --git a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json index c2e08758..8bbc6b3e 100644 --- a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json +++ b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-broken.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-C.json'", "expected": [ 2, diff --git a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson index df235543..c2e08758 100644 --- a/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson +++ b/apps/tests/main-set/015-filters-A/07-C-strip-excludes-brokenjson @@ -1,5 +1,5 @@ { - "$schema": "../../../../tools/json_tests/schema.json", + "$schema": "../../runner-schema.json", "args": "report -f strip-excludes '$DATA/extensions/report-broken-C.json'", "expected": [ 2, diff --git a/apps/tests/main-set/016-collect/01-collect-help.json b/apps/tests/main-set/016-collect/01-collect-help.json index 866b9734..1a76d1a0 100644 --- a/apps/tests/main-set/016-collect/01-collect-help.json +++ b/apps/tests/main-set/016-collect/01-collect-help.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect -h", "expected": [ 0, diff --git a/apps/tests/main-set/016-collect/02-collect-unborn.json b/apps/tests/main-set/016-collect/02-collect-unborn.json index dc5e36eb..d0f4ceac 100644 --- a/apps/tests/main-set/016-collect/02-collect-unborn.json +++ b/apps/tests/main-set/016-collect/02-collect-unborn.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect", "expected": [ 1, diff --git a/apps/tests/main-set/016-collect/03-collect-no-HEAD.json b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json index 9f3f31ab..dd6fb7ac 100644 --- a/apps/tests/main-set/016-collect/03-collect-no-HEAD.json +++ b/apps/tests/main-set/016-collect/03-collect-no-HEAD.json @@ -1,5 +1,5 @@ { - "$schema": "../../schema.json", + "$schema": "../../runner-schema.json", "disabled": true, "args": "collect", "expected": [ diff --git a/apps/tests/main-set/016-collect/04-collect-too-many-args.json b/apps/tests/main-set/016-collect/04-collect-too-many-args.json index 10d61f0a..57b1ed4d 100644 --- a/apps/tests/main-set/016-collect/04-collect-too-many-args.json +++ b/apps/tests/main-set/016-collect/04-collect-too-many-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect ctest -C Debug .", "expected": [ 2, diff --git a/apps/tests/main-set/016-collect/05-collect-too-little-args.json b/apps/tests/main-set/016-collect/05-collect-too-little-args.json index 15b27913..2b4924fd 100644 --- a/apps/tests/main-set/016-collect/05-collect-too-little-args.json +++ b/apps/tests/main-set/016-collect/05-collect-too-little-args.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect --observe", "expected": [ 2, diff --git a/apps/tests/main-set/016-collect/06-collect-observe.json b/apps/tests/main-set/016-collect/06-collect-observe.json index a1778b0c..ef90ceb3 100644 --- a/apps/tests/main-set/016-collect/06-collect-observe.json +++ b/apps/tests/main-set/016-collect/06-collect-observe.json @@ -1,7 +1,10 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "linear": true, "args": "collect --observe ctest -C Debug .", + "check": { + "stderr": "end" + }, "expected": [ 0, "Test project $TMP/observe\n", diff --git a/apps/tests/main-set/016-collect/07-collect-clang.json b/apps/tests/main-set/016-collect/07-collect-clang.json index 6c72866d..9bbe1905 100644 --- a/apps/tests/main-set/016-collect/07-collect-clang.json +++ b/apps/tests/main-set/016-collect/07-collect-clang.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect", "patches": { "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", diff --git a/apps/tests/main-set/016-collect/08-collect-gcc.json b/apps/tests/main-set/016-collect/08-collect-gcc.json index 90c0e894..2329f412 100644 --- a/apps/tests/main-set/016-collect/08-collect-gcc.json +++ b/apps/tests/main-set/016-collect/08-collect-gcc.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect", "patches": { "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", diff --git a/apps/tests/main-set/016-collect/09-collect-gcc-triple.json b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json index 8e1b13d1..66a30f64 100644 --- a/apps/tests/main-set/016-collect/09-collect-gcc-triple.json +++ b/apps/tests/main-set/016-collect/09-collect-gcc-triple.json @@ -1,5 +1,5 @@ { - "$schema": "../../schema.json", + "$schema": "../../runner-schema.json", "args": "collect", "disabled": true, "patches": { diff --git a/apps/tests/main-set/016-collect/10-collect-clean.json b/apps/tests/main-set/016-collect/10-collect-clean.json index b925e850..0dd99c30 100644 --- a/apps/tests/main-set/016-collect/10-collect-clean.json +++ b/apps/tests/main-set/016-collect/10-collect-clean.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect --clean", "expected": [0, "", ""], "prepare": [ diff --git a/apps/tests/main-set/016-collect/11-collect-no-output.json b/apps/tests/main-set/016-collect/11-collect-no-output.json index fcf7cfde..31ff8daa 100644 --- a/apps/tests/main-set/016-collect/11-collect-no-output.json +++ b/apps/tests/main-set/016-collect/11-collect-no-output.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect", "patches": { "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", diff --git a/apps/tests/main-set/016-collect/12-collect-msvc.json b/apps/tests/main-set/016-collect/12-collect-msvc.json index 8c664797..84c01c27 100644 --- a/apps/tests/main-set/016-collect/12-collect-msvc.json +++ b/apps/tests/main-set/016-collect/12-collect-msvc.json @@ -1,5 +1,5 @@ { - "$schema": "../../runner-schema.json", + "$schema": "../../../../build/downloads/runner-schema.json", "args": "collect", "patches": { "\\[([^\\]]+)\\] [0-9.]+ s": "[\\1] #.## s", From 13929be732830e6601638a8c4d7244b869152911 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 17 Sep 2023 10:31:31 +0200 Subject: [PATCH 37/39] test: fix not working tests --- apps/tests/data/invalid-coverage.json | 3 +++ .../073-report-not-the-json-filtered.json | 4 ++-- libs/cov-api/tests/cov/init-test.cc | 13 ------------- 3 files changed, 5 insertions(+), 15 deletions(-) create mode 100644 apps/tests/data/invalid-coverage.json diff --git a/apps/tests/data/invalid-coverage.json b/apps/tests/data/invalid-coverage.json new file mode 100644 index 00000000..11ee7a87 --- /dev/null +++ b/apps/tests/data/invalid-coverage.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://raw.githubusercontent.com/mzdun/cov/v0.20.0/apps/report-schema.json" +} diff --git a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json index 37ac0d78..5a5fa7e8 100644 --- a/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json +++ b/apps/tests/main-set/008-report-A/073-report-not-the-json-filtered.json @@ -1,13 +1,13 @@ { "$schema": "../../../../build/downloads/runner-schema.json", - "args": "report $DATA/no-git-coverage.json -f echo-to-stdout", + "args": "report $DATA/invalid-coverage.json -f echo-to-stdout", "expected": [ 2, "", [ "cov report: /git: undefined", "cov report: /files: undefined", - "cov report: error: there were issues with $DATA/no-git-coverage.json processed by echo-to-stdout filter\n" + "cov report: error: there were issues with $DATA/invalid-coverage.json processed by echo-to-stdout filter\n" ] ], "prepare": [ diff --git a/libs/cov-api/tests/cov/init-test.cc b/libs/cov-api/tests/cov/init-test.cc index 3ecec2d3..8710e95e 100644 --- a/libs/cov-api/tests/cov/init-test.cc +++ b/libs/cov-api/tests/cov/init-test.cc @@ -136,19 +136,6 @@ namespace cov::testing { }, }, -#ifdef WIN32 - { - "outside_git_win32"sv, - { - "outside_git/.covdata"sv, - "Z:/1234567890aswedferckarek/project/.git"sv, - }, - make_setup(remove_all("outside_git"sv), - create_directories("outside_git"sv)), - {"Z:/1234567890aswedferckarek/project/.git"sv}, - }, -#endif - { "beside_git"sv, {"beside_git/.covdata"sv, "beside_git/project/.git"sv}, From b6954d5df810e188bb602066ced0e8cb885686a1 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Sun, 17 Sep 2023 19:06:55 +0200 Subject: [PATCH 38/39] build: use runner with git user config --- CMakeLists.txt | 7 ++++--- apps/CMakeLists.txt | 4 ++-- tools/download-runner.py | 25 +++++++++++++------------ tools/flow/lib/matrix.py | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92c5e216..02040e59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,11 +55,12 @@ if (COV_TESTING) enable_testing() find_package(GTest REQUIRED) - find_program(Runner_EXECUTABLE runner REQUIRED HINTS + find_program(JsonRunner_EXECUTABLE json-runner REQUIRED HINTS "${PROJECT_SOURCE_DIR}/build/downloads" - "${PROJECT_SOURCE_DIR}/../build/release/bin" + "${PROJECT_SOURCE_DIR}/../json-runner/build/release/bin" + "${PROJECT_SOURCE_DIR}/../runner/build/release/bin" ) - message(STATUS "Runner_EXECUTABLE is: ${Runner_EXECUTABLE}") + message(STATUS "JsonRunner_EXECUTABLE is: ${JsonRunner_EXECUTABLE}") set(COVERALLS_PREFIX cov_) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 3fbd2aff..85b5cbda 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -142,7 +142,7 @@ if (COV_TESTING) ) add_test( NAME cov-exec--${TEST_SET}-alt - COMMAND "${Runner_EXECUTABLE}" + COMMAND "${JsonRunner_EXECUTABLE}" --preset "${CMAKE_PRESET}" --tests "main-set/${TEST_SET}" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} @@ -152,7 +152,7 @@ if (COV_TESTING) if (NOT cov_COVERALLS) add_test( NAME cov-exec-pl-alt - COMMAND "${Runner_EXECUTABLE}" + COMMAND "${JsonRunner_EXECUTABLE}" --preset "${CMAKE_PRESET}" --tests "messages-pl" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} diff --git a/tools/download-runner.py b/tools/download-runner.py index ef5c1c28..edf9a72e 100755 --- a/tools/download-runner.py +++ b/tools/download-runner.py @@ -10,7 +10,8 @@ import requests -TOOL_DIR = f"build/downloads" +TOOL_DIR = "build/downloads" +TOOL_NAME = "json-runner" if os.name == "nt": ARCHIVE_EXT = "zip" ARCHIVE_ARCH = "windows-x86_64" @@ -115,11 +116,9 @@ def _extract(path: str, entry: str, target_path: str): def download_tools(version: str): - package_name = f"runner-{version}-{ARCHIVE_ARCH}" - sha_url = ( - f"https://github.com/mzdun/runner/releases/download/v{version}/sha256sum.txt" - ) - arch_url = f"https://github.com/mzdun/runner/releases/download/v{version}/{package_name}.{ARCHIVE_EXT}" + package_name = f"{TOOL_NAME}-{version}-{ARCHIVE_ARCH}" + sha_url = f"https://github.com/mzdun/{TOOL_NAME}/releases/download/v{version}/sha256sum.txt" + arch_url = f"https://github.com/mzdun/{TOOL_NAME}/releases/download/v{version}/{package_name}.{ARCHIVE_EXT}" path = f"{TOOL_DIR}/{package_name}.{ARCHIVE_EXT}" os.makedirs(TOOL_DIR, exist_ok=True) @@ -170,19 +169,21 @@ def download_tools(version: str): short_version = ".".join(version.split(".")[:2]) print( - f"[EXTRACT] {package_name}/share/runner-{short_version}/schema.json", + f"[EXTRACT] {package_name}/share/{TOOL_NAME}-{short_version}/schema.json", file=sys.stderr, ) if not _extract( path, - f"{package_name}/share/runner-{short_version}/schema.json", - f"{TOOL_DIR}/runner-schema.json", + f"{package_name}/share/{TOOL_NAME}-{short_version}/schema.json", + f"{TOOL_DIR}/{TOOL_NAME}-schema.json", ): return False - print(f"[EXTRACT] {package_name}/bin/runner{EXEC_EXT}", file=sys.stderr) + print(f"[EXTRACT] {package_name}/bin/{TOOL_NAME}{EXEC_EXT}", file=sys.stderr) if not _extract( - path, f"{package_name}/bin/runner{EXEC_EXT}", f"{TOOL_DIR}/runner{EXEC_EXT}" + path, + f"{package_name}/bin/{TOOL_NAME}{EXEC_EXT}", + f"{TOOL_DIR}/{TOOL_NAME}{EXEC_EXT}", ): return False @@ -190,6 +191,6 @@ def download_tools(version: str): if __name__ == "__main__" and not download_tools( - "0.1.2" if len(sys.argv) < 2 else sys.argv[1] + "0.2.0" if len(sys.argv) < 2 else sys.argv[1] ): sys.exit(1) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index dc7b6939..155e9d8f 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -29,7 +29,7 @@ _collect_version = (0, 22, 0) _report_version = (0, 20, 0) -_runner_version = (0, 1, 2) +_runner_version = (0, 2, 0) platform = _platform_name From bdd1eb1def649da8c4fc319d65bfcf39675314c8 Mon Sep 17 00:00:00 2001 From: Marcin Zdun Date: Mon, 25 Sep 2023 07:54:56 +0200 Subject: [PATCH 39/39] build: up the runner version --- tools/download-runner.py | 2 +- tools/flow/lib/matrix.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/download-runner.py b/tools/download-runner.py index edf9a72e..95ef7f72 100755 --- a/tools/download-runner.py +++ b/tools/download-runner.py @@ -191,6 +191,6 @@ def download_tools(version: str): if __name__ == "__main__" and not download_tools( - "0.2.0" if len(sys.argv) < 2 else sys.argv[1] + "0.2.1" if len(sys.argv) < 2 else sys.argv[1] ): sys.exit(1) diff --git a/tools/flow/lib/matrix.py b/tools/flow/lib/matrix.py index 155e9d8f..0c144e5e 100644 --- a/tools/flow/lib/matrix.py +++ b/tools/flow/lib/matrix.py @@ -29,7 +29,7 @@ _collect_version = (0, 22, 0) _report_version = (0, 20, 0) -_runner_version = (0, 2, 0) +_runner_version = (0, 2, 1) platform = _platform_name