mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-16 08:25:14 +02:00
fix(cli): replace duplicate directory prompt with direct path options
Extract confirmProjectDir helper and split the "Create a new project folder" option into "New subfolder (./ktx-project)" and "Custom path" so users reach their target directory with fewer prompts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
17a2fee69a
commit
bdca6d0f04
2 changed files with 123 additions and 93 deletions
|
|
@ -140,10 +140,11 @@ describe('setup project step', () => {
|
|||
expect(result.projectDir).toBe(projectDir);
|
||||
expect(prompts.select).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
message: 'Which KTX project should setup use?',
|
||||
message: 'Where should KTX create the project?',
|
||||
options: [
|
||||
expect.objectContaining({ value: 'current', label: 'Use current directory' }),
|
||||
expect.objectContaining({ value: 'new', label: 'Create a new project folder' }),
|
||||
expect.objectContaining({ value: 'current', label: 'Current directory' }),
|
||||
expect.objectContaining({ value: 'new-default', label: 'New subfolder (./ktx-project)' }),
|
||||
expect.objectContaining({ value: 'new-custom', label: 'Custom path' }),
|
||||
expect.objectContaining({ value: 'exit', label: 'Exit' }),
|
||||
],
|
||||
}),
|
||||
|
|
@ -156,7 +157,7 @@ describe('setup project step', () => {
|
|||
it('offers an absolute default destination for a new project folder', async () => {
|
||||
const startDir = join(tempDir, 'start');
|
||||
const projectDir = join(startDir, 'ktx-project');
|
||||
const prompts = makePromptAdapter({ choices: ['new', 'default', 'create'] });
|
||||
const prompts = makePromptAdapter({ choices: ['new-default', 'create'] });
|
||||
const testIo = makeIo({ stdoutIsTty: true });
|
||||
|
||||
const result = await runKtxSetupProjectStep(
|
||||
|
|
@ -168,21 +169,16 @@ describe('setup project step', () => {
|
|||
expect(result.status).toBe('ready');
|
||||
expect(result.projectDir).toBe(projectDir);
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
1,
|
||||
expect.objectContaining({
|
||||
message: 'Where should KTX create the project?',
|
||||
options: [
|
||||
expect.objectContaining({
|
||||
value: 'default',
|
||||
label: `Create the default project folder: ${projectDir}`,
|
||||
}),
|
||||
expect.objectContaining({ value: 'custom', label: 'Enter a custom path' }),
|
||||
expect.objectContaining({ value: 'back', label: 'Back' }),
|
||||
],
|
||||
options: expect.arrayContaining([
|
||||
expect.objectContaining({ value: 'new-default', label: 'New subfolder (./ktx-project)' }),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
2,
|
||||
expect.objectContaining({ message: `Create KTX project at ${projectDir}?` }),
|
||||
);
|
||||
expect(prompts.text).not.toHaveBeenCalled();
|
||||
|
|
@ -194,7 +190,7 @@ describe('setup project step', () => {
|
|||
it('prompts for a custom path and resolves it inside the current setup directory', async () => {
|
||||
const startDir = join(tempDir, 'start');
|
||||
const projectDir = join(startDir, 'analytics-ktx');
|
||||
const prompts = makePromptAdapter({ choices: ['new', 'custom', 'create'], textValue: 'analytics-ktx' });
|
||||
const prompts = makePromptAdapter({ choices: ['new-custom', 'create'], textValue: 'analytics-ktx' });
|
||||
|
||||
const result = await runKtxSetupProjectStep(
|
||||
{ projectDir: startDir, mode: 'auto', inputMode: 'auto', yes: false },
|
||||
|
|
@ -217,7 +213,7 @@ describe('setup project step', () => {
|
|||
const startDir = join(tempDir, 'start');
|
||||
const homeDir = join(tempDir, 'home');
|
||||
const projectDir = join(homeDir, 'analytics-ktx');
|
||||
const prompts = makePromptAdapter({ choices: ['new', 'custom', 'create'], textValue: '~/analytics-ktx' });
|
||||
const prompts = makePromptAdapter({ choices: ['new-custom', 'create'], textValue: '~/analytics-ktx' });
|
||||
|
||||
const result = await runKtxSetupProjectStep(
|
||||
{ projectDir: startDir, mode: 'auto', inputMode: 'auto', yes: false },
|
||||
|
|
@ -235,7 +231,7 @@ describe('setup project step', () => {
|
|||
const homeDir = join(tempDir, 'home');
|
||||
const customProjectDir = join(homeDir, 'analytics-ktx');
|
||||
const prompts = makePromptAdapter({
|
||||
choices: ['new', 'custom', 'back', 'exit'],
|
||||
choices: ['new-custom', 'back', 'exit'],
|
||||
textValue: '~/analytics-ktx',
|
||||
});
|
||||
|
||||
|
|
@ -248,7 +244,7 @@ describe('setup project step', () => {
|
|||
expect(result.status).toBe('cancelled');
|
||||
expect(result.projectDir).toBe(startDir);
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
2,
|
||||
expect.objectContaining({
|
||||
message: `Create KTX project at ${customProjectDir}?`,
|
||||
options: [
|
||||
|
|
@ -259,15 +255,15 @@ describe('setup project step', () => {
|
|||
}),
|
||||
);
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(
|
||||
4,
|
||||
expect.objectContaining({ message: 'Which KTX project should setup use?' }),
|
||||
3,
|
||||
expect.objectContaining({ message: 'Where should KTX create the project?' }),
|
||||
);
|
||||
await expect(stat(join(customProjectDir, 'ktx.yaml'))).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('rejects an empty new folder path without creating a project in the process cwd', async () => {
|
||||
const startDir = join(tempDir, 'start');
|
||||
const prompts = makePromptAdapter({ choices: ['new', 'custom'], textValue: ' ' });
|
||||
const prompts = makePromptAdapter({ choices: ['new-custom'], textValue: ' ' });
|
||||
const initProject = vi.fn(async () => {
|
||||
throw new Error('initProject should not run for an empty path');
|
||||
});
|
||||
|
|
@ -292,7 +288,7 @@ describe('setup project step', () => {
|
|||
const projectDir = join(startDir, 'analytics-ktx');
|
||||
await mkdir(projectDir, { recursive: true });
|
||||
await writeFile(join(projectDir, 'README.md'), 'Existing project notes\n', 'utf-8');
|
||||
const prompts = makePromptAdapter({ choices: ['new', 'custom', 'use-existing'], textValue: 'analytics-ktx' });
|
||||
const prompts = makePromptAdapter({ choices: ['new-custom', 'use-existing'], textValue: 'analytics-ktx' });
|
||||
|
||||
const result = await runKtxSetupProjectStep(
|
||||
{ projectDir: startDir, mode: 'auto', inputMode: 'auto', yes: false },
|
||||
|
|
@ -303,7 +299,7 @@ describe('setup project step', () => {
|
|||
expect(result.status).toBe('ready');
|
||||
expect(result.projectDir).toBe(projectDir);
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
2,
|
||||
expect.objectContaining({
|
||||
message: `That folder already exists and is not empty: ${projectDir}`,
|
||||
options: expect.arrayContaining([
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue