From cc8850d7c2340d1decabe3bd4d3d98ec2e14509d Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 12 Feb 2025 12:49:16 +0530 Subject: [PATCH] feat: add Ctrl+C interrupt handling --- apps/cli/src/create-project.ts | 3 +- apps/cli/src/helpers/db-setup.ts | 13 +++- apps/cli/src/index.ts | 127 ++++++++++++++++++------------- apps/cli/src/utils/logger.ts | 16 ++++ 4 files changed, 101 insertions(+), 58 deletions(-) create mode 100644 apps/cli/src/utils/logger.ts diff --git a/apps/cli/src/create-project.ts b/apps/cli/src/create-project.ts index a929c59..dbb1f79 100644 --- a/apps/cli/src/create-project.ts +++ b/apps/cli/src/create-project.ts @@ -4,6 +4,7 @@ import fs from "fs-extra"; import ora from "ora"; import { setupTurso } from "./helpers/db-setup"; import type { ProjectOptions } from "./types"; +import { logger } from "./utils/logger"; export async function createProject(options: ProjectOptions) { const spinner = ora("Creating project directory...").start(); @@ -41,7 +42,7 @@ export async function createProject(options: ProjectOptions) { console.log(" bun dev"); } catch (error) { spinner.fail("Failed to create project"); - console.error(error); + logger.error("Error during project creation:", error); process.exit(1); } } diff --git a/apps/cli/src/helpers/db-setup.ts b/apps/cli/src/helpers/db-setup.ts index 309c7ed..7826194 100644 --- a/apps/cli/src/helpers/db-setup.ts +++ b/apps/cli/src/helpers/db-setup.ts @@ -4,6 +4,7 @@ import { confirm, input } from "@inquirer/prompts"; import { execa } from "execa"; import fs from "fs-extra"; import ora, { type Ora } from "ora"; +import { logger } from "../utils/logger"; async function isTursoInstalled() { try { @@ -48,10 +49,18 @@ async function installTursoCLI(isMac: boolean, spinner: Ora) { await execa("turso", ["auth", "login"]); spinner.succeed("Logged in to Turso!"); } catch (error) { - console.error(error); + if (error instanceof Error && error.message.includes("User force closed")) { + spinner.stop(); + console.log("\n"); + logger.warn("Turso CLI installation cancelled by user"); + throw error; + } + logger.error("Error during Turso CLI installation:", error); spinner.fail( "Failed to install Turso CLI. Proceeding with manual setup...", ); + + throw error; } } @@ -108,7 +117,7 @@ TURSO_AUTH_TOKEN="${authToken.trim()}"`; spinner.succeed("Turso database configured successfully!"); return; } catch (error) { - console.error(error); + logger.error("Error during Turso database creation:", error); spinner.fail( "Failed to install Turso CLI. Proceeding with manual setup...", ); diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index bdcef47..be7ccea 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -4,74 +4,91 @@ import { Command } from "commander"; import { createProject } from "./create-project"; import { renderTitle } from "./render-title"; import type { ProjectDatabase, ProjectFeature } from "./types"; +import { logger } from "./utils/logger"; const program = new Command(); async function main() { - renderTitle(); + try { + renderTitle(); - console.log(chalk.bold("\nšŸš€ Creating a new Better-T Stack project...\n")); + console.log(chalk.bold("\nšŸš€ Creating a new Better-T Stack project...\n")); - const projectName = await input({ - message: "Project name:", - default: "my-better-t-app", - }); + const projectName = await input({ + message: "Project name:", + default: "my-better-t-app", + }); - const database = await select({ - message: chalk.cyan("Select database:"), - choices: [ - { - value: "libsql", - name: "libSQL", - description: chalk.dim( - "(Recommended) - Turso's embedded SQLite database", - ), - }, - { - value: "postgres", - name: "PostgreSQL", - description: chalk.dim("Traditional relational database"), - }, - ], - }); + const database = await select({ + message: chalk.cyan("Select database:"), + choices: [ + { + value: "libsql", + name: "libSQL", + description: chalk.dim( + "(Recommended) - Turso's embedded SQLite database", + ), + }, + { + value: "postgres", + name: "PostgreSQL", + description: chalk.dim("Traditional relational database"), + }, + ], + }); - const auth = await confirm({ - message: "Add authentication with Better-Auth?", - default: true, - }); + const auth = await confirm({ + message: "Add authentication with Better-Auth?", + default: true, + }); - const features = await checkbox({ - message: chalk.cyan("Select additional features:"), - choices: [ - { - value: "docker", - name: "Docker setup", - description: chalk.dim("Containerize your application"), - }, - { - value: "github-actions", - name: "GitHub Actions", - description: chalk.dim("CI/CD workflows"), - }, - { - value: "SEO", - name: "Basic SEO setup", - description: chalk.dim("Search engine optimization configuration"), - }, - ], - }); + const features = await checkbox({ + message: chalk.cyan("Select additional features:"), + choices: [ + { + value: "docker", + name: "Docker setup", + description: chalk.dim("Containerize your application"), + }, + { + value: "github-actions", + name: "GitHub Actions", + description: chalk.dim("CI/CD workflows"), + }, + { + value: "SEO", + name: "Basic SEO setup", + description: chalk.dim("Search engine optimization configuration"), + }, + ], + }); - const projectOptions = { - projectName, - git: true, - database, - auth, - features, - }; + const projectOptions = { + projectName, + git: true, + database, + auth, + features, + }; - await createProject(projectOptions); + await createProject(projectOptions); + } catch (error) { + if (error instanceof Error && error.message.includes("User force closed")) { + console.log("\n"); + logger.warn("Operation cancelled by user"); + process.exit(0); + } + logger.error("An unexpected error occurred:", error); + process.exit(1); + } } +process.on("SIGINT", () => { + console.log("\n"); + logger.warn("Operation cancelled by user"); + process.exit(0); +}); + program .name("create-better-t-stack") .description("Create a new Better-T Stack project") diff --git a/apps/cli/src/utils/logger.ts b/apps/cli/src/utils/logger.ts new file mode 100644 index 0000000..e170575 --- /dev/null +++ b/apps/cli/src/utils/logger.ts @@ -0,0 +1,16 @@ +import chalk from "chalk"; + +export const logger = { + error(...args: unknown[]) { + console.log(chalk.red(...args)); + }, + warn(...args: unknown[]) { + console.log(chalk.yellow(...args)); + }, + info(...args: unknown[]) { + console.log(chalk.cyan(...args)); + }, + success(...args: unknown[]) { + console.log(chalk.green(...args)); + }, +};