From 5af397fbd60a0378723aa2b4f64132ca1b6a49f8 Mon Sep 17 00:00:00 2001 From: "Irsyad A. Panjaitan" Date: Sun, 22 Dec 2024 17:41:09 +0700 Subject: [PATCH] refactor: don't ask anything if flag -y used --- src/commands/init.ts | 45 +++++++++++++------ src/commands/start-new-project/index.ts | 21 ++++++--- .../partials/create-project.ts | 9 ++-- src/utils/git.ts | 9 ++-- src/utils/index.ts | 10 ++++- 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/commands/init.ts b/src/commands/init.ts index 6daf1ce..211d851 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -124,46 +124,63 @@ export async function init(flags: { force?: boolean; yes?: boolean }) { } async function getUserAlias(): Promise { - const tsConfigPath = path.join(process.cwd(), "tsconfig.json") + const tsConfigPaths = [path.join(process.cwd(), "tsconfig.app.json"), path.join(process.cwd(), "tsconfig.json")] - if (!fs.existsSync(tsConfigPath)) { - error("tsconfig.json not found.") + let tsConfigPath = tsConfigPaths.find((configPath) => fs.existsSync(configPath)) + let tsConfig + + if (!tsConfigPath) { + error("Neither tsconfig.app.json nor tsconfig.json was found.") process.exit(1) } - let tsConfig try { const tsConfigRaw = fs.readFileSync(tsConfigPath, "utf8") const stripped = stripJsonComments(tsConfigRaw) tsConfig = JSON.parse(stripped) } catch { - error("Error reading tsconfig.json file. Please check if it exists and is valid JSON.") + error(`Error reading ${tsConfigPath} file. Please check if it exists and is valid JSON.`) process.exit(1) } - if (!tsConfig.compilerOptions) tsConfig.compilerOptions = {} + if (!tsConfig.compilerOptions) { + if (tsConfigPath.endsWith("tsconfig.app.json")) { + tsConfigPath = path.join(process.cwd(), "tsconfig.json") + if (!fs.existsSync(tsConfigPath)) { + tsConfig = { compilerOptions: {} } + } else { + const tsConfigRaw = fs.readFileSync(tsConfigPath, "utf8") + const stripped = stripJsonComments(tsConfigRaw) + tsConfig = JSON.parse(stripped) + if (!tsConfig.compilerOptions) tsConfig.compilerOptions = {} + } + } else { + tsConfig.compilerOptions = {} + } + } if (!("paths" in tsConfig.compilerOptions)) { - const rootPath = await input({ - message: "No paths key found in tsconfig.json. Please enter the root directory path for the '@/':", - default: "./" + possibilityRootPath(), - }) + const rootPath = flags.yes + ? "./" + possibilityRootPath() + : await input({ + message: `No paths key found in ${path.basename(tsConfigPath)}. Please enter the root directory path for the '@/':`, + default: "./" + possibilityRootPath(), + }) tsConfig.compilerOptions.paths = { "@/*": [`${rootPath || "./src"}/*`], } - const spinner = ora("Updating tsconfig.json with paths...").start() + const spinner = ora(`Updating ${path.basename(tsConfigPath)} with paths...`).start() try { const updatedTsConfig = JSON.stringify(tsConfig, null, 2) fs.writeFileSync(tsConfigPath, updatedTsConfig) - spinner.succeed("Paths added to tsconfig.json.") + spinner.succeed(`Paths added to ${path.basename(tsConfigPath)}.`) } catch (e) { - spinner.fail("Failed to write to tsconfig.json.") + spinner.fail(`Failed to write to ${path.basename(tsConfigPath)}.`) process.exit(1) } } - await addUiPathToTsConfig() const paths = tsConfig.compilerOptions.paths diff --git a/src/commands/start-new-project/index.ts b/src/commands/start-new-project/index.ts index 4b1a5b1..8e8ed9d 100644 --- a/src/commands/start-new-project/index.ts +++ b/src/commands/start-new-project/index.ts @@ -35,7 +35,7 @@ export async function startNewProject() { default: "Yes", validate: (value) => { const normalizedValue = value.trim().toLowerCase() - return ["y", "n", "Yes", "No", "no", "yes"].includes(normalizedValue) || "Please answer yes or no." + return ["y", "n", "yes", "no"].includes(normalizedValue) || "Please answer yes or no." }, }) @@ -49,7 +49,7 @@ export async function startNewProject() { }) const projectName = await input({ - message: "Enter the name of your new project:", + message: "What is your project named?", default: "app", validate: (value) => value.trim() !== "" || "Project name cannot be empty.", }) @@ -72,7 +72,6 @@ export async function startNewProject() { }) options.usePest = testFramework === "pest" - const composerExists = await checkIfCommandExists("composer") if (!composerExists) { @@ -82,6 +81,18 @@ export async function startNewProject() { } } + if (framework === "next") { + const wantSrcFolder = await input({ + message: `Do you want to have a src folder? (Y/${grayText("n")})`, + default: "Yes", + validate: (value) => { + const normalizedValue = value.trim().toLowerCase() + return ["y", "n", "yes", "no", "Yes", "No"].includes(normalizedValue) || "Please answer yes or no." + }, + }) + options.useSrc = ["y", "yes"].includes(wantSrcFolder.trim().toLowerCase()) + } + /** * This question will be removed when Tailwind v4 is released as stable. */ @@ -90,7 +101,7 @@ export async function startNewProject() { default: "Yes", validate: (value) => { const normalizedValue = value.trim().toLowerCase() - return ["y", "n", "Yes", "No", "no", "yes"].includes(normalizedValue) || "Please answer yes or no." + return ["y", "n", "yes", "no"].includes(normalizedValue) || "Please answer yes or no." }, }) @@ -99,7 +110,7 @@ export async function startNewProject() { default: "Yes", validate: (value) => { const normalizedValue = value.trim().toLowerCase() - return ["y", "n", "Yes", "No", "no", "yes"].includes(normalizedValue) || "Please answer yes or no." + return ["y", "n", "yes", "no"].includes(normalizedValue) || "Please answer yes or no." }, }) diff --git a/src/commands/start-new-project/partials/create-project.ts b/src/commands/start-new-project/partials/create-project.ts index 1b94c38..b57599d 100644 --- a/src/commands/start-new-project/partials/create-project.ts +++ b/src/commands/start-new-project/partials/create-project.ts @@ -27,10 +27,13 @@ export const createLaravelApp = async (packageManager: string, projectName: stri export const createNextApp = async (packageManager: string, projectName: string, options?: FrameworkOptions): Promise => { const packageManagerFlag = packageManager === "bun" ? "--use-bun" : packageManager === "yarn" ? "--use-yarn" : packageManager === "pnpm" ? "--use-pnpm" : "--use-npm" - const commands = ["npx create-next-app@latest", "--yes", packageManagerFlag, projectName] - - commands.push(projectName) + const commands = ["npx create-next-app@latest", projectName, "--ts", "--tailwind", "--turbopack", "--eslint", "--app", "--import-alias='@/*'", packageManagerFlag] + if (options?.useSrc) { + commands.push("--src-dir") + } else { + commands.push("--no-src-dir") + } return commands } diff --git a/src/utils/git.ts b/src/utils/git.ts index 73d08c9..4ab8b07 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -1,18 +1,19 @@ import { execSync } from "node:child_process" +import fs from "fs" /** * This function is used to check if the current git repository is dirty * @returns boolean */ export function isRepoDirty() { + if (!fs.existsSync(".git")) { + return false + } + try { let stdout = execSync("git status --porcelain", { encoding: "utf-8" }) return stdout.trim() !== "" } catch (error) { - /** - * If the error message includes "not a git repository", it means that the current directory is not a git repository. - * In this case, we can assume that the repository is clean. - */ return !error?.toString?.().includes("not a git repository") } } diff --git a/src/utils/index.ts b/src/utils/index.ts index c259291..1ae5a93 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -92,6 +92,14 @@ const tsConfigPath = path.join(process.cwd(), "tsconfig.json") * @returns void */ export async function addUiPathToTsConfig() { + const tsConfigPaths = [path.join(process.cwd(), "tsconfig.app.json"), path.join(process.cwd(), "tsconfig.json")] + + let tsConfigPath = tsConfigPaths.find((configPath) => fs.existsSync(configPath)) + if (!tsConfigPath) { + error("Neither tsconfig.app.json nor tsconfig.json was found.") + process.exit(1) + } + try { const tsConfigContent = fs.readFileSync(tsConfigPath, "utf8") const strippedContent = stripJsonComments(tsConfigContent) @@ -105,6 +113,6 @@ export async function addUiPathToTsConfig() { fs.writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2)) } catch (er) { - error("Error updating tsconfig.json:", er!) + error(`Error updating ${path.basename(tsConfigPath)}:`, er!) } }