Write artifact.json metadata. */
| 329 | |
| 330 | /* Write artifact.json metadata. */ |
| 331 | static int write_metadata(const char *repo_path, const char *project_name, int nodes, int edges, |
| 332 | size_t original_size, size_t compressed_size, int compression_level) { |
| 333 | char commit[CBM_SZ_64] = ""; |
| 334 | git_head_hash(repo_path, commit, sizeof(commit)); |
| 335 | |
| 336 | char ts[CBM_SZ_64]; |
| 337 | iso_timestamp(ts, sizeof(ts)); |
| 338 | |
| 339 | yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL); |
| 340 | yyjson_mut_val *root = yyjson_mut_obj(doc); |
| 341 | yyjson_mut_doc_set_root(doc, root); |
| 342 | |
| 343 | yyjson_mut_obj_add_int(doc, root, "schema_version", CBM_ARTIFACT_SCHEMA_VERSION); |
| 344 | yyjson_mut_obj_add_str(doc, root, "commit", commit); |
| 345 | yyjson_mut_obj_add_str(doc, root, "indexed_at", ts); |
| 346 | yyjson_mut_obj_add_str(doc, root, "project", project_name); |
| 347 | yyjson_mut_obj_add_int(doc, root, "nodes", nodes); |
| 348 | yyjson_mut_obj_add_int(doc, root, "edges", edges); |
| 349 | yyjson_mut_obj_add_uint(doc, root, "original_size", (uint64_t)original_size); |
| 350 | yyjson_mut_obj_add_uint(doc, root, "compressed_size", (uint64_t)compressed_size); |
| 351 | yyjson_mut_obj_add_int(doc, root, "compression_level", compression_level); |
| 352 | |
| 353 | size_t json_len = 0; |
| 354 | char *json = yyjson_mut_write(doc, YYJSON_WRITE_PRETTY, &json_len); |
| 355 | yyjson_mut_doc_free(doc); |
| 356 | if (!json) { |
| 357 | return artifact_export_fail("write_metadata", NULL, "json_encode", 0); |
| 358 | } |
| 359 | |
| 360 | char meta_path[CBM_SZ_4K]; |
| 361 | if (!artifact_path(meta_path, sizeof(meta_path), repo_path, CBM_ARTIFACT_META)) { |
| 362 | free(json); |
| 363 | return artifact_export_fail("write_metadata", repo_path, "path_too_long", 0); |
| 364 | } |
| 365 | artifact_file_error_t ioerr; |
| 366 | int rc = write_file_atomic(meta_path, json, json_len, &ioerr); |
| 367 | free(json); |
| 368 | if (rc != 0) { |
| 369 | return artifact_export_fail("write_metadata", meta_path, ioerr.err, ioerr.err_no); |
| 370 | } |
| 371 | return rc; |
| 372 | } |
| 373 | |
| 374 | /* ── .gitattributes setup ────────────────────────────────────────── */ |
| 375 |
no test coverage detected