From bbab86db739f7bbfa9a42b6651880f87b7b03801 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Thu, 13 Jul 2023 16:39:34 +0800 Subject: [PATCH] Move all CLI commands to their subfolders (#7634) --- packages/astro/src/cli/build/index.ts | 21 ++++ packages/astro/src/cli/check/index.ts | 11 +- packages/astro/src/cli/dev/index.ts | 31 ++++++ packages/astro/src/cli/index.ts | 131 ++++++------------------ packages/astro/src/cli/load-settings.ts | 46 +++++++++ packages/astro/src/cli/preview/index.ts | 16 +++ packages/astro/src/cli/sync/index.ts | 18 ++++ 7 files changed, 171 insertions(+), 103 deletions(-) create mode 100644 packages/astro/src/cli/build/index.ts create mode 100644 packages/astro/src/cli/dev/index.ts create mode 100644 packages/astro/src/cli/load-settings.ts create mode 100644 packages/astro/src/cli/preview/index.ts create mode 100644 packages/astro/src/cli/sync/index.ts diff --git a/packages/astro/src/cli/build/index.ts b/packages/astro/src/cli/build/index.ts new file mode 100644 index 000000000..ab3765731 --- /dev/null +++ b/packages/astro/src/cli/build/index.ts @@ -0,0 +1,21 @@ +import type yargs from 'yargs-parser'; +import _build from '../../core/build/index.js'; +import type { LogOptions } from '../../core/logger/core.js'; +import { loadSettings } from '../load-settings.js'; + +interface BuildOptions { + flags: yargs.Arguments; + logging: LogOptions; +} + +export async function build({ flags, logging }: BuildOptions) { + const settings = await loadSettings({ cmd: 'build', flags, logging }); + if (!settings) return; + + await _build(settings, { + flags, + logging, + teardownCompiler: true, + mode: flags.mode, + }); +} diff --git a/packages/astro/src/cli/check/index.ts b/packages/astro/src/cli/check/index.ts index cf0105461..f188920ac 100644 --- a/packages/astro/src/cli/check/index.ts +++ b/packages/astro/src/cli/check/index.ts @@ -17,6 +17,7 @@ import type { LogOptions } from '../../core/logger/core.js'; import { debug, info } from '../../core/logger/core.js'; import { printHelp } from '../../core/messages.js'; import type { ProcessExit, SyncOptions } from '../../core/sync'; +import { loadSettings } from '../load-settings.js'; import { printDiagnostic } from './print.js'; type DiagnosticResult = { @@ -74,15 +75,11 @@ const ASTRO_GLOB_PATTERN = '**/*.astro'; * * Every time an astro files is modified, content collections are also generated. * - * @param {AstroSettings} settings * @param {CheckPayload} options Options passed {@link AstroChecker} * @param {Flags} options.flags Flags coming from the CLI * @param {LogOptions} options.logging Logging options */ -export async function check( - settings: AstroSettings, - { logging, flags }: CheckPayload -): Promise { +export async function check({ logging, flags }: CheckPayload): Promise { if (flags.help || flags.h) { printHelp({ commandName: 'astro check', @@ -97,6 +94,10 @@ export async function check( }); return; } + + const settings = await loadSettings({ cmd: 'check', flags, logging }); + if (!settings) return; + const checkFlags = parseFlags(flags); if (checkFlags.watch) { info(logging, 'check', 'Checking files in watch mode'); diff --git a/packages/astro/src/cli/dev/index.ts b/packages/astro/src/cli/dev/index.ts new file mode 100644 index 000000000..11eac17c5 --- /dev/null +++ b/packages/astro/src/cli/dev/index.ts @@ -0,0 +1,31 @@ +import fs from 'fs'; +import type yargs from 'yargs-parser'; +import devServer from '../../core/dev/index.js'; +import { resolveConfigPath, resolveFlags } from '../../core/config/index.js'; +import { info, type LogOptions } from '../../core/logger/core.js'; +import { handleConfigError, loadSettings } from '../load-settings.js'; + +interface DevOptions { + flags: yargs.Arguments; + logging: LogOptions; +} + +export async function dev({ flags, logging }: DevOptions) { + const settings = await loadSettings({ cmd: 'dev', flags, logging }); + if (!settings) return; + + const root = flags.root; + const configFlag = resolveFlags(flags).config; + const configFlagPath = configFlag ? await resolveConfigPath({ cwd: root, flags, fs }) : undefined; + + return await devServer(settings, { + configFlag, + configFlagPath, + flags, + logging, + handleConfigError(e) { + handleConfigError(e, { cmd: 'dev', cwd: root, flags, logging }); + info(logging, 'astro', 'Continuing with previous valid configuration\n'); + }, + }); +} diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts index a9399aae5..6f5723686 100644 --- a/packages/astro/src/cli/index.ts +++ b/packages/astro/src/cli/index.ts @@ -1,23 +1,14 @@ /* eslint-disable no-console */ -import fs from 'fs'; import * as colors from 'kleur/colors'; -import type { Arguments as Flags } from 'yargs-parser'; import yargs from 'yargs-parser'; -import { ZodError } from 'zod'; -import { - createSettings, - openConfig, - resolveConfigPath, - resolveFlags, -} from '../core/config/index.js'; import { ASTRO_VERSION } from '../core/constants.js'; import { collectErrorMetadata } from '../core/errors/dev/index.js'; import { createSafeError } from '../core/errors/index.js'; -import { debug, error, info, type LogOptions } from '../core/logger/core.js'; +import { debug, type LogOptions } from '../core/logger/core.js'; import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js'; -import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js'; +import { formatErrorMessage, printHelp } from '../core/messages.js'; import * as event from '../events/index.js'; -import { eventConfigError, eventError, telemetry } from '../events/index.js'; +import { eventError, telemetry } from '../events/index.js'; type Arguments = yargs.Arguments; type CLICommand = @@ -28,7 +19,6 @@ type CLICommand = | 'dev' | 'build' | 'preview' - | 'reload' | 'sync' | 'check' | 'info' @@ -94,20 +84,6 @@ function resolveCommand(flags: Arguments): CLICommand { return 'help'; } -async function handleConfigError( - e: any, - { cmd, cwd, flags, logging }: { cmd: string; cwd?: string; flags?: Flags; logging: LogOptions } -) { - const path = await resolveConfigPath({ cwd, flags, fs }); - error(logging, 'astro', `Unable to load ${path ? colors.bold(path) : 'your Astro config'}\n`); - if (e instanceof ZodError) { - console.error(formatConfigErrorMessage(e) + '\n'); - telemetry.record(eventConfigError({ cmd, err: e, isFatal: true })); - } else if (e instanceof Error) { - console.error(formatErrorMessage(collectErrorMetadata(e)) + '\n'); - } -} - /** * Run the given command with the given flags. * NOTE: This function provides no error handling, so be sure @@ -156,8 +132,13 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { logging.level = 'silent'; } - // These commands can also be run directly without parsing the user config, - // but they rely on parsing the `logging` first. + // Start with a default NODE_ENV so Vite doesn't set an incorrect default when loading the Astro config + if (!process.env.NODE_ENV) { + process.env.NODE_ENV = cmd === 'dev' ? 'development' : 'production'; + } + + // These commands uses the logging and user config. All commands are assumed to have been handled + // by the end of this switch statement. switch (cmd) { case 'add': { telemetry.record(event.eventCliSession(cmd)); @@ -166,66 +147,31 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { await add(packages, { cwd: root, flags, logging }); return; } - } - - // Start with a default NODE_ENV so Vite doesn't set an incorrect default when loading the Astro config - if (!process.env.NODE_ENV) { - process.env.NODE_ENV = cmd === 'dev' ? 'development' : 'production'; - } - - let { astroConfig: initialAstroConfig, userConfig: initialUserConfig } = await openConfig({ - cwd: root, - flags, - cmd, - }).catch(async (e) => { - await handleConfigError(e, { cmd, cwd: root, flags, logging }); - return {} as any; - }); - if (!initialAstroConfig) return; - telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags)); - let settings = createSettings(initialAstroConfig, root); - - // Common CLI Commands: - // These commands run normally. All commands are assumed to have been handled - // by the end of this switch statement. - switch (cmd) { case 'dev': { - const { default: devServer } = await import('../core/dev/index.js'); - - const configFlag = resolveFlags(flags).config; - const configFlagPath = configFlag - ? await resolveConfigPath({ cwd: root, flags, fs }) - : undefined; - - await devServer(settings, { - configFlag, - configFlagPath, - flags, - logging, - handleConfigError(e) { - handleConfigError(e, { cmd, cwd: root, flags, logging }); - info(logging, 'astro', 'Continuing with previous valid configuration\n'); - }, - }); - return await new Promise(() => {}); // lives forever + const { dev } = await import('./dev/index.js'); + const server = await dev({ flags, logging }); + if (server) { + return await new Promise(() => {}); // lives forever + } + return; } - case 'build': { - const { default: build } = await import('../core/build/index.js'); - - return await build(settings, { - flags, - logging, - teardownCompiler: true, - mode: flags.mode, - }); + const { build } = await import('./build/index.js'); + await build({ flags, logging }); + return; + } + case 'preview': { + const { preview } = await import('./preview/index.js'); + const server = await preview({ flags, logging }); + if (server) { + return await server.closed(); // keep alive until the server is closed + } + return; } - case 'check': { const { check } = await import('./check/index.js'); - // We create a server to start doing our operations - const checkServer = await check(settings, { flags, logging }); + const checkServer = await check({ flags, logging }); if (checkServer) { if (checkServer.isWatchMode) { await checkServer.watch(); @@ -235,24 +181,13 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { return process.exit(checkResult); } } - } - - case 'sync': { - const { syncCli } = await import('../core/sync/index.js'); - - const result = await syncCli(settings, { logging, fs, flags }); - return process.exit(result); - } - - case 'preview': { - const { default: preview } = await import('../core/preview/index.js'); - - const server = await preview(settings, { logging, flags }); - if (server) { - return await server.closed(); // keep alive until the server is closed - } return; } + case 'sync': { + const { sync } = await import('./sync/index.js'); + const exitCode = await sync({ flags, logging }); + return process.exit(exitCode); + } } // No command handler matched! This is unexpected. diff --git a/packages/astro/src/cli/load-settings.ts b/packages/astro/src/cli/load-settings.ts new file mode 100644 index 000000000..a5e9537bf --- /dev/null +++ b/packages/astro/src/cli/load-settings.ts @@ -0,0 +1,46 @@ +/* eslint-disable no-console */ +import fs from 'fs'; +import * as colors from 'kleur/colors'; +import type { Arguments as Flags } from 'yargs-parser'; +import { ZodError } from 'zod'; +import { createSettings, openConfig, resolveConfigPath } from '../core/config/index.js'; +import { collectErrorMetadata } from '../core/errors/dev/index.js'; +import { error, type LogOptions } from '../core/logger/core.js'; +import { formatConfigErrorMessage, formatErrorMessage } from '../core/messages.js'; +import * as event from '../events/index.js'; +import { eventConfigError, telemetry } from '../events/index.js'; + +interface LoadSettingsOptions { + cmd: string; + flags: Flags; + logging: LogOptions; +} + +export async function loadSettings({ cmd, flags, logging }: LoadSettingsOptions) { + const root = flags.root; + const { astroConfig: initialAstroConfig, userConfig: initialUserConfig } = await openConfig({ + cwd: root, + flags, + cmd, + }).catch(async (e) => { + await handleConfigError(e, { cmd, cwd: root, flags, logging }); + return {} as any; + }); + if (!initialAstroConfig) return; + telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags)); + return createSettings(initialAstroConfig, root); +} + +export async function handleConfigError( + e: any, + { cmd, cwd, flags, logging }: { cmd: string; cwd?: string; flags?: Flags; logging: LogOptions } +) { + const path = await resolveConfigPath({ cwd, flags, fs }); + error(logging, 'astro', `Unable to load ${path ? colors.bold(path) : 'your Astro config'}\n`); + if (e instanceof ZodError) { + console.error(formatConfigErrorMessage(e) + '\n'); + telemetry.record(eventConfigError({ cmd, err: e, isFatal: true })); + } else if (e instanceof Error) { + console.error(formatErrorMessage(collectErrorMetadata(e)) + '\n'); + } +} diff --git a/packages/astro/src/cli/preview/index.ts b/packages/astro/src/cli/preview/index.ts new file mode 100644 index 000000000..96146cebc --- /dev/null +++ b/packages/astro/src/cli/preview/index.ts @@ -0,0 +1,16 @@ +import type yargs from 'yargs-parser'; +import type { LogOptions } from '../../core/logger/core.js'; +import previewServer from '../../core/preview/index.js'; +import { loadSettings } from '../load-settings.js'; + +interface PreviewOptions { + flags: yargs.Arguments; + logging: LogOptions; +} + +export async function preview({ flags, logging }: PreviewOptions) { + const settings = await loadSettings({ cmd: 'preview', flags, logging }); + if (!settings) return; + + return await previewServer(settings, { flags, logging }); +} diff --git a/packages/astro/src/cli/sync/index.ts b/packages/astro/src/cli/sync/index.ts new file mode 100644 index 000000000..076372fe2 --- /dev/null +++ b/packages/astro/src/cli/sync/index.ts @@ -0,0 +1,18 @@ +import fs from 'fs'; +import type yargs from 'yargs-parser'; +import type { LogOptions } from '../../core/logger/core.js'; +import { syncCli } from '../../core/sync/index.js'; +import { loadSettings } from '../load-settings.js'; + +interface SyncOptions { + flags: yargs.Arguments; + logging: LogOptions; +} + +export async function sync({ flags, logging }: SyncOptions) { + const settings = await loadSettings({ cmd: 'sync', flags, logging }); + if (!settings) return; + + const exitCode = await syncCli(settings, { logging, fs, flags }); + return exitCode; +}