diff --git a/.changeset/chatty-penguins-sin.md b/.changeset/chatty-penguins-sin.md new file mode 100644 index 000000000000..5c6a1bdf0d72 --- /dev/null +++ b/.changeset/chatty-penguins-sin.md @@ -0,0 +1,5 @@ +--- +'create-astro': minor +--- + +Improves the `create astro` CLI experience by asking all the questions upfront, then creating your new Astro project based on your responses. diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 417ebc08447a..9a62aca78b63 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -31,7 +31,7 @@ "//a": "MOST PACKAGES SHOULD GO IN DEV_DEPENDENCIES! THEY WILL BE BUNDLED.", "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES", "dependencies": { - "@astrojs/cli-kit": "^0.3.1", + "@astrojs/cli-kit": "^0.4.0", "giget": "1.1.3" }, "devDependencies": { diff --git a/packages/create-astro/src/actions/context.ts b/packages/create-astro/src/actions/context.ts index a7f2e6d8c71d..7a401162544d 100644 --- a/packages/create-astro/src/actions/context.ts +++ b/packages/create-astro/src/actions/context.ts @@ -1,4 +1,4 @@ -import { prompt } from '@astrojs/cli-kit'; +import { prompt, type Task } from '@astrojs/cli-kit'; import { random } from '@astrojs/cli-kit/utils'; import arg from 'arg'; import os from 'node:os'; @@ -26,6 +26,7 @@ export interface Context { stdout?: typeof process.stdout; exit(code: number): never; hat?: string; + tasks: Task[]; } export async function getContext(argv: string[]): Promise { @@ -103,6 +104,7 @@ export async function getContext(argv: string[]): Promise { exit(code) { process.exit(code); }, + tasks: [], }; return context; } diff --git a/packages/create-astro/src/actions/dependencies.ts b/packages/create-astro/src/actions/dependencies.ts index 26557d5a2f1d..e420fcb716e3 100644 --- a/packages/create-astro/src/actions/dependencies.ts +++ b/packages/create-astro/src/actions/dependencies.ts @@ -1,12 +1,12 @@ import { color } from '@astrojs/cli-kit'; import fs from 'node:fs'; import path from 'node:path'; -import { error, info, spinner, title } from '../messages.js'; +import { error, info, title } from '../messages.js'; import { shell } from '../shell.js'; import type { Context } from './context.js'; export async function dependencies( - ctx: Pick + ctx: Pick ) { let deps = ctx.install ?? ctx.yes; if (deps === undefined) { @@ -24,8 +24,9 @@ export async function dependencies( if (ctx.dryRun) { await info('--dry-run', `Skipping dependency installation`); } else if (deps) { - await spinner({ - start: `Installing dependencies with ${ctx.packageManager}...`, + ctx.tasks.push({ + pending: 'Dependencies', + start: `Dependencies installing with ${ctx.packageManager}...`, end: 'Dependencies installed', onError: (e) => { error('error', e); diff --git a/packages/create-astro/src/actions/git.ts b/packages/create-astro/src/actions/git.ts index dd703b1f559c..bd038f3f5236 100644 --- a/packages/create-astro/src/actions/git.ts +++ b/packages/create-astro/src/actions/git.ts @@ -3,10 +3,12 @@ import path from 'node:path'; import type { Context } from './context.js'; import { color } from '@astrojs/cli-kit'; -import { error, info, spinner, title } from '../messages.js'; +import { error, info, title } from '../messages.js'; import { shell } from '../shell.js'; -export async function git(ctx: Pick) { +export async function git( + ctx: Pick +) { if (fs.existsSync(path.join(ctx.cwd, '.git'))) { await info('Nice!', `Git has already been initialized`); return; @@ -26,7 +28,8 @@ export async function git(ctx: Pick diff --git a/packages/create-astro/src/actions/template.ts b/packages/create-astro/src/actions/template.ts index bdb32607692b..fa88fd503044 100644 --- a/packages/create-astro/src/actions/template.ts +++ b/packages/create-astro/src/actions/template.ts @@ -4,10 +4,10 @@ import { color } from '@astrojs/cli-kit'; import { downloadTemplate } from 'giget'; import fs from 'node:fs'; import path from 'node:path'; -import { error, info, spinner, title } from '../messages.js'; +import { error, info, title } from '../messages.js'; export async function template( - ctx: Pick + ctx: Pick ) { if (!ctx.template && ctx.yes) ctx.template = 'basics'; @@ -32,7 +32,8 @@ export async function template( if (ctx.dryRun) { await info('--dry-run', `Skipping template copying`); } else if (ctx.template) { - await spinner({ + ctx.tasks.push({ + pending: 'Template', start: 'Template copying...', end: 'Template copied', while: () => diff --git a/packages/create-astro/src/actions/typescript.ts b/packages/create-astro/src/actions/typescript.ts index 2c0d21e89bcb..0ac1c753d50c 100644 --- a/packages/create-astro/src/actions/typescript.ts +++ b/packages/create-astro/src/actions/typescript.ts @@ -4,12 +4,20 @@ import { color } from '@astrojs/cli-kit'; import { readFile, rm, writeFile } from 'node:fs/promises'; import path from 'node:path'; import stripJsonComments from 'strip-json-comments'; -import { error, info, spinner, title, typescriptByDefault } from '../messages.js'; +import { error, info, title, typescriptByDefault } from '../messages.js'; import { shell } from '../shell.js'; type PickedTypeScriptContext = Pick< Context, - 'typescript' | 'yes' | 'prompt' | 'dryRun' | 'cwd' | 'exit' | 'packageManager' | 'install' + | 'typescript' + | 'yes' + | 'prompt' + | 'dryRun' + | 'cwd' + | 'exit' + | 'packageManager' + | 'install' + | 'tasks' >; export async function typescript(ctx: PickedTypeScriptContext) { @@ -61,7 +69,8 @@ export async function typescript(ctx: PickedTypeScriptContext) { if (ts === 'relaxed' || ts === 'default') { ts = 'base'; } - await spinner({ + ctx.tasks.push({ + pending: 'TypeScript', start: 'TypeScript customizing...', end: 'TypeScript customized', while: () => diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index f641e876e414..2ffdd00b7dd3 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -10,6 +10,7 @@ import { template } from './actions/template.js'; import { setupTypeScript, typescript } from './actions/typescript.js'; import { verify } from './actions/verify.js'; import { setStdout } from './messages.js'; +import { tasks } from '@astrojs/cli-kit'; const exit = () => process.exit(0); process.on('SIGINT', exit); @@ -43,12 +44,23 @@ export async function main() { // Steps which write to files need to go above git git, - next, ]; for (const step of steps) { await step(ctx); } + + // eslint-disable-next-line no-console + console.log(''); + + const labels = { + start: 'Project initializing...', + end: 'Project initialized!', + }; + await tasks(labels, ctx.tasks); + + await next(ctx); + process.exit(0); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b995a2002c3e..ea42a5abe7ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3713,8 +3713,8 @@ importers: packages/create-astro: dependencies: '@astrojs/cli-kit': - specifier: ^0.3.1 - version: 0.3.1 + specifier: ^0.4.0 + version: 0.4.0 giget: specifier: 1.1.3 version: 1.1.3 @@ -5235,8 +5235,8 @@ packages: sisteransi: 1.0.5 dev: false - /@astrojs/cli-kit@0.3.1: - resolution: {integrity: sha512-BEzf3gudr4XrrrInJKD+GSS5O+GXRTukLUpOfgqdTSq6d48EWVhigNHobmlQGbpa9FEAw+sZmvmHmhS29QhnwA==} + /@astrojs/cli-kit@0.4.0: + resolution: {integrity: sha512-M7R2Af/Gh13pwZ2zjTkTPt87x4IjRw/bSRCmjJGWEGeW3nLNzuEeRY8tleeIGbbfUsm3DJg+UF5rCrQGoviHgQ==} engines: {node: '>=18.14.1'} dependencies: chalk: 5.3.0