Refactor simple CLI commands (#7619)
This commit is contained in:
parent
3669e2d276
commit
03c28aa629
12 changed files with 123 additions and 115 deletions
|
@ -9,35 +9,36 @@ import preferredPM from 'preferred-pm';
|
||||||
import prompts from 'prompts';
|
import prompts from 'prompts';
|
||||||
import { fileURLToPath, pathToFileURL } from 'url';
|
import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import type yargs from 'yargs-parser';
|
import type yargs from 'yargs-parser';
|
||||||
import { loadTSConfig, resolveConfigPath } from '../config/index.js';
|
import { loadTSConfig, resolveConfigPath } from '../../core/config/index.js';
|
||||||
import {
|
import {
|
||||||
defaultTSConfig,
|
defaultTSConfig,
|
||||||
presets,
|
presets,
|
||||||
updateTSConfigForFramework,
|
updateTSConfigForFramework,
|
||||||
type frameworkWithTSSettings,
|
type frameworkWithTSSettings,
|
||||||
} from '../config/tsconfig.js';
|
} from '../../core/config/tsconfig.js';
|
||||||
import { debug, info, type LogOptions } from '../logger/core.js';
|
import { debug, info, type LogOptions } from '../../core/logger/core.js';
|
||||||
import * as msg from '../messages.js';
|
import * as msg from '../../core/messages.js';
|
||||||
import { printHelp } from '../messages.js';
|
import { printHelp } from '../../core/messages.js';
|
||||||
import { appendForwardSlash } from '../path.js';
|
import { appendForwardSlash } from '../../core/path.js';
|
||||||
import { apply as applyPolyfill } from '../polyfill.js';
|
import { apply as applyPolyfill } from '../../core/polyfill.js';
|
||||||
import { parseNpmName } from '../util.js';
|
import { parseNpmName } from '../../core/util.js';
|
||||||
import { generate, parse, t, visit } from './babel.js';
|
import { generate, parse, t, visit } from './babel.js';
|
||||||
import { ensureImport } from './imports.js';
|
import { ensureImport } from './imports.js';
|
||||||
import { wrapDefaultExport } from './wrapper.js';
|
import { wrapDefaultExport } from './wrapper.js';
|
||||||
|
|
||||||
export interface AddOptions {
|
interface AddOptions {
|
||||||
logging: LogOptions;
|
logging: LogOptions;
|
||||||
flags: yargs.Arguments;
|
flags: yargs.Arguments;
|
||||||
cwd?: string;
|
cwd?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IntegrationInfo {
|
interface IntegrationInfo {
|
||||||
id: string;
|
id: string;
|
||||||
packageName: string;
|
packageName: string;
|
||||||
dependencies: [name: string, version: string][];
|
dependencies: [name: string, version: string][];
|
||||||
type: 'integration' | 'adapter';
|
type: 'integration' | 'adapter';
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALIASES = new Map([
|
const ALIASES = new Map([
|
||||||
['solid', 'solid-js'],
|
['solid', 'solid-js'],
|
||||||
['tailwindcss', 'tailwind'],
|
['tailwindcss', 'tailwind'],
|
||||||
|
@ -85,7 +86,7 @@ async function getRegistry(): Promise<string> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function add(names: string[], { cwd, flags, logging }: AddOptions) {
|
export async function add(names: string[], { cwd, flags, logging }: AddOptions) {
|
||||||
applyPolyfill();
|
applyPolyfill();
|
||||||
if (flags.help || names.length === 0) {
|
if (flags.help || names.length === 0) {
|
||||||
printHelp({
|
printHelp({
|
22
packages/astro/src/cli/docs/index.ts
Normal file
22
packages/astro/src/cli/docs/index.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import type yargs from 'yargs-parser';
|
||||||
|
import { printHelp } from '../../core/messages.js';
|
||||||
|
import { openInBrowser } from './open.js';
|
||||||
|
|
||||||
|
interface DocsOptions {
|
||||||
|
flags: yargs.Arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function docs({ flags }: DocsOptions) {
|
||||||
|
if (flags.help || flags.h) {
|
||||||
|
printHelp({
|
||||||
|
commandName: 'astro docs',
|
||||||
|
tables: {
|
||||||
|
Flags: [['--help (-h)', 'See all available flags.']],
|
||||||
|
},
|
||||||
|
description: `Launches the Astro Docs website directly from the terminal.`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await openInBrowser('https://docs.astro.build/');
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import * as colors from 'kleur/colors';
|
import * as colors from 'kleur/colors';
|
||||||
import { arch, platform } from 'node:os';
|
|
||||||
import type { Arguments as Flags } from 'yargs-parser';
|
import type { Arguments as Flags } from 'yargs-parser';
|
||||||
import yargs from 'yargs-parser';
|
import yargs from 'yargs-parser';
|
||||||
import { ZodError } from 'zod';
|
import { ZodError } from 'zod';
|
||||||
|
@ -19,7 +18,6 @@ import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js
|
||||||
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
|
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
|
||||||
import * as event from '../events/index.js';
|
import * as event from '../events/index.js';
|
||||||
import { eventConfigError, eventError, telemetry } from '../events/index.js';
|
import { eventConfigError, eventError, telemetry } from '../events/index.js';
|
||||||
import { openInBrowser } from './open.js';
|
|
||||||
|
|
||||||
type Arguments = yargs.Arguments;
|
type Arguments = yargs.Arguments;
|
||||||
type CLICommand =
|
type CLICommand =
|
||||||
|
@ -69,62 +67,11 @@ function printAstroHelp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Display --version flag */
|
/** Display --version flag */
|
||||||
async function printVersion() {
|
function printVersion() {
|
||||||
console.log();
|
console.log();
|
||||||
console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${ASTRO_VERSION}`)}`);
|
console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${ASTRO_VERSION}`)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function printInfo({
|
|
||||||
cwd,
|
|
||||||
flags,
|
|
||||||
logging,
|
|
||||||
}: {
|
|
||||||
cwd?: string;
|
|
||||||
flags?: Flags;
|
|
||||||
logging: LogOptions;
|
|
||||||
}) {
|
|
||||||
const whichPm = await import('which-pm');
|
|
||||||
const packageManager = await whichPm.default(process.cwd());
|
|
||||||
let adapter = "Couldn't determine.";
|
|
||||||
let integrations = [];
|
|
||||||
|
|
||||||
const MAX_PADDING = 25;
|
|
||||||
function printRow(label: string, value: string) {
|
|
||||||
const padding = MAX_PADDING - label.length;
|
|
||||||
console.log(`${colors.bold(label)}` + ' '.repeat(padding) + `${colors.green(value)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { userConfig } = await openConfig({
|
|
||||||
cwd,
|
|
||||||
flags,
|
|
||||||
cmd: 'info',
|
|
||||||
logging,
|
|
||||||
});
|
|
||||||
if (userConfig.adapter?.name) {
|
|
||||||
adapter = userConfig.adapter.name;
|
|
||||||
}
|
|
||||||
if (userConfig.integrations) {
|
|
||||||
integrations = (userConfig?.integrations ?? [])
|
|
||||||
.filter(Boolean)
|
|
||||||
.flat()
|
|
||||||
.map((i: any) => i?.name);
|
|
||||||
}
|
|
||||||
} catch (_e) {}
|
|
||||||
console.log();
|
|
||||||
const packageManagerName = packageManager?.name ?? "Couldn't determine.";
|
|
||||||
printRow('Astro version', `v${ASTRO_VERSION}`);
|
|
||||||
printRow('Package manager', packageManagerName);
|
|
||||||
printRow('Platform', platform());
|
|
||||||
printRow('Architecture', arch());
|
|
||||||
printRow('Adapter', adapter);
|
|
||||||
let integrationsString = "None or couldn't determine.";
|
|
||||||
if (integrations.length > 0) {
|
|
||||||
integrationsString = integrations.join(', ');
|
|
||||||
}
|
|
||||||
printRow('Integrations', integrationsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine which command the user requested */
|
/** Determine which command the user requested */
|
||||||
function resolveCommand(flags: Arguments): CLICommand {
|
function resolveCommand(flags: Arguments): CLICommand {
|
||||||
const cmd = flags._[2] as string;
|
const cmd = flags._[2] as string;
|
||||||
|
@ -171,24 +118,40 @@ async function handleConfigError(
|
||||||
**/
|
**/
|
||||||
async function runCommand(cmd: string, flags: yargs.Arguments) {
|
async function runCommand(cmd: string, flags: yargs.Arguments) {
|
||||||
const root = flags.root;
|
const root = flags.root;
|
||||||
// logLevel
|
|
||||||
let logging: LogOptions = {
|
// These commands can run directly without parsing the user config.
|
||||||
dest: nodeLogDestination,
|
|
||||||
level: 'info',
|
|
||||||
};
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 'help':
|
case 'help':
|
||||||
printAstroHelp();
|
printAstroHelp();
|
||||||
return process.exit(0);
|
return;
|
||||||
case 'version':
|
case 'version':
|
||||||
await printVersion();
|
printVersion();
|
||||||
return process.exit(0);
|
return;
|
||||||
case 'info': {
|
case 'info': {
|
||||||
await printInfo({ cwd: root, flags, logging });
|
const { printInfo } = await import('./info/index.js');
|
||||||
return process.exit(0);
|
await printInfo({ cwd: root, flags });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'docs': {
|
||||||
|
telemetry.record(event.eventCliSession(cmd));
|
||||||
|
const { docs } = await import('./docs/index.js');
|
||||||
|
await docs({ flags });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'telemetry': {
|
||||||
|
// Do not track session start, since the user may be trying to enable,
|
||||||
|
// disable, or modify telemetry settings.
|
||||||
|
const { update } = await import('./telemetry/index.js');
|
||||||
|
const subcommand = flags._[3]?.toString();
|
||||||
|
await update(subcommand, { flags });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logging: LogOptions = {
|
||||||
|
dest: nodeLogDestination,
|
||||||
|
level: 'info',
|
||||||
|
};
|
||||||
if (flags.verbose) {
|
if (flags.verbose) {
|
||||||
logging.level = 'debug';
|
logging.level = 'debug';
|
||||||
enableVerboseLogging();
|
enableVerboseLogging();
|
||||||
|
@ -196,39 +159,15 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
|
||||||
logging.level = 'silent';
|
logging.level = 'silent';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special CLI Commands: "add", "docs", "telemetry"
|
// These commands can also be run directly without parsing the user config,
|
||||||
// These commands run before the user's config is parsed, and may have other special
|
// but they rely on parsing the `logging` first.
|
||||||
// conditions that should be handled here, before the others.
|
|
||||||
//
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 'add': {
|
case 'add': {
|
||||||
const { default: add } = await import('../core/add/index.js');
|
|
||||||
|
|
||||||
telemetry.record(event.eventCliSession(cmd));
|
telemetry.record(event.eventCliSession(cmd));
|
||||||
|
const { add } = await import('./add/index.js');
|
||||||
const packages = flags._.slice(3) as string[];
|
const packages = flags._.slice(3) as string[];
|
||||||
return await add(packages, { cwd: root, flags, logging });
|
await add(packages, { cwd: root, flags, logging });
|
||||||
}
|
return;
|
||||||
case 'docs': {
|
|
||||||
telemetry.record(event.eventCliSession(cmd));
|
|
||||||
if (flags.help || flags.h) {
|
|
||||||
printHelp({
|
|
||||||
commandName: 'astro docs',
|
|
||||||
tables: {
|
|
||||||
Flags: [['--help (-h)', 'See all available flags.']],
|
|
||||||
},
|
|
||||||
description: `Launches the Astro Docs website directly from the terminal.`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return await openInBrowser('https://docs.astro.build/');
|
|
||||||
}
|
|
||||||
case 'telemetry': {
|
|
||||||
const telemetryHandler = await import('./telemetry.js');
|
|
||||||
|
|
||||||
// Do not track session start, since the user may be trying to enable,
|
|
||||||
// disable, or modify telemetry settings.
|
|
||||||
const subcommand = flags._[3]?.toString();
|
|
||||||
return await telemetryHandler.update(subcommand, { flags });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +180,6 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
|
||||||
cwd: root,
|
cwd: root,
|
||||||
flags,
|
flags,
|
||||||
cmd,
|
cmd,
|
||||||
logging,
|
|
||||||
}).catch(async (e) => {
|
}).catch(async (e) => {
|
||||||
await handleConfigError(e, { cmd, cwd: root, flags, logging });
|
await handleConfigError(e, { cmd, cwd: root, flags, logging });
|
||||||
return {} as any;
|
return {} as any;
|
||||||
|
|
53
packages/astro/src/cli/info/index.ts
Normal file
53
packages/astro/src/cli/info/index.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
import { arch, platform } from 'node:os';
|
||||||
|
import * as colors from 'kleur/colors';
|
||||||
|
import whichPm from 'which-pm';
|
||||||
|
import type yargs from 'yargs-parser';
|
||||||
|
import { openConfig } from '../../core/config/index.js';
|
||||||
|
import { ASTRO_VERSION } from '../../core/constants.js';
|
||||||
|
|
||||||
|
interface InfoOptions {
|
||||||
|
cwd?: string;
|
||||||
|
flags: yargs.Arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function printInfo({ cwd, flags }: InfoOptions) {
|
||||||
|
const packageManager = await whichPm(process.cwd());
|
||||||
|
let adapter = "Couldn't determine.";
|
||||||
|
let integrations = [];
|
||||||
|
|
||||||
|
const MAX_PADDING = 25;
|
||||||
|
function printRow(label: string, value: string) {
|
||||||
|
const padding = MAX_PADDING - label.length;
|
||||||
|
console.log(`${colors.bold(label)}` + ' '.repeat(padding) + `${colors.green(value)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { userConfig } = await openConfig({
|
||||||
|
cwd,
|
||||||
|
flags,
|
||||||
|
cmd: 'info',
|
||||||
|
});
|
||||||
|
if (userConfig.adapter?.name) {
|
||||||
|
adapter = userConfig.adapter.name;
|
||||||
|
}
|
||||||
|
if (userConfig.integrations) {
|
||||||
|
integrations = (userConfig?.integrations ?? [])
|
||||||
|
.filter(Boolean)
|
||||||
|
.flat()
|
||||||
|
.map((i: any) => i?.name);
|
||||||
|
}
|
||||||
|
} catch (_e) {}
|
||||||
|
console.log();
|
||||||
|
const packageManagerName = packageManager?.name ?? "Couldn't determine.";
|
||||||
|
printRow('Astro version', `v${ASTRO_VERSION}`);
|
||||||
|
printRow('Package manager', packageManagerName);
|
||||||
|
printRow('Platform', platform());
|
||||||
|
printRow('Architecture', arch());
|
||||||
|
printRow('Adapter', adapter);
|
||||||
|
let integrationsString = "None or couldn't determine.";
|
||||||
|
if (integrations.length > 0) {
|
||||||
|
integrationsString = integrations.join(', ');
|
||||||
|
}
|
||||||
|
printRow('Integrations', integrationsString);
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import type yargs from 'yargs-parser';
|
import type yargs from 'yargs-parser';
|
||||||
import * as msg from '../core/messages.js';
|
import * as msg from '../../core/messages.js';
|
||||||
import { telemetry } from '../events/index.js';
|
import { telemetry } from '../../events/index.js';
|
||||||
|
|
||||||
export interface TelemetryOptions {
|
interface TelemetryOptions {
|
||||||
flags: yargs.Arguments;
|
flags: yargs.Arguments;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,7 @@ export function getViteConfig(inlineConfig: UserConfig) {
|
||||||
dest: nodeLogDestination,
|
dest: nodeLogDestination,
|
||||||
level: 'info',
|
level: 'info',
|
||||||
};
|
};
|
||||||
const { astroConfig: config } = await openConfig({
|
const { astroConfig: config } = await openConfig({ cmd });
|
||||||
cmd,
|
|
||||||
logging,
|
|
||||||
});
|
|
||||||
const settings = createSettings(config, inlineConfig.root);
|
const settings = createSettings(config, inlineConfig.root);
|
||||||
await runHookConfigSetup({ settings, command: cmd, logging });
|
await runHookConfigSetup({ settings, command: cmd, logging });
|
||||||
const viteConfig = await createVite(
|
const viteConfig = await createVite(
|
||||||
|
|
|
@ -7,7 +7,6 @@ import path from 'path';
|
||||||
import { fileURLToPath, pathToFileURL } from 'url';
|
import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import { mergeConfig as mergeViteConfig } from 'vite';
|
import { mergeConfig as mergeViteConfig } from 'vite';
|
||||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||||
import type { LogOptions } from '../logger/core.js';
|
|
||||||
import { arraify, isObject, isURL } from '../util.js';
|
import { arraify, isObject, isURL } from '../util.js';
|
||||||
import { createRelativeSchema } from './schema.js';
|
import { createRelativeSchema } from './schema.js';
|
||||||
import { loadConfigWithVite } from './vite-load.js';
|
import { loadConfigWithVite } from './vite-load.js';
|
||||||
|
@ -163,7 +162,6 @@ interface LoadConfigOptions {
|
||||||
flags?: Flags;
|
flags?: Flags;
|
||||||
cmd: string;
|
cmd: string;
|
||||||
validate?: boolean;
|
validate?: boolean;
|
||||||
logging: LogOptions;
|
|
||||||
/** Invalidate when reloading a previously loaded config */
|
/** Invalidate when reloading a previously loaded config */
|
||||||
isRestart?: boolean;
|
isRestart?: boolean;
|
||||||
fsMod?: typeof fs;
|
fsMod?: typeof fs;
|
||||||
|
|
|
@ -87,7 +87,6 @@ export async function restartContainer({
|
||||||
cwd: resolvedRoot,
|
cwd: resolvedRoot,
|
||||||
flags,
|
flags,
|
||||||
cmd: 'dev',
|
cmd: 'dev',
|
||||||
logging,
|
|
||||||
isRestart: true,
|
isRestart: true,
|
||||||
fsMod: container.fs,
|
fsMod: container.fs,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue