Skip to content

Commit

Permalink
SImplify "astro add" by removing confusing multi-select (#3715)
Browse files Browse the repository at this point in the history
* wip

* update create-astro for new astro add

* update copy

* update git prompt

* Update packages/astro/src/core/logger/node.ts

Co-authored-by: Chris Swithinbank <[email protected]>

* Update packages/create-astro/test/install-step.test.js

Co-authored-by: Chris Swithinbank <[email protected]>

* update git prompt

* update test

Co-authored-by: Chris Swithinbank <[email protected]>
  • Loading branch information
FredKSchott and delucis authored Jun 27, 2022
1 parent bd4dac0 commit 4d6d864
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 258 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-apes-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Update "astro add" output to remove confusing multi-select prompt.
5 changes: 5 additions & 0 deletions .changeset/perfect-drinks-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Update the help output to improve formatting
39 changes: 20 additions & 19 deletions packages/astro/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.'],
],
},
});
}

Expand Down
14 changes: 8 additions & 6 deletions packages/astro/src/cli/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
27 changes: 0 additions & 27 deletions packages/astro/src/core/add/consts.ts

This file was deleted.

99 changes: 49 additions & 50 deletions packages/astro/src/core/add/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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: '[...integrations]',
tables: {
Flags: [
['--yes', 'Accept all prompts.'],
['--help', 'Show this help message.'],
],
'Example: Add a UI Framework': [
['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'],
],
'Example: Add an Integration': [
['tailwind', 'astro add tailwind'],
['partytown', 'astro add partytown'],
['sitemap', 'astro add sitemap'],
],
},
description: `Check out the full integration catalog: ${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' });
}

// 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.`
);
}

const integrations = await validateIntegrations(names);
// 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 {
Expand Down Expand Up @@ -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`);
Expand Down
46 changes: 24 additions & 22 deletions packages/astro/src/core/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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');
}
2 changes: 1 addition & 1 deletion packages/create-astro/create-astro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

const currentVersion = process.versions.node;
const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10);
const minimumMajorVersion = 12;
const minimumMajorVersion = 14;

if (requiredMajorVersion < minimumMajorVersion) {
console.error(`Node.js v${currentVersion} is out of date and unsupported!`);
Expand Down
Loading

0 comments on commit 4d6d864

Please sign in to comment.