Build Fix
ci / checks (push) Failing after 1h18m29s

This commit is contained in:
khodowany
2026-09-25 09:35:09 -05:00
parent 07559ad74c
commit 17326dbf56
34 changed files with 283 additions and 3723 deletions
+6 -7
View File
@@ -50,7 +50,7 @@ auto invalid(std::string message) -> modulus::error {
}
auto usage() -> std::string {
return "usage: vamp-zero [--config PATH] [--check-config] [--health-check] [--version] [--once]";
return "usage: vamp-zero [--config PATH] [--check-config] [--health-check] [--build-info] [--once]";
}
auto bind_port(vamp_zero::config const &config) -> std::uint16_t {
@@ -127,7 +127,6 @@ auto write_text_atomic(std::filesystem::path const &destination, std::string con
auto write_heartbeat(vamp_zero::config const &config) -> std::expected<void, modulus::error> {
auto heartbeat = boost::json::object{};
heartbeat["version"] = VAMP_VERSION;
heartbeat["git_sha"] = VAMP_GIT_SHA;
heartbeat["status"] = "ok";
heartbeat["endpoint"] = "http://" + config.control.zero_ip + ":" + std::to_string(bind_port(config));
@@ -457,8 +456,8 @@ auto vamp_zero::parse_command_line(std::int32_t argc, std::char_t **argv) -> std
result.check_config = true;
} else if (argument == "--health-check") {
result.health_check = true;
} else if (argument == "--version") {
result.print_version = true;
} else if (argument == "--build-info") {
result.print_build_info = true;
} else if (argument == "--once") {
result.exit_after_startup = true;
} else if (argument == "--help" || argument == "-h") {
@@ -469,7 +468,7 @@ auto vamp_zero::parse_command_line(std::int32_t argc, std::char_t **argv) -> std
}
auto command_count = static_cast<std::uint32_t>(result.check_config ? 1 : 0) +
static_cast<std::uint32_t>(result.health_check ? 1 : 0) +
static_cast<std::uint32_t>(result.print_version ? 1 : 0) +
static_cast<std::uint32_t>(result.print_build_info ? 1 : 0) +
static_cast<std::uint32_t>(result.exit_after_startup ? 1 : 0);
if (command_count > 1U) {
return std::unexpected(invalid("only one command flag may be selected"));
@@ -478,8 +477,8 @@ auto vamp_zero::parse_command_line(std::int32_t argc, std::char_t **argv) -> std
}
auto vamp_zero::run(vamp_zero::command_line command) -> std::expected<void, modulus::error> {
if (command.print_version) {
std::cout << VAMP_VERSION << " " << VAMP_GIT_SHA << '\n';
if (command.print_build_info) {
std::cout << "product-vamp " << VAMP_GIT_SHA << '\n';
return {};
}
auto config = vamp_zero::load_config(command.config_path);
+34 -3
View File
@@ -25,7 +25,6 @@
namespace {
constexpr auto application_id = std::int64_t{0x56414D50};
constexpr auto catalog_schema_version = std::int64_t{3};
auto connection_config(vamp_zero::database_config const &config) -> noto::connection_config {
auto result = noto::file_connection_config(config.path, "product-vamp");
@@ -89,6 +88,34 @@ auto count_value(noto::sqlite_value const &value) -> std::size_t {
return count == nullptr || *count <= 0 ? 0U : static_cast<std::size_t>(*count);
}
auto compatible_table(noto::connection &connection, std::string const &table) -> boost::asio::awaitable<std::bool_t> {
auto columns = std::vector<std::string_view>{"id", "title", "composer", "key_signature", "source_path", "source_json", "measure_count", "total_pages"};
if (table == "practice_exercises") {
columns.push_back("exercise_id");
}
columns.push_back("part");
auto parameters = std::vector<noto::sqlite_value>{noto::sqlite_value{table}};
auto selected = co_await connection.async_execute("SELECT name, type, \"notnull\", pk FROM pragma_table_info(?1) "
"WHERE EXISTS (SELECT 1 FROM pragma_table_list WHERE schema = 'main' AND name = ?1 AND type = 'table' AND strict = 1) ORDER BY cid",
std::move(parameters));
if (!selected || selected->rows.size() != columns.size()) {
co_return false;
}
for (auto index = std::size_t{}; index < columns.size(); ++index) {
auto const &row = selected->rows[index];
if (row.size() != 4U) {
co_return false;
}
auto required = std::get_if<std::int64_t>(&row[2].value);
auto primary = std::get_if<std::int64_t>(&row[3].value);
auto type = index == 6U || index == 7U ? "INTEGER" : "TEXT";
if (text_value(row[0]) != columns[index] || text_value(row[1]) != type || required == nullptr || *required != 1 || primary == nullptr || *primary != (index == 0U ? 1 : 0)) {
co_return false;
}
}
co_return true;
}
}
auto vamp_zero::async_validate_database(boost::asio::any_io_executor executor, vamp_zero::database_config config, std::bool_t integrity) -> boost::asio::awaitable<std::expected<void, modulus::error>> {
@@ -102,11 +129,15 @@ auto vamp_zero::async_validate_database(boost::asio::any_io_executor executor, v
co_return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::PERSISTENCE, "cannot open catalog: " + config.path + "; rebuild or reinstall Product Vamp: " + connected.error().describe()));
}
auto application = co_await connection.async_application_id();
auto version = co_await connection.async_user_version();
auto status = std::expected<void, modulus::error>{};
if (!application || !version || *application != application_id || *version != catalog_schema_version) {
if (!application || *application != application_id) {
status = std::unexpected(vamp_zero::make_error(vamp_zero::error_code::PERSISTENCE, "invalid or incompatible catalog: " + config.path + "; rebuild or reinstall Product Vamp"));
}
for (auto table : {"songs", "practice_exercises"}) {
if (status && !(co_await compatible_table(connection, table))) {
status = std::unexpected(vamp_zero::make_error(vamp_zero::error_code::PERSISTENCE, "incompatible catalog table " + std::string{table} + ": " + config.path + "; rebuild or reinstall Product Vamp"));
}
}
if (status && integrity) {
auto checked = co_await connection.async_execute("PRAGMA quick_check(1)");
if (!checked || checked->rows.size() != 1U || checked->rows[0].size() != 1U || text_value(checked->rows[0][0]) != "ok") {
-3
View File
@@ -50,9 +50,6 @@ auto vamp_zero::parse_notation_document(std::string_view json, std::string sourc
return invalid("expected a JSON object");
}
auto const &root = value.as_object();
if (!integer_equals(root, "schema_version", 3)) {
return invalid("unsupported schema; regenerate this score and its page assets");
}
auto music = object_field(root, "music");
auto presentation = object_field(root, "presentation");
if (music == nullptr || presentation == nullptr) {
+2 -4
View File
@@ -132,9 +132,8 @@ auto vamp_zero::prepare_playback(vamp_zero::score_document const &score, std::fi
return std::unexpected(invalid("regenerate this score to enable playback"));
}
auto const &object = playback->as_object();
auto version = number(object, "version");
auto available = object.if_contains("available");
if (!version || *version != 1U || !available || !available->is_bool()) {
if (!available || !available->is_bool()) {
return std::unexpected(invalid("unsupported playback manifest"));
}
if (!available->as_bool()) {
@@ -205,9 +204,8 @@ auto vamp_zero::validate_playback_assets(vamp_zero::score_document const &score,
if (playback->is_object()) {
auto available = playback->as_object().if_contains("available");
if (available && available->is_bool() && !available->as_bool()) {
auto version = number(playback->as_object(), "version");
auto reason = text(playback->as_object(), "reason");
if (version && *version == 1U && reason && !reason->empty()) {
if (reason && !reason->empty()) {
return {};
}
}
-1
View File
@@ -155,7 +155,6 @@ auto vamp_zero::portal_status_json(vamp_zero::config const &config, vamp_zero::a
control["endpoint"] = "http://" + config.control.zero_ip + ":" + endpoint_port(config.control.endpoint.bind);
auto root = boost::json::object{};
root["device"] = "zero";
root["version"] = VAMP_VERSION;
root["git_sha"] = VAMP_GIT_SHA;
root["control"] = std::move(control);
root["state"] = vamp_zero::app_status_json(state);