diff --git a/packages/create-redwood-app/package.json b/packages/create-redwood-app/package.json index 34c732b077a1..4ce7ac605d72 100644 --- a/packages/create-redwood-app/package.json +++ b/packages/create-redwood-app/package.json @@ -35,6 +35,7 @@ "semver": "7.5.3", "systeminformation": "5.18.5", "terminal-link": "2.1.1", + "untildify": "4.0.0", "uuid": "9.0.0", "yargs": "17.7.2" }, diff --git a/packages/create-redwood-app/src/create-redwood-app.js b/packages/create-redwood-app/src/create-redwood-app.js index 82b17363bdd3..f40fb0fd3c65 100644 --- a/packages/create-redwood-app/src/create-redwood-app.js +++ b/packages/create-redwood-app/src/create-redwood-app.js @@ -3,12 +3,12 @@ import path from 'path' import { trace, SpanStatusCode } from '@opentelemetry/api' -import chalk from 'chalk' import checkNodeVersionCb from 'check-node-version' import execa from 'execa' import fs from 'fs-extra' import semver from 'semver' import terminalLink from 'terminal-link' +import untildify from 'untildify' import { hideBin, Parser } from 'yargs/helpers' import yargs from 'yargs/yargs' @@ -404,6 +404,46 @@ async function initializeGit(newAppDir, commitMessage) { tui.stopReactive() } +async function handleTargetDirPreference(targetDir) { + if (targetDir) { + tui.drawText( + `${RedwoodStyling.green( + '✔' + )} Creating your Redwood app in ${targetDir} based on command line argument` + ) + + return targetDir + } + + // Prompt user for preference + try { + const response = await tui.prompt({ + type: 'input', + name: 'targetDir', + message: 'Where would you like to create your Redwood app?', + initial: 'my-redwood-app', + }) + + if (/^~\w/.test(response.targetDir)) { + tui.stopReactive(true) + tui.displayError( + 'The `~username` syntax is not supported here', + 'Please use the full path or specify the target directory on the command line.' + ) + + recordErrorViaTelemetry('Target dir prompt path syntax not supported') + await shutdownTelemetry() + process.exit(1) + } + + return untildify(response.targetDir) + } catch { + recordErrorViaTelemetry('User cancelled install at target dir prompt') + await shutdownTelemetry() + process.exit(1) + } +} + async function handleTypescriptPreference(typescriptFlag) { // Handle case where flag is set if (typescriptFlag !== null) { @@ -603,35 +643,15 @@ async function createRedwoodApp() { trace.getActiveSpan()?.setAttribute('overwrite', overwrite) // Get the directory for installation from the args - const targetDir = String(args).replace(/,/g, '-') + let targetDir = String(args).replace(/,/g, '-') - // Throw an error if there is no target directory specified - if (!targetDir) { - tui.displayError( - 'No target directory specified', - [ - 'Please specify the project directory', - ` ${chalk.cyan('yarn create redwood-app')} ${chalk.green( - '' - )}`, - '', - 'For example:', - ` ${chalk.cyan('yarn create redwood-app')} ${chalk.green( - 'my-redwood-app' - )}`, - ].join('\n') - ) - recordErrorViaTelemetry('No target directory specified') - await shutdownTelemetry() - process.exit(1) - } - - const newAppDir = path.resolve(process.cwd(), targetDir) const templatesDir = path.resolve(__dirname, '../templates') // Engine check await executeCompatibilityCheck(path.join(templatesDir, 'ts')) + targetDir = await handleTargetDirPreference(targetDir) + // Determine ts/js preference const useTypescript = await handleTypescriptPreference(typescriptFlag) trace.getActiveSpan()?.setAttribute('typescript', useTypescript) @@ -654,6 +674,8 @@ async function createRedwoodApp() { yarnInstall = await handleYarnInstallPreference(yarnInstallFlag) } + const newAppDir = path.resolve(process.cwd(), targetDir) + // Create project files await createProjectFiles(newAppDir, { templateDir, overwrite }) diff --git a/yarn.lock b/yarn.lock index e04d4ceea42f..31fcf80ef378 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14998,6 +14998,7 @@ __metadata: semver: 7.5.3 systeminformation: 5.18.5 terminal-link: 2.1.1 + untildify: 4.0.0 uuid: 9.0.0 yargs: 17.7.2 bin: @@ -30769,7 +30770,7 @@ __metadata: languageName: node linkType: hard -"untildify@npm:^4.0.0": +"untildify@npm:4.0.0, untildify@npm:^4.0.0": version: 4.0.0 resolution: "untildify@npm:4.0.0" checksum: d758e624c707d49f76f7511d75d09a8eda7f2020d231ec52b67ff4896bcf7013be3f9522d8375f57e586e9a2e827f5641c7e06ee46ab9c435fc2b2b2e9de517a