mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-27 21:55:14 +08:00
fix(extraction): a video .ts is never pending on the git path or a scoped sync
Review found two places that decide "is this a source file" without the MPEG-TS check the scan applies: the git fast path's candidate loop in getChangedFiles and the scoped-sync path filter (watcher events). An untracked clip in a git repo was reported as `added`, skipped by sync without a record, and reported as `added` again on every status; a tracked .ts that became a clip stayed `modified` with its stale nodes. Both now treat the clip as non-source: removed when tracked, ignored otherwise. Regression tests fail without this change and pass with it, on both arms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Forge
co-authored by
Claude Opus 5.5
parent
1dbb3d90f1
commit
3111045f6e
@@ -12,6 +12,7 @@ import { describe, it, expect, afterEach } from 'vitest';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { execFileSync } from 'child_process';
|
||||
import { CodeGraph } from '../src';
|
||||
import { scanDirectoryAsync, type ScanSkipStats } from '../src/extraction';
|
||||
import { detectLanguage, isMpegTransportStream, MPEG_TS_SNIFF_BYTES } from '../src/extraction/grammars';
|
||||
@@ -154,3 +155,50 @@ describe('MPEG-TS video named .ts is skipped, real TypeScript is indexed (#1910)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('a video .ts never stays pending (#1910)', () => {
|
||||
const dirs: string[] = [];
|
||||
afterEach(() => { for (const d of dirs.splice(0)) fs.rmSync(d, { recursive: true, force: true }); });
|
||||
const gitProject = (): string => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-mpegts-git-'));
|
||||
dirs.push(dir);
|
||||
const git = (...a: string[]) => execFileSync('git', a, { cwd: dir, stdio: 'pipe' });
|
||||
git('init', '-q'); git('config', 'user.email', 't@t'); git('config', 'user.name', 't');
|
||||
fs.writeFileSync(path.join(dir, 'app.ts'), 'export const a = 1;\n');
|
||||
git('add', '.'); git('commit', '-qm', 'init');
|
||||
return dir;
|
||||
};
|
||||
|
||||
it('an untracked clip is not reported as added, before or after sync', async () => {
|
||||
const dir = gitProject();
|
||||
const cg = await CodeGraph.init(dir, { index: true });
|
||||
try {
|
||||
fs.writeFileSync(path.join(dir, 'clip.ts'), makeMpegTs(40));
|
||||
expect(cg.getChangedFiles()).toEqual({ added: [], modified: [], removed: [] });
|
||||
await cg.sync();
|
||||
expect(cg.getChangedFiles()).toEqual({ added: [], modified: [], removed: [] });
|
||||
expect(cg.getFiles().map((f) => f.path)).toEqual(['app.ts']);
|
||||
} finally {
|
||||
cg.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('a tracked TypeScript file that becomes a clip is removed, on the git path and on a scoped sync', async () => {
|
||||
for (const scoped of [false, true]) {
|
||||
const dir = gitProject();
|
||||
fs.writeFileSync(path.join(dir, 'clip.ts'), 'export const clip = 1;\n');
|
||||
const cg = await CodeGraph.init(dir, { index: true });
|
||||
try {
|
||||
expect(cg.getNodesInFile('clip.ts').some((n) => n.name === 'clip')).toBe(true);
|
||||
fs.writeFileSync(path.join(dir, 'clip.ts'), makeMpegTs(40));
|
||||
if (!scoped) expect(cg.getChangedFiles()).toEqual({ added: [], modified: [], removed: ['clip.ts'] });
|
||||
await (scoped ? cg.sync({ paths: ['clip.ts'] }) : cg.sync());
|
||||
expect(cg.getFiles().map((f) => f.path)).toEqual(['app.ts']);
|
||||
expect(cg.getNodesInFile('clip.ts')).toEqual([]);
|
||||
expect(cg.getChangedFiles()).toEqual({ added: [], modified: [], removed: [] });
|
||||
} finally {
|
||||
cg.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3156,7 +3156,10 @@ export class ExtractionOrchestrator {
|
||||
(p) =>
|
||||
isSourceFile(p, overrides) &&
|
||||
!scope.ignores(p) &&
|
||||
fs.existsSync(path.join(this.rootDir, p))
|
||||
fs.existsSync(path.join(this.rootDir, p)) &&
|
||||
// Same rule as the scan (#1910): a reported video clip is not a
|
||||
// source file, so a tracked one is removed and a new one ignored.
|
||||
!isMpegTsVideoFile(this.rootDir, p)
|
||||
);
|
||||
trackedFiles = [];
|
||||
for (const p of unique) {
|
||||
@@ -3411,7 +3414,11 @@ export class ExtractionOrchestrator {
|
||||
for (const filePath of candidates) {
|
||||
const tracked = this.queries.getFileByPath(filePath);
|
||||
const fullPath = path.join(this.rootDir, filePath);
|
||||
if (!isSourceFile(filePath, overrides) || scope.ignores(filePath) || !fs.existsSync(fullPath)) {
|
||||
// A `.ts` that is an MPEG transport stream is not source (#1910): the
|
||||
// scan never lists it, so git must not report it as pending either —
|
||||
// an untracked clip would otherwise stay "added" after every sync.
|
||||
if (!isSourceFile(filePath, overrides) || scope.ignores(filePath) || !fs.existsSync(fullPath)
|
||||
|| isMpegTsVideoFile(this.rootDir, filePath)) {
|
||||
if (tracked) removed.push(filePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user