mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-07 14:17:16 +02:00
refactor(cli): make the CLI an even thinner wrapper around command functions (#7583)
This commit is contained in:
parent
b4d93b9bd0
commit
0114f00069
11 changed files with 54 additions and 50 deletions
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import cli from 'commander';
|
import cli from 'commander';
|
||||||
import {DOCUSAURUS_VERSION} from '@docusaurus/utils';
|
import {DOCUSAURUS_VERSION} from '@docusaurus/utils';
|
||||||
|
@ -27,8 +26,6 @@ import beforeCli from './beforeCli.mjs';
|
||||||
|
|
||||||
await beforeCli();
|
await beforeCli();
|
||||||
|
|
||||||
const resolveDir = (dir = '.') => fs.realpath(dir);
|
|
||||||
|
|
||||||
cli.version(DOCUSAURUS_VERSION).usage('<command> [options]');
|
cli.version(DOCUSAURUS_VERSION).usage('<command> [options]');
|
||||||
|
|
||||||
cli
|
cli
|
||||||
|
@ -54,9 +51,9 @@ cli
|
||||||
'--no-minify',
|
'--no-minify',
|
||||||
'build website without minimizing JS bundles (default: false)',
|
'build website without minimizing JS bundles (default: false)',
|
||||||
)
|
)
|
||||||
.action(async (siteDir, options) => {
|
// @ts-expect-error: Promise<string> is not assignable to Promise<void>... but
|
||||||
await build(await resolveDir(siteDir), options);
|
// good enough here.
|
||||||
});
|
.action(build);
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('swizzle [themeName] [componentName] [siteDir]')
|
.command('swizzle [themeName] [componentName] [siteDir]')
|
||||||
|
@ -80,9 +77,7 @@ cli
|
||||||
'copy TypeScript theme files when possible (default: false)',
|
'copy TypeScript theme files when possible (default: false)',
|
||||||
)
|
)
|
||||||
.option('--danger', 'enable swizzle for unsafe component of themes')
|
.option('--danger', 'enable swizzle for unsafe component of themes')
|
||||||
.action(async (themeName, componentName, siteDir, options) =>
|
.action(swizzle);
|
||||||
swizzle(await resolveDir(siteDir), themeName, componentName, options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('deploy [siteDir]')
|
.command('deploy [siteDir]')
|
||||||
|
@ -103,9 +98,7 @@ cli
|
||||||
'--skip-build',
|
'--skip-build',
|
||||||
'skip building website before deploy it (default: false)',
|
'skip building website before deploy it (default: false)',
|
||||||
)
|
)
|
||||||
.action(async (siteDir, options) =>
|
.action(deploy);
|
||||||
deploy(await resolveDir(siteDir), options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('start [siteDir]')
|
.command('start [siteDir]')
|
||||||
|
@ -130,9 +123,7 @@ cli
|
||||||
'--no-minify',
|
'--no-minify',
|
||||||
'build website without minimizing JS bundles (default: false)',
|
'build website without minimizing JS bundles (default: false)',
|
||||||
)
|
)
|
||||||
.action(async (siteDir, options) =>
|
.action(start);
|
||||||
start(await resolveDir(siteDir), options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('serve [siteDir]')
|
.command('serve [siteDir]')
|
||||||
|
@ -152,14 +143,12 @@ cli
|
||||||
'--no-open',
|
'--no-open',
|
||||||
'do not open page in the browser (default: false, or true in CI)',
|
'do not open page in the browser (default: false, or true in CI)',
|
||||||
)
|
)
|
||||||
.action(async (siteDir, options) =>
|
.action(serve);
|
||||||
serve(await resolveDir(siteDir), options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('clear [siteDir]')
|
.command('clear [siteDir]')
|
||||||
.description('Remove build artifacts.')
|
.description('Remove build artifacts.')
|
||||||
.action(async (siteDir) => clear(await resolveDir(siteDir)));
|
.action(clear);
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('write-translations [siteDir]')
|
.command('write-translations [siteDir]')
|
||||||
|
@ -180,9 +169,7 @@ cli
|
||||||
'--messagePrefix <messagePrefix>',
|
'--messagePrefix <messagePrefix>',
|
||||||
'Allows to init new written messages with a given prefix. This might help you to highlight untranslated message by making them stand out in the UI (default: "")',
|
'Allows to init new written messages with a given prefix. This might help you to highlight untranslated message by making them stand out in the UI (default: "")',
|
||||||
)
|
)
|
||||||
.action(async (siteDir, options) =>
|
.action(writeTranslations);
|
||||||
writeTranslations(await resolveDir(siteDir), options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('write-heading-ids [siteDir] [files...]')
|
.command('write-heading-ids [siteDir] [files...]')
|
||||||
|
@ -192,9 +179,7 @@ cli
|
||||||
"keep the headings' casing, otherwise make all lowercase (default: false)",
|
"keep the headings' casing, otherwise make all lowercase (default: false)",
|
||||||
)
|
)
|
||||||
.option('--overwrite', 'overwrite existing heading IDs (default: false)')
|
.option('--overwrite', 'overwrite existing heading IDs (default: false)')
|
||||||
.action(async (siteDir, files, options) =>
|
.action(writeHeadingIds);
|
||||||
writeHeadingIds(await resolveDir(siteDir), files, options),
|
|
||||||
);
|
|
||||||
|
|
||||||
cli.arguments('<command>').action((cmd) => {
|
cli.arguments('<command>').action((cmd) => {
|
||||||
cli.outputHelp();
|
cli.outputHelp();
|
||||||
|
@ -221,7 +206,7 @@ function isInternalCommand(command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isInternalCommand(process.argv.slice(2)[0])) {
|
if (!isInternalCommand(process.argv.slice(2)[0])) {
|
||||||
await externalCommand(cli, await resolveDir('.'));
|
await externalCommand(cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!process.argv.slice(2).length) {
|
if (!process.argv.slice(2).length) {
|
||||||
|
|
|
@ -38,14 +38,16 @@ export type BuildCLIOptions = Pick<
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function build(
|
export async function build(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
cliOptions: Partial<BuildCLIOptions>,
|
cliOptions: Partial<BuildCLIOptions> = {},
|
||||||
// When running build, we force terminate the process to prevent async
|
// When running build, we force terminate the process to prevent async
|
||||||
// operations from never returning. However, if run as part of docusaurus
|
// operations from never returning. However, if run as part of docusaurus
|
||||||
// deploy, we have to let deploy finish.
|
// deploy, we have to let deploy finish.
|
||||||
// See https://github.com/facebook/docusaurus/pull/2496
|
// See https://github.com/facebook/docusaurus/pull/2496
|
||||||
forceTerminate: boolean = true,
|
forceTerminate: boolean = true,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
['SIGINT', 'SIGTERM'].forEach((sig) => {
|
['SIGINT', 'SIGTERM'].forEach((sig) => {
|
||||||
process.on(sig, () => process.exit());
|
process.on(sig, () => process.exit());
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,9 @@ async function removePath(entry: {path: string; description: string}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clear(siteDir: string): Promise<void> {
|
export async function clear(siteDirParam: string = '.'): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const generatedFolder = {
|
const generatedFolder = {
|
||||||
path: path.join(siteDir, GENERATED_FILES_DIR_NAME),
|
path: path.join(siteDir, GENERATED_FILES_DIR_NAME),
|
||||||
description: 'generated folder',
|
description: 'generated folder',
|
||||||
|
|
|
@ -41,9 +41,11 @@ function shellExecLog(cmd: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deploy(
|
export async function deploy(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
cliOptions: Partial<DeployCLIOptions>,
|
cliOptions: Partial<DeployCLIOptions> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const {outDir, siteConfig, siteConfigPath} = await loadContext({
|
const {outDir, siteConfig, siteConfigPath} = await loadContext({
|
||||||
siteDir,
|
siteDir,
|
||||||
config: cliOptions.config,
|
config: cliOptions.config,
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs-extra';
|
||||||
import {loadContext} from '../server';
|
import {loadContext} from '../server';
|
||||||
import {initPlugins} from '../server/plugins/init';
|
import {initPlugins} from '../server/plugins/init';
|
||||||
import type {CommanderStatic} from 'commander';
|
import type {CommanderStatic} from 'commander';
|
||||||
|
|
||||||
export async function externalCommand(
|
export async function externalCommand(cli: CommanderStatic): Promise<void> {
|
||||||
cli: CommanderStatic,
|
const siteDir = await fs.realpath('.');
|
||||||
siteDir: string,
|
|
||||||
): Promise<void> {
|
|
||||||
const context = await loadContext({siteDir});
|
const context = await loadContext({siteDir});
|
||||||
const plugins = await initPlugins(context);
|
const plugins = await initPlugins(context);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs-extra';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
|
@ -24,9 +25,11 @@ export type ServeCLIOptions = HostPortOptions &
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function serve(
|
export async function serve(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
cliOptions: Partial<ServeCLIOptions>,
|
cliOptions: Partial<ServeCLIOptions> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const buildDir = cliOptions.dir ?? DEFAULT_BUILD_DIR_NAME;
|
const buildDir = cliOptions.dir ?? DEFAULT_BUILD_DIR_NAME;
|
||||||
let dir = path.resolve(siteDir, buildDir);
|
let dir = path.resolve(siteDir, buildDir);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
|
@ -35,9 +36,11 @@ export type StartCLIOptions = HostPortOptions &
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function start(
|
export async function start(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
cliOptions: Partial<StartCLIOptions>,
|
cliOptions: Partial<StartCLIOptions> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
process.env.NODE_ENV = 'development';
|
process.env.NODE_ENV = 'development';
|
||||||
process.env.BABEL_ENV = 'development';
|
process.env.BABEL_ENV = 'development';
|
||||||
logger.info('Starting the development server...');
|
logger.info('Starting the development server...');
|
||||||
|
|
|
@ -111,7 +111,7 @@ async function createTestSite() {
|
||||||
component: string;
|
component: string;
|
||||||
typescript?: boolean;
|
typescript?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return swizzleWithExit(siteDir, FixtureThemeName, component, {
|
return swizzleWithExit(FixtureThemeName, component, siteDir, {
|
||||||
wrap: true,
|
wrap: true,
|
||||||
danger: true,
|
danger: true,
|
||||||
typescript,
|
typescript,
|
||||||
|
@ -125,7 +125,7 @@ async function createTestSite() {
|
||||||
component: string;
|
component: string;
|
||||||
typescript?: boolean;
|
typescript?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return swizzleWithExit(siteDir, FixtureThemeName, component, {
|
return swizzleWithExit(FixtureThemeName, component, siteDir, {
|
||||||
eject: true,
|
eject: true,
|
||||||
danger: true,
|
danger: true,
|
||||||
typescript,
|
typescript,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs-extra';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {getThemeName, getThemePath, getThemeNames} from './themes';
|
import {getThemeName, getThemePath, getThemeNames} from './themes';
|
||||||
import {getThemeComponents, getComponentName} from './components';
|
import {getThemeComponents, getComponentName} from './components';
|
||||||
|
@ -87,11 +88,13 @@ If you want to swizzle it, use the code=${'--danger'} flag, or confirm that you
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function swizzle(
|
export async function swizzle(
|
||||||
siteDir: string,
|
themeNameParam: string | undefined = undefined,
|
||||||
themeNameParam: string | undefined,
|
componentNameParam: string | undefined = undefined,
|
||||||
componentNameParam: string | undefined,
|
siteDirParam: string = '.',
|
||||||
optionsParam: Partial<SwizzleCLIOptions>,
|
optionsParam: Partial<SwizzleCLIOptions> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const options = normalizeOptions(optionsParam);
|
const options = normalizeOptions(optionsParam);
|
||||||
const {list, danger, typescript} = options;
|
const {list, danger, typescript} = options;
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,12 @@ async function getPathsToWatch(siteDir: string): Promise<string[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function writeHeadingIds(
|
export async function writeHeadingIds(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
files: string[] | undefined,
|
files: string[] = [],
|
||||||
options: WriteHeadingIDOptions,
|
options: WriteHeadingIDOptions = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const markdownFiles = await safeGlobby(
|
const markdownFiles = await safeGlobby(
|
||||||
files ?? (await getPathsToWatch(siteDir)),
|
files ?? (await getPathsToWatch(siteDir)),
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {loadContext, type LoadContextOptions} from '../server';
|
import {loadContext, type LoadContextOptions} from '../server';
|
||||||
import {initPlugins} from '../server/plugins/init';
|
import {initPlugins} from '../server/plugins/init';
|
||||||
|
@ -75,9 +76,11 @@ async function writePluginTranslationFiles({
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function writeTranslations(
|
export async function writeTranslations(
|
||||||
siteDir: string,
|
siteDirParam: string = '.',
|
||||||
options: Partial<WriteTranslationsCLIOptions>,
|
options: Partial<WriteTranslationsCLIOptions> = {},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const siteDir = await fs.realpath(siteDirParam);
|
||||||
|
|
||||||
const context = await loadContext({
|
const context = await loadContext({
|
||||||
siteDir,
|
siteDir,
|
||||||
config: options.config,
|
config: options.config,
|
||||||
|
|
Loading…
Add table
Reference in a new issue