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
72 changes: 71 additions & 1 deletion packages/rstack/src/cli/commands.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { join } from 'node:path';
import { getConfigState } from '../config.ts';
import { insertConfigArg, parseArgs, parseCliArgs } from './args.ts';
import { renderHelp } from './help.ts';
import { hasHelpFlag, renderHelp } from './help.ts';

const renderRootHelp = (): string =>
renderHelp({
Expand Down Expand Up @@ -54,7 +54,77 @@ const renderCheckHelp = (): string =>
],
});

const renderDevHelp = (): string =>
renderHelp({
usage: 'rs dev [options]',
description: 'Run the app dev server',
sections: [
{
title: 'Options',
items: [
['-o, --open [url]', 'Open the page in browser on startup'],
['--port <port>', 'Set the port number for the server'],
['--strict-port', 'Exit if the specified port is already in use'],
['--host [host]', 'Set the host that the server listens to'],
['-c, --config <path>', 'Specify Rstack config file path'],
['-h, --help', 'Display this help message'],
],
},
],
});

const renderBuildHelp = (): string =>
renderHelp({
usage: 'rs build [options]',
description: 'Build the app for production',
sections: [
{
title: 'Options',
items: [
['-w, --watch', 'Enable watch mode to automatically rebuild on file changes'],
['--dist-path <dir>', 'Set the root directory of output files'],
['--source-map', 'Enable source map'],
['-c, --config <path>', 'Specify Rstack config file path'],
['-h, --help', 'Display this help message'],
],
},
],
});

const renderPreviewHelp = (): string =>
renderHelp({
usage: 'rs preview [options]',
description: 'Preview the app production build',
sections: [
{
title: 'Options',
items: [
['-o, --open [url]', 'Open the page in browser on startup'],
['--port <port>', 'Set the port number for the server'],
['--strict-port', 'Exit if the specified port is already in use'],
['--host [host]', 'Set the host that the server listens to'],
['-c, --config <path>', 'Specify Rstack config file path'],
['-h, --help', 'Display this help message'],
],
},
],
});

async function runRsbuildCLI(args: string[]): Promise<void> {
if (hasHelpFlag(args)) {
switch (args[0]) {
case 'dev':
console.log(renderDevHelp());
return;
case 'build':
console.log(renderBuildHelp());
return;
case 'preview':
console.log(renderPreviewHelp());
return;
}
}

const argv = [
process.execPath,
'rsbuild',
Expand Down
7 changes: 7 additions & 0 deletions packages/rstack/src/cli/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ export type HelpDefinition = {
sections?: readonly HelpSection[];
};

export const hasHelpFlag = (args: readonly string[]): boolean => {
const end = args.indexOf('--');
const flags = end === -1 ? args : args.slice(0, end);

return flags.some((flag) => flag === '-h' || flag === '--help');
};

const renderItems = (items: readonly HelpItem[]): string => {
const labelWidth = items.reduce((width, [label]) => Math.max(width, label.length), 0);

Expand Down
53 changes: 53 additions & 0 deletions packages/rstack/tests/cli/__snapshots__/help.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
// Rstest Snapshot v1

exports[`displays build help 1`] = `
"Rstack v<version>

Usage:
$ rs build [options]

Build the app for production

Options:
-w, --watch Enable watch mode to automatically rebuild on file changes
--dist-path <dir> Set the root directory of output files
--source-map Enable source map
-c, --config <path> Specify Rstack config file path
-h, --help Display this help message
"
`;

exports[`displays dev help 1`] = `
"Rstack v<version>

Usage:
$ rs dev [options]

Run the app dev server

Options:
-o, --open [url] Open the page in browser on startup
--port <port> Set the port number for the server
--strict-port Exit if the specified port is already in use
--host [host] Set the host that the server listens to
-c, --config <path> Specify Rstack config file path
-h, --help Display this help message
"
`;

exports[`displays preview help 1`] = `
"Rstack v<version>

Usage:
$ rs preview [options]

Preview the app production build

Options:
-o, --open [url] Open the page in browser on startup
--port <port> Set the port number for the server
--strict-port Exit if the specified port is already in use
--host [host] Set the host that the server listens to
-c, --config <path> Specify Rstack config file path
-h, --help Display this help message
"
`;

exports[`displays top-level help 1`] = `
"Rstack v<version>

Expand Down
17 changes: 17 additions & 0 deletions packages/rstack/tests/cli/help.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { normalizeHelpOutput, test } from '#test-helpers';
import { hasHelpFlag } from '../../src/cli/help.ts';

test('detects help flags before the option terminator', ({ expect }) => {
expect(hasHelpFlag(['dev', '-h'])).toBe(true);
expect(hasHelpFlag(['dev', '--help'])).toBe(true);
expect(hasHelpFlag(['dev', '--', '--help'])).toBe(false);
expect(hasHelpFlag(['dev'])).toBe(false);
});

test('displays top-level help', ({ execCli, expect }) => {
expect(normalizeHelpOutput(execCli('--help'))).toMatchSnapshot();
});

for (const command of ['dev', 'build', 'preview']) {
test(`displays ${command} help`, ({ execCli, expect }) => {
const output = execCli(`${command} --help`);

expect(execCli(`${command} -h`)).toBe(output);
expect(normalizeHelpOutput(output)).toMatchSnapshot();
});
}