Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 53 additions & 41 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,41 +211,52 @@ function logHelpMessage(
}

const hasTools = toolsList.length > 0;
const gitOptionLine = git
? ' --no-git skip Git repository initialization\n'
: '';
const toolsOptionLine = hasTools
? ' --tools <tool> add additional tools, comma separated\n'
: '';
const skillsOptionLine = hasSkills
? ' --skill <skill> add optional skills, comma separated\n'
: '';
const optionalToolsSection = hasTools
? `
Optional tools:
${toolsList.join(', ')}`
: '';
const optionalSkillsSection = hasSkills
? `
Optional skills:
${skillsList.join(', ')}`
: '';

logger.log(`
Usage: create-${name} [dir] [options]

Options:

-h, --help display help for command
-d, --dir <dir> create project in specified directory
-t, --template <tpl> specify the template to use
${gitOptionLine}${toolsOptionLine}${skillsOptionLine} --override override files in target directory
--packageName <name> specify the package name
--template-version <ver> specify the npm template version

Available templates:
${templates.join(', ')}${optionalToolsSection}${optionalSkillsSection}
`);
const options: [flags: string, description: string][] = [
['-h, --help', 'display help for command'],
['-d, --dir <dir>', 'create project in specified directory'],
['-t, --template <tpl>', 'specify the template to use'],
];

if (git) {
options.push(['--no-git', 'skip Git repository initialization']);
}
if (hasTools) {
options.push(['--tools <tool>', 'add additional tools, comma separated']);
}
if (hasSkills) {
options.push(['--skill <skill>', 'add optional skills, comma separated']);
}

options.push(
['--override', 'override files in target directory'],
['--package-name <name>', 'specify the package name'],
['--template-version <ver>', 'specify the npm template version'],
);

const optionWidth = Math.max(...options.map(([flags]) => flags.length));
const optionLines = options
.map(
([flags, description]) =>
` ${flags.padEnd(optionWidth)} ${description}`,
)
.join('\n');
const helpSections = [
`Usage: create-${name} [dir] [options]`,
'',
'Options:',
optionLines,
'',
`Available templates: ${templates.join(', ')}`,
];

if (hasTools) {
helpSections.push('', `Optional tools: ${toolsList.join(', ')}`);
}
if (hasSkills) {
helpSections.push('', `Optional skills: ${skillsList.join(', ')}`);
}

logger.log(helpSections.join('\n'));
}

async function getTools(
Expand Down Expand Up @@ -747,6 +758,13 @@ export async function create({
*/
argv?: string[];
}) {
const argv = parseArgv(processArgv);

if (argv.help) {
logHelpMessage(name, templates, git, builtinTools, extraTools, extraSkills);
return;
}

logger.greet(`\n◆ Create ${upperFirst(name)} Project`);

const { isAgent } = await determineAgent();
Expand All @@ -757,14 +775,8 @@ export async function create({
);
}

const argv = parseArgv(processArgv);
const gitEnabled = git && argv.git !== false;

if (argv.help) {
logHelpMessage(name, templates, git, builtinTools, extraTools, extraSkills);
return;
}

const cwd = process.cwd();
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);
const packageManager = pkgInfo ? pkgInfo.name : 'npm';
Expand Down
20 changes: 20 additions & 0 deletions test/__snapshots__/help.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Rstest Snapshot v1

exports[`help message uses compact, aligned output 1`] = `
[
[
"Usage: create-test [dir] [options]

Options:
-h, --help display help for command
-d, --dir <dir> create project in specified directory
-t, --template <tpl> specify the template to use
--no-git skip Git repository initialization
--override override files in target directory
--package-name <name> specify the package name
--template-version <ver> specify the npm template version

Available templates: vanilla",
],
]
`;
25 changes: 21 additions & 4 deletions test/help.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { expect, test } from 'rstack/test';
import { afterEach, expect, rs, test } from 'rstack/test';
import { logger } from 'rslog';
import { create } from '../src';

afterEach(() => {
rs.restoreAllMocks();
});

test('help message uses compact, aligned output', async () => {
const log = rs.spyOn(logger, 'log').mockImplementation(() => {});

await create({
name: 'test',
root: '.',
templates: ['vanilla'],
getTemplateName: async () => 'vanilla',
builtinTools: [],
argv: ['node', 'test', '--help'],
});

expect(log.mock.calls).toMatchSnapshot();
});

test('help message includes the Git opt-out option', async () => {
const logs: string[] = [];
const originalLog = logger.log;
Expand All @@ -26,9 +45,7 @@ test('help message includes the Git opt-out option', async () => {
});
}

expect(logs.join('\n')).toContain(
'--no-git skip Git repository initialization',
);
expect(logs.join('\n')).toContain('--no-git');
});

test('help message hides the Git opt-out option when Git is disabled', async () => {
Expand Down