21#define native_ops_strdup _strdup
24#define native_ops_strdup strdup
28 return value != NULL && (
29 streq(value,
"development") ||
30 streq(value,
"test") ||
31 streq(value,
"testing") ||
32 streq(value,
"staging") ||
33 streq(value,
"production")
43 if (command == NULL || command[0] ==
'\0') {
46 if (strchr(command,
'/') != NULL) {
47 return access(command, X_OK) == 0;
49 path_env = getenv(
"PATH");
50 if (path_env == NULL || path_env[0] ==
'\0') {
54 if (path_copy == NULL) {
57 for (segment = strtok_r(path_copy,
":", &state);
59 segment = strtok_r(NULL,
":", &state)) {
61 if (segment[0] ==
'\0') {
64 snprintf(candidate,
sizeof(candidate),
"%s/%s", segment, command);
65 if (access(candidate, X_OK) == 0) {
77 char compose_path[4096];
79 if (repo_root == NULL || repo_root[0] ==
'\0') {
82 snprintf(compose_path,
sizeof(compose_path),
"%s/cross/docker/docker-compose.yml", repo_root);
83 handle = fopen(compose_path,
"r");
97 if (environment == NULL || environment[0] ==
'\0') {
106 if (backend == NULL || backend[0] ==
'\0') {
116 if (db_path != NULL && db_path[0] !=
'\0') {
120 snprintf(buffer,
sizeof(buffer),
"/var/lib/pharos/%s.sqlite3", app != NULL && app->
app_id != NULL ? app->
app_id :
"app");
127 if (output != NULL) {
130 if (code_out != NULL) {
139 const char *cursor = value;
140 if (value == NULL || value[0] ==
'\0') {
143 while (*cursor !=
'\0') {
144 if (!( (*cursor >=
'A' && *cursor <=
'Z') || (*cursor >=
'a' && *cursor <=
'z') || (*cursor >=
'0' && *cursor <=
'9') || *cursor ==
'_' )) {
153 if (buffer == NULL) {
166 const char *cursor = value != NULL ? value :
"";
168 while (*cursor !=
'\0') {
179 if (file_exists && !file_writable) {
180 return "not_writable";
182 if (!file_exists && !parent_exists) {
183 return "missing_parent_dir";
185 if (!file_exists && !parent_writable) {
186 return "parent_not_writable";
194 if (db_path == NULL || sql == NULL) {
197 argv_list[0] =
"sqlite3";
198 argv_list[1] = (
char *)db_path;
199 argv_list[2] = (
char *)sql;
206 char *escaped = NULL;
213 if (escaped == NULL) {
216 snprintf(query,
sizeof(query),
"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '%s' LIMIT 1;", escaped);
218 if (result != NULL &&
streq(result, table_name)) {
233 snprintf(query,
sizeof(query),
"SELECT COUNT(*) FROM \"%s\";", table_name);
235 if (result != NULL && result[0] !=
'\0') {
236 value = strtol(result, NULL, 10);
244 char *escaped_id = NULL;
245 char *escaped_backend = NULL;
248 if (db_path == NULL || migration_id == NULL || backend == NULL) {
253 if (escaped_id == NULL || escaped_backend == NULL) {
255 free(escaped_backend);
258 snprintf(query,
sizeof(query),
"SELECT COUNT(*) FROM pharos_schema_migration WHERE migration_id = '%s' AND backend = '%s';", escaped_id, escaped_backend);
260 if (result != NULL && result[0] !=
'\0') {
261 value = strtol(result, NULL, 10);
264 free(escaped_backend);
271 char *escaped_id = NULL;
272 char *escaped_backend = NULL;
274 if (db_path == NULL || migration_id == NULL || backend == NULL) {
279 if (escaped_id == NULL || escaped_backend == NULL) {
281 free(escaped_backend);
284 snprintf(query,
sizeof(query),
"SELECT schema_version FROM pharos_schema_migration WHERE migration_id = '%s' AND backend = '%s' ORDER BY applied_at DESC LIMIT 1;", escaped_id, escaped_backend);
287 free(escaped_backend);
293 char *escaped_id = NULL;
294 char *escaped_backend = NULL;
296 if (db_path == NULL || migration_id == NULL || backend == NULL) {
301 if (escaped_id == NULL || escaped_backend == NULL) {
303 free(escaped_backend);
306 snprintf(query,
sizeof(query),
"SELECT checksum_sha256 FROM pharos_schema_migration WHERE migration_id = '%s' AND backend = '%s' ORDER BY applied_at DESC LIMIT 1;", escaped_id, escaped_backend);
309 free(escaped_backend);
317 char *path_json = NULL;
318 char *parent_json = NULL;
320 char *parent_dir = NULL;
322 int file_writable = 0;
323 int parent_exists = 0;
324 int parent_writable = 0;
325 const char *status =
"ok";
327 if (file_path == NULL || file_path[0] ==
'\0') {
328 needed = strlen(label != NULL ? label :
"path") + 160;
329 result = (
char *)malloc(needed);
330 if (result != NULL) {
331 snprintf(result, needed,
"{\"label\":\"%s\",\"configured\":false,\"exists\":false,\"parent_exists\":false,\"parent_writable\":false,\"file_writable\":false,\"status\":\"not_configured\"}", label != NULL ? label :
"path");
344 needed = (label_json != NULL ? strlen(label_json) : 0) + (path_json != NULL ? strlen(path_json) : 0) + (parent_json != NULL ? strlen(parent_json) : 0) + strlen(status) + 192;
345 result = (
char *)malloc(needed);
346 if (result != NULL && label_json != NULL && path_json != NULL && parent_json != NULL) {
347 snprintf(result, needed,
"{\"label\":%s,\"configured\":true,\"path\":%s,\"parent_dir\":%s,\"exists\":%s,\"parent_exists\":%s,\"parent_writable\":%s,\"file_writable\":%s,\"status\":\"%s\"}", label_json, path_json, parent_json, file_exists ?
"true" :
"false", parent_exists ?
"true" :
"false", parent_writable ?
"true" :
"false", file_writable ?
"true" :
"false", status);
360 if (backend != NULL &&
streq(backend,
"sqlite")) {
363 char *parent_dir =
path_dirname(sqlite_path != NULL ? sqlite_path :
"");
365 int path_exists_value = sqlite_path != NULL &&
path_exists(sqlite_path);
367 needed = (backend_json != NULL ? strlen(backend_json) : 0) + (sqlite_path_json != NULL ? strlen(sqlite_path_json) : 0) + (parent_json != NULL ? strlen(parent_json) : 0) + 128;
368 result = (
char *)malloc(needed);
369 if (result != NULL && backend_json != NULL && sqlite_path_json != NULL && parent_json != NULL) {
370 snprintf(result, needed,
"[{\"backend\":%s,\"kind\":\"sqlite_path\",\"path\":%s,\"parent_dir\":%s,\"path_exists\":%s,\"parent_exists\":%s,\"status\":\"%s\"}]", backend_json, sqlite_path_json, parent_json, path_exists_value ?
"true" :
"false", parent_exists_value ?
"true" :
"false", parent_exists_value ?
"ok" :
"missing_parent_dir");
373 free(sqlite_path_json);
385 int host_present = host != NULL && host[0] !=
'\0';
386 int port_present = port != NULL && port[0] !=
'\0';
387 int name_present = name != NULL && name[0] !=
'\0';
388 int user_present = user != NULL && user[0] !=
'\0';
389 int ok = host_present && port_present && name_present && user_present;
390 needed = (backend_json != NULL ? strlen(backend_json) : 0) + (host_json != NULL ? strlen(host_json) : 0) + (port_json != NULL ? strlen(port_json) : 0) + (name_json != NULL ? strlen(name_json) : 0) + (user_json != NULL ? strlen(user_json) : 0) + 256;
391 result = (
char *)malloc(needed);
392 if (result != NULL && backend_json != NULL && host_json != NULL && port_json != NULL && name_json != NULL && user_json != NULL) {
393 snprintf(result, needed,
"[{\"backend\":%s,\"kind\":\"postgresql_connection\",\"host\":%s,\"port\":%s,\"database\":%s,\"user\":%s,\"host_present\":%s,\"port_present\":%s,\"database_present\":%s,\"user_present\":%s,\"tls_ok\":true,\"status\":\"%s\"}]", backend_json, host_json, port_json, name_json, user_json, host_present ?
"true" :
"false", port_present ?
"true" :
"false", name_present ?
"true" :
"false", user_present ?
"true" :
"false", ok ?
"ok" :
"incomplete");
419 int db_ok = db_checks_json != NULL && strstr(db_checks_json,
"\"status\":\"ok\"") != NULL && strstr(db_checks_json,
"incomplete") == NULL && strstr(db_checks_json,
"missing_parent_dir") == NULL;
420 int log_ok = log_check_json != NULL && strstr(log_check_json,
"\"status\":\"ok\"") != NULL;
421 int error_ok = error_check_json != NULL && (strstr(error_check_json,
"\"status\":\"ok\"") != NULL || strstr(error_check_json,
"\"status\":\"not_configured\"") != NULL);
422 const char *status = (environment_valid && db_ok && log_ok && error_ok) ?
"ok" :
"invalid";
424 size_t needed = (environment_json != NULL ? strlen(environment_json) : 0) + (backend_json != NULL ? strlen(backend_json) : 0) + (log_path_json != NULL ? strlen(log_path_json) : 0) + (error_report_path_json != NULL ? strlen(error_report_path_json) : 0) + (db_checks_json != NULL ? strlen(db_checks_json) : 0) + (log_check_json != NULL ? strlen(log_check_json) : 0) + (error_check_json != NULL ? strlen(error_check_json) : 0) + 512;
425 result = (
char *)malloc(needed);
426 if (result != NULL && environment_json != NULL && backend_json != NULL && log_path_json != NULL && error_report_path_json != NULL && db_checks_json != NULL && log_check_json != NULL && error_check_json != NULL) {
427 snprintf(result, needed,
"{\"environment\":%s,\"backend\":%s,\"environment_valid\":%s,\"log_path\":%s,\"error_report_path\":%s,\"required_env_refs\":[],\"secret_env_refs\":[],\"required_env_checks\":[],\"secret_env_checks\":[],\"db_checks\":%s,\"log_checks\":[%s,%s],\"issues\":[],\"status\":\"%s\"}", environment_json, backend_json, environment_valid ?
"true" :
"false", log_path_json, error_report_path_json, db_checks_json, log_check_json, error_check_json, status);
431 free(environment_json);
434 free(error_report_path_json);
435 free(db_checks_json);
436 free(log_check_json);
437 free(error_check_json);
455 size_t needed = (app_id_json != NULL ? strlen(app_id_json) : 0) + (mount_json != NULL ? strlen(mount_json) : 0) + (app_root_json != NULL ? strlen(app_root_json) : 0) + (build_dir_json != NULL ? strlen(build_dir_json) : 0) + (state_path_json != NULL ? strlen(state_path_json) : 0) + (log_path_json != NULL ? strlen(log_path_json) : 0) + (log_format_json != NULL ? strlen(log_format_json) : 0) + (error_report_path_json != NULL ? strlen(error_report_path_json) : 0) + (debug_json != NULL ? strlen(debug_json) : 0) + (host_profile_json != NULL ? strlen(host_profile_json) : 0) + (compiled_entrypoint_json != NULL ? strlen(compiled_entrypoint_json) : 0) + (runtime_conf_path_json != NULL ? strlen(runtime_conf_path_json) : 0) + 384;
456 result = (
char *)malloc(needed);
457 if (result != NULL && app_id_json != NULL && mount_json != NULL && app_root_json != NULL && build_dir_json != NULL && state_path_json != NULL && log_path_json != NULL && log_format_json != NULL && error_report_path_json != NULL && debug_json != NULL && host_profile_json != NULL && compiled_entrypoint_json != NULL && runtime_conf_path_json != NULL) {
458 snprintf(result, needed,
"{\"app_id\":%s,\"mount_path\":%s,\"app_root\":%s,\"build_dir\":%s,\"state_path\":%s,\"log_path\":%s,\"log_format\":%s,\"error_report_path\":%s,\"debug\":%s,\"host_profile\":%s,\"compiled_entrypoint\":%s,\"runtime_conf_path\":%s}", app_id_json, mount_json, app_root_json, build_dir_json, state_path_json, log_path_json, log_format_json, error_report_path_json, debug_json, host_profile_json, compiled_entrypoint_json, runtime_conf_path_json);
463 free(build_dir_json);
464 free(state_path_json);
466 free(log_format_json);
467 free(error_report_path_json);
469 free(host_profile_json);
470 free(compiled_entrypoint_json);
471 free(runtime_conf_path_json);
477 argv_list[(*argc)++] =
"--conf";
478 argv_list[(*argc)++] = config->
conf_path;
481 argv_list[(*argc)++] =
"--app-dir";
482 argv_list[(*argc)++] = config->
app_dir;
485 argv_list[(*argc)++] =
"--build-dir";
486 argv_list[(*argc)++] = config->
build_dir;
489 argv_list[(*argc)++] =
"--state-dir";
490 argv_list[(*argc)++] = config->
state_dir;
493 argv_list[(*argc)++] =
"--state-path";
497 argv_list[(*argc)++] =
"--base-path";
498 argv_list[(*argc)++] = config->
base_path;
505 const char *error_text) {
506 char *target_id_json = NULL;
507 char *status_json = NULL;
508 char *error_json = NULL;
509 char *db_path = NULL;
510 char *db_path_json = NULL;
511 char *manifest_path = NULL;
512 char *migration_fixture_rel = NULL;
513 char *entity_fixture_rel = NULL;
514 char *query_fixture_rel = NULL;
515 char *migration_fixture_path = NULL;
516 char *entity_fixture_path = NULL;
517 char *query_fixture_path = NULL;
518 char *migration_fixture_json = NULL;
519 char *entity_fixture_json = NULL;
520 char *query_fixture_json = NULL;
527 if (config == NULL || app == NULL) {
534 error_text != NULL ? error_text :
"native sqlite migrate verify unavailable");
539 if (manifest_path != NULL &&
path_exists(manifest_path)) {
542 if (manifest_doc != NULL) {
545 if (database_obj != NULL) {
546 migration_fixture_rel =
553 migration_fixture_path =
556 entity_fixture_path =
560 migration_fixture_json = migration_fixture_path != NULL
563 entity_fixture_json = entity_fixture_path != NULL
566 query_fixture_json = query_fixture_path != NULL
570 if (target_id_json == NULL || status_json == NULL || error_json == NULL ||
571 db_path_json == NULL || migration_fixture_json == NULL ||
572 entity_fixture_json == NULL || query_fixture_json == NULL) {
576 needed = strlen(target_id_json) + strlen(status_json) + strlen(error_json) +
577 strlen(db_path_json) + strlen(migration_fixture_json) +
578 strlen(entity_fixture_json) + strlen(query_fixture_json) + 2048;
579 result = (
char *)malloc(needed);
580 if (result != NULL) {
581 snprintf(result, needed,
582 "{\"report_id\":\"pharos-migrate-verify-v1\","
583 "\"target_kind\":\"app\",\"target_id\":%s,"
584 "\"backend\":\"sqlite\",\"status\":%s,"
585 "\"error\":%s,\"live_database_verified\":false,"
586 "\"database_present\":false,\"ledger_table_present\":false,"
587 "\"db_path\":%s,\"schema_version\":0,"
588 "\"preferred_backend\":\"sqlite\","
589 "\"development_backend\":\"sqlite\","
590 "\"testing_backend\":\"sqlite\","
591 "\"migration_fixture\":%s,\"entity_fixture\":%s,"
592 "\"query_fixture\":%s,\"db_config\":{\"backend\":\"sqlite\"},"
593 "\"verification_contract\":{},\"required_tables\":[],"
594 "\"required_migration_ids\":[],\"seed_expectations\":[],"
595 "\"table_checks\":[],\"missing_tables\":[],"
596 "\"seed_checks\":[],\"failed_seed_expectations\":[],"
597 "\"migration_checks\":[],\"missing_migrations\":[],"
598 "\"drifted_migrations\":[]}",
599 target_id_json, status_json, error_json, db_path_json,
600 migration_fixture_json, entity_fixture_json, query_fixture_json);
604 free(target_id_json);
610 free(migration_fixture_rel);
611 free(entity_fixture_rel);
612 free(query_fixture_rel);
613 free(migration_fixture_path);
614 free(entity_fixture_path);
615 free(query_fixture_path);
616 free(migration_fixture_json);
617 free(entity_fixture_json);
618 free(query_fixture_json);
624 char *manifest_path = NULL;
625 char *migration_fixture_rel = NULL;
626 char *migration_fixture_path = NULL;
640 if (app == NULL || app->
app_root == NULL) {
644 if (manifest_path == NULL || !
path_exists(manifest_path)) {
648 if (manifest_doc == NULL) {
653 if (database_obj == NULL) {
656 migration_fixture_rel =
658 if (migration_fixture_rel == NULL || migration_fixture_rel[0] ==
'\0') {
662 if (migration_fixture_path == NULL || !
path_exists(migration_fixture_path)) {
666 if (fixture_doc == NULL) {
671 if (sqlite_backend == NULL) {
675 if (verification_contract == NULL) {
679 required_migration_ids =
681 if (required_tables == NULL || required_migration_ids == NULL) {
688 const char *migration_id = NULL;
701 free(migration_fixture_rel);
702 free(migration_fixture_path);
709 char *native_report = NULL;
714 int output_is_json = 0;
716 if (backend != NULL &&
streq(backend,
"sqlite") && app != NULL) {
719 config, app, status_out, error_out);
720 if (native_report != NULL) {
721 if (strstr(native_report,
"\"status\":\"verification_failed\"") != NULL) {
723 if (status_out != NULL) {
727 if (error_out != NULL) {
733 config, app,
"native sqlite migrate verify unavailable");
735 if (native_report != NULL) {
736 return native_report;
740 if (status_out != NULL) {
743 if (error_out != NULL) {
748 config, app,
"native sqlite migrate verify unavailable");
749 if (native_report != NULL) {
750 return native_report;
754 argv_list[argc++] =
"migrate";
755 argv_list[argc++] =
"verify";
756 argv_list[argc++] =
"app";
759 if (backend != NULL && backend[0] !=
'\0') {
760 argv_list[argc++] =
"--backend";
761 argv_list[argc++] = (
char *)backend;
763 argv_list[argc++] =
"--text";
765 if (output != NULL) {
767 output_is_json = output[0] ==
'{';
769 if (output_is_json) {
772 if (status_out != NULL) {
773 *status_out = status != NULL ? status :
native_ops_strdup(code == 0 ?
"verified" :
"failed");
777 if (output_is_json) {
778 if (error_out != NULL) {
783 if (error_out != NULL && *error_out == NULL && output != NULL && output[0] !=
'\0') {
794 char *verify_status = NULL;
795 char *verify_error = NULL;
798 char *build_verify_status =
native_ops_strdup(build_verify_report_json != NULL ?
"ok" :
"failed");
799 char *build_verify_error = NULL;
803 char *build_verify_status_json =
json_string_dup_native(build_verify_status != NULL ? build_verify_status :
"failed");
806 const char *overall_status = (config_report_json != NULL && strstr(config_report_json,
"\"status\":\"ok\"") != NULL && verify_status != NULL &&
streq(verify_status,
"verified") && build_verify_report_json != NULL) ?
"ok" :
"needs_attention";
809 size_t needed = (target_id_json != NULL ? strlen(target_id_json) : 0) + (backend_json != NULL ? strlen(backend_json) : 0) + (runtime_summary_json != NULL ? strlen(runtime_summary_json) : 0) + (config_report_json != NULL ? strlen(config_report_json) : 0) + (verify_status_json != NULL ? strlen(verify_status_json) : 0) + (build_verify_status_json != NULL ? strlen(build_verify_status_json) : 0) + (verify_error_json != NULL ? strlen(verify_error_json) : 0) + (build_verify_error_json != NULL ? strlen(build_verify_error_json) : 0) + (verify_report_json != NULL ? strlen(verify_report_json) : 0) + (build_verify_report_json != NULL ? strlen(build_verify_report_json) : 0) + (overall_status_json != NULL ? strlen(overall_status_json) : 0) + 4096;
810 result = (
char *)malloc(needed);
811 if (result != NULL && target_id_json != NULL && backend_json != NULL && runtime_summary_json != NULL && config_report_json != NULL && verify_status_json != NULL && build_verify_status_json != NULL && verify_error_json != NULL && build_verify_error_json != NULL && verify_report_json != NULL && build_verify_report_json != NULL && overall_status_json != NULL) {
812 snprintf(result, needed,
"{\"report_id\":\"pharos-doctor-v1\",\"target_kind\":\"app\",\"target_id\":%s,\"backend\":%s,\"status\":%s,\"runtime_summary\":%s,\"config\":%s,\"migrate_verify_status\":%s,\"build_verify_status\":%s,\"migrate_verify_error\":%s,\"build_verify_error\":%s,\"migrate_verify_report\":%s,\"build_verify_report\":%s}", target_id_json, backend_json, overall_status_json, runtime_summary_json, config_report_json, verify_status_json, build_verify_status_json, verify_error_json, build_verify_error_json, verify_report_json, build_verify_report_json);
815 free(runtime_summary_json);
816 free(config_report_json);
819 free(verify_report_json);
820 free(build_verify_report_json);
821 free(build_verify_status);
822 free(build_verify_error);
823 free(target_id_json);
825 free(verify_status_json);
826 free(build_verify_status_json);
827 free(verify_error_json);
828 free(build_verify_error_json);
829 free(overall_status_json);
835 char *verify_status = NULL;
836 char *verify_error = NULL;
841 const char *status = verify_status != NULL &&
streq(verify_status,
"verified") ?
"clean" :
"failed";
844 size_t needed = (target_id_json != NULL ? strlen(target_id_json) : 0) + (backend_json != NULL ? strlen(backend_json) : 0) + (stderr_json != NULL ? strlen(stderr_json) : 0) + (verify_report_json != NULL ? strlen(verify_report_json) : 0) + (status_json != NULL ? strlen(status_json) : 0) + 2048;
845 result = (
char *)malloc(needed);
846 if (result != NULL && target_id_json != NULL && backend_json != NULL && stderr_json != NULL && verify_report_json != NULL && status_json != NULL) {
847 snprintf(result, needed,
"{\"report_id\":\"pharos-drift-check-v1\",\"target_kind\":\"app\",\"target_id\":%s,\"backend\":%s,\"status\":%s,\"drifted_migrations\":[],\"missing_tables\":[],\"missing_migrations\":[],\"stderr\":%s,\"verify_report\":%s}", target_id_json, backend_json, status_json, stderr_json, verify_report_json);
852 free(verify_report_json);
853 free(target_id_json);
862 const char *doctor_ok = doctor_json != NULL && strstr(doctor_json,
"\"status\":\"ok\"") != NULL ?
"ready" :
"blocked";
867 size_t needed = (target_id_json != NULL ? strlen(target_id_json) : 0) + (status_json != NULL ? strlen(status_json) : 0) + (package_formats_json != NULL ? strlen(package_formats_json) : 0) + (doctor_json != NULL ? strlen(doctor_json) : 0) + 2048;
868 result = (
char *)malloc(needed);
869 if (result != NULL && target_id_json != NULL && status_json != NULL && package_formats_json != NULL && doctor_json != NULL) {
870 snprintf(result, needed,
"{\"report_id\":\"pharos-deploy-check-v1\",\"target_kind\":\"app\",\"target_id\":%s,\"status\":%s,\"package_formats\":%s,\"doctor\":%s}", target_id_json, status_json, package_formats_json, doctor_json);
873 free(target_id_json);
875 free(package_formats_json);
char * json_string_dup_native(const char *value)
Duplicates a string while escaping it for JSON string output.
Declares helpers that build native artifact and report payload strings.
char * conf_lookup_value(const char *path, const char *key)
Reads a Pharos conf file and looks up one key.
char * json_find_string(const char *text, const char *key)
Finds the first JSON string value associated with a key.
Declares lightweight JSON and conf value lookup helpers.
char * native_capture_migrate_verify_sqlite_report_json(const ServeConfig *config, const AppRuntime *app, char **status_out, char **error_out)
Captures a sqlite migration verification report for one app.
Declares native migration verification entry points.
static int native_command_exists(const char *command)
static char * native_default_environment(const AppRuntime *app)
static char * native_default_sqlite_path(const AppRuntime *app)
static const char * native_output_path_status(int file_exists, int file_writable, int parent_exists, int parent_writable)
char * build_native_app_drift_report_local_json(const char *repo_root, const ServeConfig *config, const AppRuntime *app)
Builds a JSON drift report for one app using native ops bridges.
static char * native_capture_trimmed(char *const argv[], int *code_out)
#define native_ops_strdup
static int native_environment_valid(const char *value)
static void append_app_common_flags(const ServeConfig *config, char *argv_list[], int *argc)
static char * native_sqlite_query_value(const char *db_path, const char *sql)
char * build_native_app_doctor_report_local_json(const char *repo_root, const ServeConfig *config, const char *artifact_dir, const AppRuntime *app, const char *host_target)
Builds a JSON doctor report for one app using native ops bridges.
static char * build_native_app_config_report_local_json(const AppRuntime *app)
static int native_sqlite_migrate_verify_preflight_ok(const AppRuntime *app)
char * build_native_app_deploy_check_report_local_json(const char *repo_root, const ServeConfig *config, const char *artifact_dir, const AppRuntime *app, const char *host_target)
Builds a JSON deploy-check report for one app using native ops bridges.
static char * native_db_check_json(const AppRuntime *app, const char *backend)
static char * native_sqlite_migration_applied_schema_version(const char *db_path, const char *migration_id, const char *backend)
static char * native_build_sqlite_migrate_verify_failure_report_json(const ServeConfig *config, const AppRuntime *app, const char *error_text)
static char * native_sql_literal_escape(const char *value)
static long native_sqlite_migration_applied_count(const char *db_path, const char *migration_id, const char *backend)
static int native_identifier_safe(const char *value)
static char * native_output_path_check_json(const char *file_path, const char *label)
static char * capture_migrate_verify_report_json(const char *repo_root, const ServeConfig *config, const AppRuntime *app, const char *backend, char **status_out, char **error_out)
static char * native_default_backend(const AppRuntime *app)
static char * native_sqlite_migration_applied_checksum(const char *db_path, const char *migration_id, const char *backend)
static int native_sqlite_table_exists(const char *db_path, const char *table_name)
static int native_append_escaped_sql_char(Buffer *buffer, char value)
static char * build_runtime_summary_json_from_app(const AppRuntime *app)
static long native_sqlite_table_row_count(const char *db_path, const char *table_name)
static int native_cross_deb_packaging_available(const char *repo_root)
Declares native bridge helpers for Pharos ops commands.
int run_process_capture_native(char *const argv[], char **output)
Executes a process and captures its combined output text.
Declares child-process capture helpers.
char * build_native_app_runtime_report_json(const char *report_id, const char *verb, const char *host_target, const char *host_mode, const char *artifact_dir, const AppRuntime *app)
Builds a JSON runtime report for one app artifact and host surface.
Declares builders for native runtime report payloads.
int shell_runtime_command_capture_native(const char *repo_root, int argc, char *const argv[], char **output)
Executes a runtime shell command and captures its combined output.
Declares bridge helpers for invoking Pharos shell command surfaces.
void buffer_init(Buffer *buffer)
Initializes a growable buffer to an empty state.
char * path_join(const char *left, const char *right)
Joins two path segments using the native path separator.
void trim_in_place(char *text)
Trims leading and trailing ASCII whitespace from a string in place.
void buffer_free(Buffer *buffer)
Releases memory owned by a growable buffer.
int streq(const char *a, const char *b)
Tests whether two strings are exactly equal.
int path_is_directory(const char *path)
Tests whether a filesystem path refers to a directory.
char * path_dirname(const char *path)
Returns the parent directory component of a path.
char * resolve_relative_to(const char *base_dir, const char *value)
Resolves a path value relative to a base directory when needed.
int buffer_append(Buffer *buffer, const void *data, size_t len)
Appends bytes to a growable buffer and maintains a trailing NUL byte.
int path_is_writable(const char *path)
Tests whether a filesystem path is writable by the current process.
int path_exists(const char *path)
Tests whether a filesystem path currently exists.
Declares shared low-level support helpers used across the Pharos native runtime.
yyjson_doc * native_json_doc_load_file(const char *path)
Parses a JSON file into an owned yyjson document.
yyjson_val * native_json_find_migration_by_id(yyjson_val *root, const char *migration_id)
Finds a migration record by migration_id under a fixture root.
void native_json_doc_free(yyjson_doc *doc)
Releases a document returned by the native yyjson helpers.
yyjson_val * native_json_find_backend_by_name(yyjson_val *root, const char *backend_name)
Finds a backend record by backend name under a fixture root.
char * native_json_obj_get_string_dup(yyjson_val *obj, const char *key)
Duplicates a string-valued key from a JSON object.
yyjson_val * native_json_obj_get_array(yyjson_val *obj, const char *key)
Looks up an array-valued key from a JSON object value.
yyjson_val * native_json_obj_get(yyjson_val *obj, const char *key)
Looks up a key from a JSON object value.
Declares shared helper wrappers around vendored yyjson parsing and serialization APIs.
Loaded runtime metadata for one Pharos app artifact.
char * compiled_entrypoint
Growable byte buffer used by parsing and string assembly helpers.
Parsed native serve configuration used to bootstrap the runtime listener.
yyjson_api_inline bool yyjson_is_str(const yyjson_val *val)
yyjson_api_inline yyjson_val * yyjson_doc_get_root(const yyjson_doc *doc)
yyjson_api_inline yyjson_val * yyjson_arr_iter_next(yyjson_arr_iter *iter)
yyjson_api_inline const char * yyjson_get_str(const yyjson_val *val)
yyjson_api_inline bool yyjson_arr_iter_init(const yyjson_val *arr, yyjson_arr_iter *iter)