mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
feat: route sl query managed runtime policy
This commit is contained in:
parent
399353986f
commit
b1ca79ac9c
3 changed files with 82 additions and 0 deletions
|
|
@ -64,6 +64,8 @@ export const slQueryCommandSchema = z.object({
|
|||
}),
|
||||
format: z.enum(['json', 'sql']),
|
||||
execute: z.boolean(),
|
||||
cliVersion: z.string().min(1),
|
||||
runtimeInstallPolicy: z.enum(['prompt', 'auto', 'never']),
|
||||
maxRows: z.number().int().positive().optional(),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
resolveCommandProjectDir,
|
||||
} from '../cli-program.js';
|
||||
import { slQueryCommandSchema } from '../command-schemas.js';
|
||||
import type { KtxManagedPythonInstallPolicy } from '../managed-python-command.js';
|
||||
import type { KtxSlArgs } from '../sl.js';
|
||||
import { profileMark } from '../startup-profile.js';
|
||||
|
||||
|
|
@ -32,6 +33,16 @@ function collectOrderBy(
|
|||
return [...previous, parseOrderBy(value)];
|
||||
}
|
||||
|
||||
function runtimeInstallPolicy(options: { yes?: boolean; input?: boolean }): KtxManagedPythonInstallPolicy {
|
||||
if (options.yes === true && options.input === false) {
|
||||
throw new Error('Choose only one runtime install mode: --yes or --no-input');
|
||||
}
|
||||
if (options.yes === true) {
|
||||
return 'auto';
|
||||
}
|
||||
return options.input === false ? 'never' : 'prompt';
|
||||
}
|
||||
|
||||
async function runSlArgs(context: KtxCliCommandContext, args: KtxSlArgs): Promise<void> {
|
||||
const runner = context.deps.sl ?? (await import('../sl.js')).runKtxSl;
|
||||
context.setExitCode(await runner(args, context.io));
|
||||
|
|
@ -121,6 +132,8 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
|
|||
.option('--include-empty', 'Include empty rows', false)
|
||||
.addOption(new Option('--format <format>', 'json or sql').choices(['json', 'sql']).default('json'))
|
||||
.option('--execute', 'Execute the compiled query', false)
|
||||
.option('--yes', 'Install the managed Python runtime without prompting when required', false)
|
||||
.option('--no-input', 'Disable interactive managed runtime installation')
|
||||
.option('--max-rows <n>', 'Maximum rows to return when executing', parsePositiveIntegerOption)
|
||||
.action(async (options, command) => {
|
||||
if (options.measure.length === 0) {
|
||||
|
|
@ -141,6 +154,8 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
|
|||
},
|
||||
format: options.format,
|
||||
execute: options.execute === true,
|
||||
cliVersion: context.packageInfo.version,
|
||||
runtimeInstallPolicy: runtimeInstallPolicy(options),
|
||||
...(options.maxRows !== undefined ? { maxRows: options.maxRows } : {}),
|
||||
});
|
||||
await runSlArgs(context, args);
|
||||
|
|
|
|||
|
|
@ -178,6 +178,71 @@ describe('runKtxCli', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('routes sl query managed runtime install policies', async () => {
|
||||
const sl = vi.fn(async () => 0);
|
||||
|
||||
const promptIo = makeIo();
|
||||
await expect(
|
||||
runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count'], promptIo.io, { sl }),
|
||||
).resolves.toBe(0);
|
||||
expect(sl).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
command: 'query',
|
||||
projectDir: tempDir,
|
||||
cliVersion: '0.0.0-private',
|
||||
runtimeInstallPolicy: 'prompt',
|
||||
query: expect.objectContaining({ measures: ['orders.order_count'], dimensions: [] }),
|
||||
}),
|
||||
promptIo.io,
|
||||
);
|
||||
|
||||
const autoIo = makeIo();
|
||||
await expect(
|
||||
runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--yes'], autoIo.io, {
|
||||
sl,
|
||||
}),
|
||||
).resolves.toBe(0);
|
||||
expect(sl).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
cliVersion: '0.0.0-private',
|
||||
runtimeInstallPolicy: 'auto',
|
||||
}),
|
||||
autoIo.io,
|
||||
);
|
||||
|
||||
const noInputIo = makeIo();
|
||||
await expect(
|
||||
runKtxCli(
|
||||
['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--no-input'],
|
||||
noInputIo.io,
|
||||
{ sl },
|
||||
),
|
||||
).resolves.toBe(0);
|
||||
expect(sl).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
cliVersion: '0.0.0-private',
|
||||
runtimeInstallPolicy: 'never',
|
||||
}),
|
||||
noInputIo.io,
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects conflicting sl query runtime install flags', async () => {
|
||||
const io = makeIo();
|
||||
const sl = vi.fn(async () => 0);
|
||||
|
||||
await expect(
|
||||
runKtxCli(
|
||||
['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--yes', '--no-input'],
|
||||
io.io,
|
||||
{ sl },
|
||||
),
|
||||
).resolves.toBe(1);
|
||||
|
||||
expect(sl).not.toHaveBeenCalled();
|
||||
expect(io.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input');
|
||||
});
|
||||
|
||||
it('exposes demo under setup help instead of root help', async () => {
|
||||
const testIo = makeIo();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue