diff --git a/.changeset/serious-pens-matter.md b/.changeset/serious-pens-matter.md new file mode 100644 index 000000000..0569e2ef7 --- /dev/null +++ b/.changeset/serious-pens-matter.md @@ -0,0 +1,5 @@ +--- +'create-astro': minor +--- + +Add "initialize git repository" step to simplify our next steps suggestion. We now give you a one-liner to easily paste in your terminal and start the dev server! diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index 3c4e3e1a0..dab8e7a3b 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import path from 'path'; -import { bold, cyan, gray, green, red, yellow } from 'kleur/colors'; +import { bgCyan, black, bold, cyan, gray, green, red, yellow } from 'kleur/colors'; import prompts from 'prompts'; import degit from 'degit'; import yargs from 'yargs-parser'; @@ -181,19 +181,17 @@ export async function main() { process.exit(0); } - if (installResponse.install) { + if (installResponse.install && !args.dryrun) { const installExec = execa(pkgManager, ['install'], { cwd }); const installingPackagesMsg = `Installing packages${emojiWithFallback(' 📦', '...')}`; spinner = ora({ color: 'green', text: installingPackagesMsg }).start(); - if (!args.dryrun) { - await new Promise((resolve, reject) => { - installExec.stdout?.on('data', function (data) { - spinner.text = `${installingPackagesMsg}\n${bold(`[${pkgManager}]`)} ${data}`; - }); - installExec.on('error', (error) => reject(error)); - installExec.on('close', () => resolve()); + await new Promise((resolve, reject) => { + installExec.stdout?.on('data', function (data) { + spinner.text = `${installingPackagesMsg}\n${bold(`[${pkgManager}]`)} ${data}`; }); - } + installExec.on('error', (error) => reject(error)); + installExec.on('close', () => resolve()); + }); spinner.succeed(); } @@ -227,26 +225,36 @@ export async function main() { ); } - console.log('\nNext steps:'); - let i = 1; - const relative = path.relative(process.cwd(), cwd); - if (relative !== '') { - console.log(` ${i++}: ${bold(cyan(`cd ${relative}`))}`); + const gitResponse = await prompts({ + type: 'confirm', + name: 'git', + message: 'Initialize a git repository?', + initial: true, + }); + + if (!gitResponse) { + process.exit(0); } - if (!installResponse.install) { - console.log(` ${i++}: ${bold(cyan(`${pkgManager} install`))}`); + if (gitResponse.git && !args.dryrun) { + await execaCommand('git init', { cwd }); } - console.log( - ` ${i++}: ${bold( - cyan('git init && git add -A && git commit -m "Initial commit"') - )} (optional step)` - ); - const runCommand = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`; - console.log(` ${i++}: ${bold(cyan(runCommand))}`); + + console.log(`\n${bgCyan(black(' Next steps '))}\n`); + + const relative = path.relative(process.cwd(), cwd); + const startCommand = []; + if (relative !== '') { + startCommand.push(bold(cyan(`cd ${relative}`))); + } + if (!installResponse.install) { + startCommand.push(bold(cyan(`${pkgManager} install`))); + } + startCommand.push(bold(cyan(pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`))); + console.log(startCommand.join(' && ')); console.log(`\nTo close the dev server, hit ${bold(cyan('Ctrl-C'))}`); - console.log(`\nStuck? Visit us at ${cyan('https://astro.build/chat')}\n`); + console.log(`Stuck? Visit us at ${cyan('https://astro.build/chat')}\n`); } function emojiWithFallback(char: string, fallback: string) { diff --git a/packages/create-astro/test/astro-add-step.test.js b/packages/create-astro/test/astro-add-step.test.js index b46d836cc..73d963ed0 100644 --- a/packages/create-astro/test/astro-add-step.test.js +++ b/packages/create-astro/test/astro-add-step.test.js @@ -23,13 +23,14 @@ describe('[create-astro] astro add', function () { }); it('should use "astro add" when user has installed dependencies', function () { - const { stdout, stdin } = setup([tempDir, '--dryrun']); + const { stdout, stdin } = setup([tempDir]); return promiseWithTimeout((resolve) => { const seen = new Set(); const installPrompt = PROMPT_MESSAGES.install('npm'); stdout.on('data', (chunk) => { if (!seen.has(PROMPT_MESSAGES.template) && chunk.includes(PROMPT_MESSAGES.template)) { seen.add(PROMPT_MESSAGES.template); + // respond with "enter key" stdin.write('\x0D'); } if (!seen.has(installPrompt) && chunk.includes(installPrompt)) { @@ -44,17 +45,19 @@ describe('[create-astro] astro add', function () { }); it('should use "npx astro@latest add" when use has NOT installed dependencies', function () { - const { stdout, stdin } = setup([tempDir, '--dryrun']); + const { stdout, stdin } = setup([tempDir]); return promiseWithTimeout((resolve) => { const seen = new Set(); const installPrompt = PROMPT_MESSAGES.install('npm'); stdout.on('data', (chunk) => { if (!seen.has(PROMPT_MESSAGES.template) && chunk.includes(PROMPT_MESSAGES.template)) { seen.add(PROMPT_MESSAGES.template); + // respond with "enter key" stdin.write('\x0D'); } if (!seen.has(installPrompt) && chunk.includes(installPrompt)) { seen.add(installPrompt); + // respond with "no, then enter key" stdin.write('n\x0D'); } if (chunk.includes(PROMPT_MESSAGES.astroAdd('npx astro@latest add --yes'))) { diff --git a/packages/create-astro/test/install-step.test.js b/packages/create-astro/test/install-step.test.js index fbd7f2249..d8219b520 100644 --- a/packages/create-astro/test/install-step.test.js +++ b/packages/create-astro/test/install-step.test.js @@ -21,13 +21,14 @@ describe('[create-astro] install', function () { }); it('should respect package manager in prompt', function () { - const { stdout, stdin } = setup([tempDir, '--dryrun']); + const { stdout, stdin } = setup([tempDir]); return promiseWithTimeout((resolve) => { const seen = new Set(); const installPrompt = PROMPT_MESSAGES.install(FAKE_PACKAGE_MANAGER); stdout.on('data', (chunk) => { if (!seen.has(PROMPT_MESSAGES.template) && chunk.includes(PROMPT_MESSAGES.template)) { seen.add(PROMPT_MESSAGES.template); + // respond with "enter key" stdin.write('\x0D'); } if (!seen.has(installPrompt) && chunk.includes(installPrompt)) { @@ -39,7 +40,7 @@ describe('[create-astro] install', function () { }); it('should respect package manager in next steps', function () { - const { stdout, stdin } = setup([tempDir, '--dryrun']); + const { stdout, stdin } = setup([tempDir]); return promiseWithTimeout((resolve) => { const seen = new Set(); const installPrompt = PROMPT_MESSAGES.install(FAKE_PACKAGE_MANAGER); @@ -47,14 +48,20 @@ describe('[create-astro] install', function () { stdout.on('data', (chunk) => { if (!seen.has(PROMPT_MESSAGES.template) && chunk.includes(PROMPT_MESSAGES.template)) { seen.add(PROMPT_MESSAGES.template); + // respond with "enter key" stdin.write('\x0D'); } if (!seen.has(installPrompt) && chunk.includes(installPrompt)) { seen.add(installPrompt); + // respond with "no, then enter key" stdin.write('n\x0D'); } if (!seen.has(astroAddPrompt) && chunk.includes(astroAddPrompt)) { seen.add(astroAddPrompt); + stdin.write('n\x0D'); + } + if (!seen.has(PROMPT_MESSAGES.git) && chunk.includes(PROMPT_MESSAGES.git)) { + seen.add(PROMPT_MESSAGES.git); stdin.write('\x0D'); } if (chunk.includes('banana dev')) { diff --git a/packages/create-astro/test/utils.js b/packages/create-astro/test/utils.js index 70ad32210..964ae6a20 100644 --- a/packages/create-astro/test/utils.js +++ b/packages/create-astro/test/utils.js @@ -29,10 +29,11 @@ export const PROMPT_MESSAGES = { install: (pkgManager) => `Would you like us to run "${pkgManager} install?"`, astroAdd: (astroAddCommand = 'npx astro@latest add --yes') => `Run "${astroAddCommand}?" This lets you optionally add component frameworks (ex. React), CSS frameworks (ex. Tailwind), and more.`, + git: 'Initialize a git repository?', }; export function setup(args = []) { - const { stdout, stdin } = execa('../create-astro.mjs', args, { cwd: testDir }); + const { stdout, stdin } = execa('../create-astro.mjs', [...args, '--dryrun'], { cwd: testDir }); return { stdin, stdout,