mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-10 08:05:14 +02:00
fix(cli): sanitize public ingest progress copy
This commit is contained in:
parent
38ba88176c
commit
2266f91e05
4 changed files with 72 additions and 17 deletions
|
|
@ -625,6 +625,37 @@ describe('runContextBuild', () => {
|
|||
expect(io.stdout()).not.toContain('historic-sql');
|
||||
});
|
||||
|
||||
it('renders database ingest progress without scan wording', async () => {
|
||||
const io = makeIo();
|
||||
const project = projectWithConnections({ warehouse: { driver: 'postgres' } });
|
||||
const executeTarget = vi.fn(async (target, _args, _targetIo, deps) => {
|
||||
await deps.scanProgress?.update(0.05, 'Preparing scan');
|
||||
await deps.scanProgress?.update(0.15, 'Inspecting database schema');
|
||||
await deps.scanProgress?.update(0.7, 'Writing schema artifacts');
|
||||
return successResult(target.connectionId, target.driver, target.operation);
|
||||
});
|
||||
|
||||
await expect(
|
||||
runContextBuild(
|
||||
project,
|
||||
{
|
||||
projectDir: '/tmp/project',
|
||||
inputMode: 'disabled',
|
||||
targetConnectionId: 'warehouse',
|
||||
all: false,
|
||||
},
|
||||
io.io,
|
||||
{ executeTarget, now: () => 1000, sourceProgressThrottleMs: 0 },
|
||||
),
|
||||
).resolves.toMatchObject({ exitCode: 0 });
|
||||
|
||||
expect(io.stdout()).toContain('Preparing database ingest');
|
||||
expect(io.stdout()).toContain('Reading database schema');
|
||||
expect(io.stdout()).toContain('Writing schema context');
|
||||
expect(io.stdout()).not.toContain('Preparing scan');
|
||||
expect(io.stdout()).not.toMatch(/\bscan\b/i);
|
||||
});
|
||||
|
||||
it('passes schema-first notices from the plan into foreground output', async () => {
|
||||
const io = makeIo();
|
||||
const project: KtxPublicIngestProject = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { KtxProgressPort, KtxProgressUpdateOptions } from '@ktx/context/scan';
|
||||
import type { KtxCliIo } from './index.js';
|
||||
import type { KtxIngestProgressUpdate } from './ingest.js';
|
||||
import { publicDatabaseIngestMessage, publicQueryHistoryMessage } from './public-ingest-copy.js';
|
||||
import type {
|
||||
KtxPublicIngestArgs,
|
||||
KtxPublicIngestDeps,
|
||||
|
|
@ -578,17 +579,14 @@ export function initViewState(targets: KtxPublicIngestPlanTarget[]): ContextBuil
|
|||
}
|
||||
|
||||
function publicProgressMessage(message: string, target: KtxPublicIngestPlanTarget): string {
|
||||
if (!target.steps.includes('query-history')) {
|
||||
return message;
|
||||
let current = message;
|
||||
if (target.operation === 'database-ingest') {
|
||||
current = publicDatabaseIngestMessage(current);
|
||||
}
|
||||
return message
|
||||
.replace(
|
||||
new RegExp(`Fetching source files for ${target.connectionId}/historic-sql`, 'i'),
|
||||
`Fetching query history for ${target.connectionId}`,
|
||||
)
|
||||
.replace(`${target.connectionId}/historic-sql`, `${target.connectionId} query history`)
|
||||
.replace(/\bhistoric-sql\b/g, 'query history')
|
||||
.replace(/\bhistoric SQL\b/gi, 'query history');
|
||||
if (target.steps.includes('query-history')) {
|
||||
current = publicQueryHistoryMessage(current, target.connectionId);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
function formatProgressDetail(
|
||||
|
|
|
|||
|
|
@ -523,6 +523,38 @@ describe('runKtxPublicIngest', () => {
|
|||
expect(io.stdout()).not.toContain('live-database');
|
||||
});
|
||||
|
||||
it('sanitizes captured database scan failure details in direct public output', async () => {
|
||||
const io = makeIo();
|
||||
const project = deepReadyProject({ warehouse: { driver: 'postgres', context: { depth: 'deep' } } });
|
||||
const runScan = vi.fn(async (_args, scanIo) => {
|
||||
scanIo.stdout.write('KTX scan enrichment failed after structural scan completed: embedding service timed out\n');
|
||||
return 1;
|
||||
});
|
||||
|
||||
await expect(
|
||||
runKtxPublicIngest(
|
||||
{
|
||||
command: 'run',
|
||||
projectDir: '/tmp/project',
|
||||
targetConnectionId: 'warehouse',
|
||||
all: false,
|
||||
json: false,
|
||||
inputMode: 'disabled',
|
||||
depth: 'deep',
|
||||
},
|
||||
io.io,
|
||||
{ loadProject: vi.fn(async () => project), runScan },
|
||||
),
|
||||
).resolves.toBe(1);
|
||||
|
||||
expect(io.stdout()).toContain(
|
||||
'warehouse failed: Database enrichment failed after schema context completed: embedding service timed out.',
|
||||
);
|
||||
expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --deep');
|
||||
expect(io.stdout()).not.toContain('KTX scan enrichment failed');
|
||||
expect(io.stdout()).not.toContain('structural scan');
|
||||
});
|
||||
|
||||
it('suppresses lower-level source report output during direct public source ingest', async () => {
|
||||
const io = makeIo();
|
||||
const project = projectWithConnections({
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
isDatabaseDriver,
|
||||
normalizeConnectionDriver,
|
||||
} from './ingest-depth.js';
|
||||
import { publicIngestOutputLine } from './public-ingest-copy.js';
|
||||
import type { KtxScanArgs, KtxScanDeps } from './scan.js';
|
||||
import { profileMark } from './startup-profile.js';
|
||||
|
||||
|
|
@ -587,13 +588,6 @@ function createCapturedPublicIngestIo(): CapturedPublicIngestIo {
|
|||
const INTERNAL_STATUS_LINE_RE =
|
||||
/^(Report|Run|Job|Status|Adapter|Connection|Sync|Diff|Work units|Saved memory|Provenance rows):\s*/;
|
||||
|
||||
function publicIngestOutputLine(line: string): string {
|
||||
return line
|
||||
.replace(/\blive-database\b/g, 'database schema')
|
||||
.replace(/\bhistoric-sql\b/g, 'query history')
|
||||
.replace(/\bhistoric SQL\b/gi, 'query history');
|
||||
}
|
||||
|
||||
function firstCapturedFailureLine(output: string): string | undefined {
|
||||
return output
|
||||
.split(/\r?\n/)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue