wip
This commit is contained in:
parent
c3d41d1f60
commit
ee5b66e298
8 changed files with 112 additions and 124 deletions
5
.changeset/lucky-apes-yell.md
Normal file
5
.changeset/lucky-apes-yell.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Update "astro add" output to remove confusing multi-select prompt.
|
5
.changeset/perfect-drinks-fold.md
Normal file
5
.changeset/perfect-drinks-fold.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Update the help output to improve formatting
|
|
@ -37,26 +37,27 @@ type CLICommand =
|
|||
function printAstroHelp() {
|
||||
printHelp({
|
||||
commandName: 'astro',
|
||||
usage: '[command] [...flags]',
|
||||
headline: 'Futuristic web development tool.',
|
||||
commands: [
|
||||
['add', 'Add an integration to your configuration.'],
|
||||
['docs', "Launch Astro's Doc site directly from the terminal. "],
|
||||
['dev', 'Run Astro in development mode.'],
|
||||
['build', 'Build a pre-compiled production-ready site.'],
|
||||
['preview', 'Preview your build locally before deploying.'],
|
||||
['check', 'Check your project for errors.'],
|
||||
['telemetry', 'Enable/disable anonymous data collection.'],
|
||||
['--version', 'Show the version number and exit.'],
|
||||
['--help', 'Show this help message.'],
|
||||
],
|
||||
flags: [
|
||||
['--host [optional IP]', 'Expose server on network'],
|
||||
['--config <path>', 'Specify the path to the Astro config file.'],
|
||||
['--root <path>', 'Specify the path to the project root folder.'],
|
||||
['--drafts', 'Include markdown draft pages in the build.'],
|
||||
['--verbose', 'Enable verbose logging'],
|
||||
['--silent', 'Disable logging'],
|
||||
],
|
||||
tables: {
|
||||
Commands: [
|
||||
['add', 'Add an integration.'],
|
||||
['build', 'Build your project and write it to disk.'],
|
||||
['check', 'Check your project for errors.'],
|
||||
['dev', 'Start the development server.'],
|
||||
['docs', "Open documentation in your web browser."],
|
||||
['preview', 'Preview your build locally.'],
|
||||
['telemetry', 'Configure telemetry settings.'],
|
||||
],
|
||||
'Global Flags': [
|
||||
['--config <path>', 'Specify your config file.'],
|
||||
['--root <path>', 'Specify your project root folder.'],
|
||||
['--verbose', 'Enable verbose logging.'],
|
||||
['--silent', 'Disable all logging.'],
|
||||
['--version', 'Show the version number and exit.'],
|
||||
['--help', 'Show this help message.'],
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,14 @@ export async function update(subcommand: string, { flags, telemetry }: Telemetry
|
|||
if (flags.help || !isValid) {
|
||||
msg.printHelp({
|
||||
commandName: 'astro telemetry',
|
||||
usage: '<enable|disable|reset>',
|
||||
commands: [
|
||||
['enable', 'Enable anonymous data collection.'],
|
||||
['disable', 'Disable anonymous data collection.'],
|
||||
['reset', 'Reset anonymous data collection settings.'],
|
||||
],
|
||||
usage: '[command]',
|
||||
tables: {
|
||||
Commands: [
|
||||
['enable', 'Enable anonymous data collection.'],
|
||||
['disable', 'Disable anonymous data collection.'],
|
||||
['reset', 'Reset anonymous data collection settings.'],
|
||||
],
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
export const FIRST_PARTY_FRAMEWORKS = [
|
||||
{ value: 'react', title: 'React' },
|
||||
{ value: 'preact', title: 'Preact' },
|
||||
{ value: 'vue', title: 'Vue' },
|
||||
{ value: 'svelte', title: 'Svelte' },
|
||||
{ value: 'solid-js', title: 'Solid' },
|
||||
{ value: 'lit', title: 'Lit' },
|
||||
];
|
||||
export const FIRST_PARTY_ADDONS = [
|
||||
{ value: 'tailwind', title: 'Tailwind' },
|
||||
{ value: 'turbolinks', title: 'Turbolinks' },
|
||||
{ value: 'partytown', title: 'Partytown' },
|
||||
{ value: 'sitemap', title: 'Sitemap' },
|
||||
];
|
||||
export const ALIASES = new Map([
|
||||
['solid', 'solid-js'],
|
||||
['tailwindcss', 'tailwind'],
|
||||
]);
|
||||
export const CONFIG_STUB = `import { defineConfig } from 'astro/config';\n\nexport default defineConfig({});`;
|
||||
export const TAILWIND_CONFIG_STUB = `/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}\n`;
|
|
@ -11,14 +11,13 @@ import prompts from 'prompts';
|
|||
import { fileURLToPath, pathToFileURL } from 'url';
|
||||
import type yargs from 'yargs-parser';
|
||||
import { resolveConfigURL } from '../config.js';
|
||||
import { debug, error, info, LogOptions } from '../logger/core.js';
|
||||
import { debug, info, LogOptions } from '../logger/core.js';
|
||||
import * as msg from '../messages.js';
|
||||
import { printHelp } from '../messages.js';
|
||||
import { appendForwardSlash } from '../path.js';
|
||||
import { apply as applyPolyfill } from '../polyfill.js';
|
||||
import { parseNpmName } from '../util.js';
|
||||
import { generate, parse, t, visit } from './babel.js';
|
||||
import * as CONSTS from './consts.js';
|
||||
import { ensureImport } from './imports.js';
|
||||
import { wrapDefaultExport } from './wrapper.js';
|
||||
|
||||
|
@ -34,71 +33,71 @@ export interface IntegrationInfo {
|
|||
packageName: string;
|
||||
dependencies: [name: string, version: string][];
|
||||
}
|
||||
const ALIASES = new Map([
|
||||
['solid', 'solid-js'],
|
||||
['tailwindcss', 'tailwind'],
|
||||
]);
|
||||
const ASTRO_CONFIG_STUB = `import { defineConfig } from 'astro/config';\n\ndefault defineConfig({});`;
|
||||
const TAILWIND_CONFIG_STUB = `/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}\n`;
|
||||
|
||||
export default async function add(names: string[], { cwd, flags, logging, telemetry }: AddOptions) {
|
||||
if (flags.help) {
|
||||
if (flags.help || names.length === 0) {
|
||||
printHelp({
|
||||
commandName: 'astro add',
|
||||
usage: '[FLAGS] [INTEGRATIONS...]',
|
||||
flags: [
|
||||
['--yes', 'Add the integration without user interaction.'],
|
||||
['--help', 'Show this help message.'],
|
||||
],
|
||||
usage: '[integration]',
|
||||
tables: {
|
||||
Flags: [
|
||||
['--yes', 'Accept all prompts.'],
|
||||
['--help', 'Show this help message.'],
|
||||
],
|
||||
'Recommended: UI Frameworks': [
|
||||
['react', 'astro add react'],
|
||||
['preact', 'astro add preact'],
|
||||
['vue', 'astro add vue'],
|
||||
['svelte', 'astro add svelte'],
|
||||
['solid-js', 'astro add solid-js'],
|
||||
['lit', 'astro add lit'],
|
||||
],
|
||||
'Recommended: Integrations': [
|
||||
['tailwind', 'astro add tailwind'],
|
||||
['partytown', 'astro add partytown'],
|
||||
['sitemap', 'astro add sitemap'],
|
||||
],
|
||||
},
|
||||
description: `For more integrations, check out: ${cyan('https://astro.build/integrations')}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
let configURL: URL | undefined;
|
||||
const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd());
|
||||
// TODO: improve error handling for invalid configs
|
||||
configURL = await resolveConfigURL({ cwd, flags });
|
||||
|
||||
if (configURL?.pathname.endsWith('package.json')) {
|
||||
throw new Error(
|
||||
`Unable to use astro add with package.json#astro configuration! Try migrating to \`astro.config.mjs\` and try again.`
|
||||
);
|
||||
}
|
||||
applyPolyfill();
|
||||
|
||||
// If no integrations were given, prompt the user for some popular ones.
|
||||
if (names.length === 0) {
|
||||
const response = await prompts([
|
||||
{
|
||||
type: 'multiselect',
|
||||
name: 'frameworks',
|
||||
message: 'What frameworks would you like to enable?',
|
||||
instructions: '\n Space to select. Return to submit',
|
||||
choices: CONSTS.FIRST_PARTY_FRAMEWORKS,
|
||||
},
|
||||
{
|
||||
type: 'multiselect',
|
||||
name: 'addons',
|
||||
message: 'What additional integrations would you like to enable?',
|
||||
instructions: '\n Space to select. Return to submit',
|
||||
choices: CONSTS.FIRST_PARTY_ADDONS,
|
||||
},
|
||||
]);
|
||||
|
||||
names = [...(response.frameworks ?? []), ...(response.addons ?? [])];
|
||||
}
|
||||
|
||||
// If still empty after prompting, exit gracefully.
|
||||
if (names.length === 0) {
|
||||
error(logging, null, `No integrations specified.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Some packages might have a common alias! We normalize those here.
|
||||
names = names.map((name) => (CONSTS.ALIASES.has(name) ? CONSTS.ALIASES.get(name)! : name));
|
||||
|
||||
|
||||
if (configURL) {
|
||||
debug('add', `Found config at ${configURL}`);
|
||||
} else {
|
||||
info(logging, 'add', `Unable to locate a config file, generating one for you.`);
|
||||
configURL = new URL('./astro.config.mjs', appendForwardSlash(root.href));
|
||||
await fs.writeFile(fileURLToPath(configURL), CONSTS.CONFIG_STUB, { encoding: 'utf-8' });
|
||||
await fs.writeFile(fileURLToPath(configURL), ASTRO_CONFIG_STUB, { encoding: 'utf-8' });
|
||||
}
|
||||
|
||||
const integrations = await validateIntegrations(names);
|
||||
// TODO: improve error handling for invalid configs
|
||||
if (configURL?.pathname.endsWith('package.json')) {
|
||||
throw new Error(
|
||||
`Unable to use "astro add" with package.json configuration. Try migrating to \`astro.config.mjs\` and try again.`
|
||||
);
|
||||
}
|
||||
|
||||
// Some packages might have a common alias! We normalize those here.
|
||||
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
|
||||
const integrations = await validateIntegrations(integrationNames);
|
||||
|
||||
let ast: t.File | null = null;
|
||||
try {
|
||||
|
@ -194,7 +193,7 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
|
|||
if (await askToContinue({ flags })) {
|
||||
await fs.writeFile(
|
||||
fileURLToPath(new URL('./tailwind.config.cjs', configURL)),
|
||||
CONSTS.TAILWIND_CONFIG_STUB,
|
||||
TAILWIND_CONFIG_STUB,
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
debug('add', `Generated default ./tailwind.config.cjs file`);
|
||||
|
|
|
@ -126,6 +126,7 @@ export const logger = {
|
|||
|
||||
export function enableVerboseLogging() {
|
||||
//debugPackage.enable('*,-babel');
|
||||
console.log('ah!');
|
||||
debug('cli', '--verbose flag enabled! Enabling: DEBUG="*,-babel"');
|
||||
debug(
|
||||
'cli',
|
||||
|
|
|
@ -248,29 +248,28 @@ export function printHelp({
|
|||
commandName,
|
||||
headline,
|
||||
usage,
|
||||
commands,
|
||||
flags,
|
||||
tables,
|
||||
description,
|
||||
}: {
|
||||
commandName: string;
|
||||
headline?: string;
|
||||
usage?: string;
|
||||
commands?: [command: string, help: string][];
|
||||
flags?: [flag: string, help: string][];
|
||||
tables?: Record<string, [command: string, help: string][]>;
|
||||
description?: string,
|
||||
}) {
|
||||
const linebreak = () => '';
|
||||
const title = (label: string) => ` ${bgWhite(black(` ${label} `))}`;
|
||||
const table = (rows: [string, string][], opts: { padding: number; prefix: string }) => {
|
||||
const split = rows.some((row) => {
|
||||
const message = `${opts.prefix}${' '.repeat(opts.padding)}${row[1]}`;
|
||||
return message.length > process.stdout.columns;
|
||||
});
|
||||
|
||||
const table = (rows: [string, string][], { padding }: { padding: number }) => {
|
||||
const split = process.stdout.columns < 60;
|
||||
let raw = '';
|
||||
|
||||
for (const row of rows) {
|
||||
raw += `${opts.prefix}${bold(`${row[0]}`.padStart(opts.padding - opts.prefix.length))}`;
|
||||
if (split) raw += '\n ';
|
||||
raw += ' ' + dim(row[1]) + '\n';
|
||||
if (split) {
|
||||
raw += ` ${row[0]}\n `;
|
||||
} else {
|
||||
raw += `${(`${row[0]}`.padStart(padding))}`;
|
||||
}
|
||||
raw += ' ' + dim(row[1]) + '\n';
|
||||
}
|
||||
|
||||
return raw.slice(0, -1); // remove latest \n
|
||||
|
@ -291,18 +290,21 @@ export function printHelp({
|
|||
message.push(linebreak(), ` ${green(commandName)} ${bold(usage)}`);
|
||||
}
|
||||
|
||||
if (commands) {
|
||||
message.push(
|
||||
linebreak(),
|
||||
title('Commands'),
|
||||
table(commands, { padding: 28, prefix: ` ${commandName || 'astro'} ` })
|
||||
);
|
||||
if (tables) {
|
||||
function calculateTablePadding(rows: [string, string][]) {
|
||||
return rows.reduce((val, [first]) => Math.max(val, first.length), 0) + 2;
|
||||
};
|
||||
const tableEntries = Object.entries(tables);
|
||||
const padding = Math.max(...tableEntries.map(([, rows]) => calculateTablePadding(rows)));
|
||||
for (const [tableTitle, tableRows] of tableEntries) {
|
||||
message.push(linebreak(), title(tableTitle), table(tableRows, { padding }));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
message.push(linebreak(), title('Flags'), table(flags, { padding: 28, prefix: ' ' }));
|
||||
if (description) {
|
||||
message.push(linebreak(), `${description}`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(message.join('\n'));
|
||||
console.log(message.join('\n') + '\n');
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue