Skip to content

Commit 7377fd9

Browse files
fix(builder): preserve structure data during incremental builds
buildStructure() clears all contains edges and directory nodes before rebuilding, but during incremental builds it only received the changed files — causing all unchanged files to lose their directory containment edges and metrics. This made `codegraph structure` show "0 files" for most directories after any incremental build. Fix: before calling buildStructure, load all existing file nodes and their symbols from the DB so the complete file set is available for structure rebuild. Closes #89 Impact: 1 functions changed, 0 affected
1 parent 6eef6b3 commit 7377fd9

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

src/builder.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,43 @@ export async function buildGraph(rootDir, opts = {}) {
827827
}
828828
}
829829

830+
// For incremental builds, buildStructure needs ALL files (not just changed ones)
831+
// because it clears and rebuilds all contains edges and directory metrics.
832+
// Load unchanged files from the DB so structure data stays complete.
833+
if (!isFullBuild) {
834+
const existingFiles = db.prepare("SELECT DISTINCT file FROM nodes WHERE kind = 'file'").all();
835+
const defsByFile = db.prepare(
836+
"SELECT name, kind, line FROM nodes WHERE file = ? AND kind != 'file' AND kind != 'directory'",
837+
);
838+
const importsByFile = db.prepare(
839+
`SELECT DISTINCT n2.file AS source FROM edges e
840+
JOIN nodes n1 ON e.source_id = n1.id
841+
JOIN nodes n2 ON e.target_id = n2.id
842+
WHERE n1.file = ? AND e.kind = 'imports'`,
843+
);
844+
let loadedFromDb = 0;
845+
for (const { file: relPath } of existingFiles) {
846+
if (!fileSymbols.has(relPath)) {
847+
fileSymbols.set(relPath, {
848+
definitions: defsByFile.all(relPath),
849+
imports: importsByFile.all(relPath),
850+
exports: [],
851+
});
852+
loadedFromDb++;
853+
}
854+
if (!lineCountMap.has(relPath)) {
855+
const absPath = path.join(rootDir, relPath);
856+
try {
857+
const content = fs.readFileSync(absPath, 'utf-8');
858+
lineCountMap.set(relPath, content.split('\n').length);
859+
} catch {
860+
lineCountMap.set(relPath, 0);
861+
}
862+
}
863+
}
864+
debug(`Structure: ${fileSymbols.size} files (${loadedFromDb} loaded from DB)`);
865+
}
866+
830867
// Build directory structure, containment edges, and metrics
831868
const relDirs = new Set();
832869
for (const absDir of discoveredDirs) {

0 commit comments

Comments
 (0)