fix(ingestion): Log skipped sequential parser languages (#1021)

* fix(ingestion): Log skipped sequential parser languages

* 修复: 对齐 GitNexus#1021 的 Prettier 格式
This commit is contained in:
Ryanba 2026-04-23 15:50:38 +08:00 committed by GitHub
parent 38db0244e8
commit 358e4b5542
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 12 deletions

View file

@ -11,6 +11,7 @@ import { ASTCache } from './ast-cache.js';
import { getLanguageFromFilename, SupportedLanguages } from 'gitnexus-shared';
import { extractVueScript, isVueSetupTopLevel } from './vue-sfc-extractor.js';
import { yieldToEventLoop } from './utils/event-loop.js';
import { isVerboseIngestionEnabled } from './utils/verbose.js';
import {
getDefinitionNodeFromCaptures,
findEnclosingClassInfo,
@ -323,7 +324,8 @@ const processParsingSequential = async (
) => {
const parser = await loadParser();
const total = files.length;
const skippedLanguages = new Map<string, number>();
const logSkipped = isVerboseIngestionEnabled();
const skippedByLang = logSkipped ? new Map<string, number>() : null;
for (let i = 0; i < files.length; i++) {
const file = files[i];
@ -342,10 +344,10 @@ const processParsingSequential = async (
const language = getLanguageFromFilename(file.path);
if (!language) continue;
// Skip unsupported languages (e.g. Swift when tree-sitter-swift not installed)
if (!isLanguageAvailable(language)) {
skippedLanguages.set(language, (skippedLanguages.get(language) || 0) + 1);
if (skippedByLang) {
skippedByLang.set(language, (skippedByLang.get(language) ?? 0) + 1);
}
continue;
}
@ -370,7 +372,7 @@ const processParsingSequential = async (
continue; // parser unavailable — safety net
}
let tree;
let tree: Parser.Tree;
try {
tree = parser.parse(parseContent, undefined, {
bufferSize: getTreeSitterBufferSize(parseContent.length),
@ -395,8 +397,8 @@ const processParsingSequential = async (
continue;
}
let query;
let matches;
let query: Parser.Query;
let matches: Parser.QueryMatch[];
try {
const language = parser.getLanguage();
query = new Parser.Query(language, queryString);
@ -690,11 +692,12 @@ const processParsingSequential = async (
});
}
if (skippedLanguages.size > 0) {
const summary = Array.from(skippedLanguages.entries())
.map(([lang, count]) => `${lang}: ${count}`)
.join(', ');
console.warn(` Skipped unsupported languages: ${summary}`);
if (skippedByLang && skippedByLang.size > 0) {
for (const [lang, count] of skippedByLang.entries()) {
console.warn(
`[ingestion] Skipped ${count} ${lang} file(s) in parsing processing — ${lang} parser not available.`,
);
}
}
};

View file

@ -11,9 +11,11 @@ vi.mock('../../src/core/tree-sitter/parser-loader.js', () => ({
import { createKnowledgeGraph } from '../../src/core/graph/graph.js';
import { createASTCache } from '../../src/core/ingestion/ast-cache.js';
import { processParsing } from '../../src/core/ingestion/parsing-processor.js';
import { processImports } from '../../src/core/ingestion/import-processor.js';
import { processCalls } from '../../src/core/ingestion/call-processor.js';
import { processHeritage } from '../../src/core/ingestion/heritage-processor.js';
import { createSymbolTable } from '../../src/core/ingestion/model/symbol-table.js';
import { createResolutionContext } from '../../src/core/ingestion/model/resolution-context.js';
import * as parserLoader from '../../src/core/tree-sitter/parser-loader.js';
@ -147,4 +149,44 @@ describe('sequential native parser availability', () => {
process.env.GITNEXUS_VERBOSE = previous;
}
});
it('skips Swift files in processParsing when the native parser is unavailable', async () => {
vi.mocked(parserLoader.isLanguageAvailable).mockReturnValue(false);
await expect(
processParsing(
createKnowledgeGraph(),
[{ path: 'App.swift', content: 'class AppViewController: UIViewController {}' }],
createSymbolTable(),
createASTCache(),
),
).resolves.toBeNull();
expect(parserLoader.loadLanguage).not.toHaveBeenCalled();
});
it('warns when processParsing skips files in verbose mode', async () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
const previous = process.env.GITNEXUS_VERBOSE;
process.env.GITNEXUS_VERBOSE = '1';
vi.mocked(parserLoader.isLanguageAvailable).mockReturnValue(false);
await processParsing(
createKnowledgeGraph(),
[{ path: 'App.swift', content: 'class AppViewController: UIViewController {}' }],
createSymbolTable(),
createASTCache(),
);
expect(warnSpy).toHaveBeenCalledWith(
'[ingestion] Skipped 1 swift file(s) in parsing processing — swift parser not available.',
);
warnSpy.mockRestore();
if (previous === undefined) {
delete process.env.GITNEXUS_VERBOSE;
} else {
process.env.GITNEXUS_VERBOSE = previous;
}
});
});