Skip to content

Commit 23f262c

Browse files
authored
Merge pull request DeusData#995 from spde/fix/incremental-file-node-basename
fix(incremental): name File nodes by basename, matching the full pipeline
2 parents 807a4a3 + 2833ef5 commit 23f262c

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

‎src/pipeline/pipeline_incremental.c‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -885,8 +885,17 @@ int cbm_pipeline_run_incremental(cbm_pipeline_t *p, const char *db_path, cbm_fil
885885
for (int i = 0; i < ci; i++) {
886886
char *file_qn = cbm_pipeline_fqn_compute(project, changed_files[i].rel_path, "__file__");
887887
if (file_qn) {
888-
cbm_gbuf_upsert_node(existing, "File", changed_files[i].rel_path, file_qn,
889-
changed_files[i].rel_path, 0, 0, "{}");
888+
/* #994: the name must be the BASENAME with extension props,
889+
* mirroring the full build's File node (pipeline.c) — upserts
890+
* match by QN, so any other name here renames the node in place
891+
* and the incremental graph diverges from a full build. */
892+
const char *rel = changed_files[i].rel_path;
893+
const char *slash = strrchr(rel, '/');
894+
const char *basename = slash ? slash + SKIP_ONE : rel;
895+
char props[CBM_SZ_256];
896+
const char *ext = strrchr(basename, '.');
897+
snprintf(props, sizeof(props), "{\"extension\":\"%s\"}", ext ? ext : "");
898+
cbm_gbuf_upsert_node(existing, "File", basename, file_qn, rel, 0, 0, props);
890899
free(file_qn);
891900
}
892901
}

‎tests/test_incremental.c‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,36 @@ static int resp_lacks_key(const char *resp, const char *key) {
964964

965965
/* ── list_projects ─────────────────────────────────────────────── */
966966

967+
TEST(incr_file_node_name_stays_basename) {
968+
/* #994: File nodes must keep their basename NAME through an incremental
969+
* re-index (the bug renamed touched files' nodes to rel_path, diverging
970+
* from a full build). Modify a file, re-index, assert no File node name
971+
* contains a path separator. */
972+
char path[512];
973+
snprintf(path, sizeof(path), "%s/fastapi/applications.py", g_repodir);
974+
FILE *f = fopen(path, "a");
975+
ASSERT(f != NULL);
976+
fprintf(f, "\n# incr_file_node_name_stays_basename touch\n");
977+
fclose(f);
978+
979+
char *resp = index_repo();
980+
ASSERT(resp != NULL);
981+
free(resp);
982+
983+
double ms;
984+
char *r = call_tool_timed("query_graph", &ms,
985+
"{\"project\":\"%s\",\"format\":\"json\","
986+
"\"query\":\"MATCH (n:File) WHERE n.name CONTAINS '/'"
987+
" RETURN n.name LIMIT 5\"}",
988+
g_project);
989+
TOOL_OK(r, ms);
990+
/* No File node may carry a path separator in its name; the query engine
991+
* returns an empty rows array when nothing matches. */
992+
ASSERT(strstr(r, "\"rows\":[]") != NULL || strstr(r, "\\\"rows\\\":[]") != NULL);
993+
free(r);
994+
PASS();
995+
}
996+
967997
TEST(tool_list_projects_basic) {
968998
double ms;
969999
char *r = call_tool_timed("list_projects", &ms, "{}");
@@ -2970,6 +3000,7 @@ SUITE(incremental) {
29703000

29713001
/* Phase 3: Incremental deltas */
29723002
RUN_TEST(incr_modify_file);
3003+
RUN_TEST(incr_file_node_name_stays_basename);
29733004
RUN_TEST(incr_formatter_run);
29743005
RUN_TEST(incr_add_file);
29753006
RUN_TEST(incr_delete_file);

0 commit comments

Comments
 (0)