From a4380043049eddeaf0b52384a1ce4dc5b63cf4e4 Mon Sep 17 00:00:00 2001 From: BlankParticle Date: Fri, 22 Nov 2024 21:19:15 +0530 Subject: [PATCH] feat: add git init prompt --- .changeset/beige-dancers-study.md | 5 ++++ packages/cli/commands/create.ts | 26 ++++++++++++++--- packages/cli/utils/git.ts | 48 +++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 .changeset/beige-dancers-study.md create mode 100644 packages/cli/utils/git.ts diff --git a/.changeset/beige-dancers-study.md b/.changeset/beige-dancers-study.md new file mode 100644 index 00000000..c78f5585 --- /dev/null +++ b/.changeset/beige-dancers-study.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +add prompt to setup git repo if already not initialized diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index dd93c4f1..c8cdef2a 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -19,6 +19,7 @@ import { installDependencies, packageManagerPrompt } from '../utils/package-manager.ts'; +import { gitInitPrompt, initGitRepo } from '../utils/git.ts'; const langs = ['ts', 'jsdoc'] as const; const langMap: Record = { @@ -40,7 +41,8 @@ const OptionsSchema = v.strictObject({ ), addOns: v.boolean(), install: v.boolean(), - template: v.optional(v.picklist(templateChoices)) + template: v.optional(v.picklist(templateChoices)), + git: v.boolean() }); type Options = v.InferOutput; type ProjectPath = v.InferOutput; @@ -53,12 +55,16 @@ export const create = new Command('create') .option('--no-types') .option('--no-add-ons', 'skips interactive add-on installer') .option('--no-install', 'skip installing dependencies') + .option('--no-git', 'skip initializing a git repository') .configureHelp(common.helpConfig) .action((projectPath, opts) => { const cwd = v.parse(ProjectPathSchema, projectPath); const options = v.parse(OptionsSchema, opts); common.runCommand(async () => { - const { directory, addOnNextSteps, packageManager } = await createProject(cwd, options); + const { directory, addOnNextSteps, packageManager, gitInit } = await createProject( + cwd, + options + ); const highlight = (str: string) => pc.bold(pc.cyan(str)); let i = 1; @@ -75,10 +81,13 @@ export const create = new Command('create') initialSteps.push(`${i++}: ${highlight(`${pm} install`)}`); } + if (gitInit) { + initialSteps.push(`${i++}: ${highlight('git commit -m "Initial commit"')}`); + } + const pmRun = pm === 'npm' ? 'npm run dev --' : `${pm} dev`; const steps = [ ...initialSteps, - `${i++}: ${highlight('git init && git add -A && git commit -m "Initial commit"')} (optional)`, `${i++}: ${highlight(`${pmRun} --open`)}`, '', `To close the dev server, hit ${highlight('Ctrl-C')}`, @@ -184,5 +193,14 @@ async function createProject(cwd: ProjectPath, options: Options) { await installDeps(); } - return { directory: projectPath, addOnNextSteps, packageManager }; + let gitInit = false; + if (options.git) { + const shouldInit = await gitInitPrompt(projectPath); + if (shouldInit) { + initGitRepo(projectPath); + gitInit = true; + } + } + + return { directory: projectPath, addOnNextSteps, packageManager, gitInit }; } diff --git a/packages/cli/utils/git.ts b/packages/cli/utils/git.ts new file mode 100644 index 00000000..f748b819 --- /dev/null +++ b/packages/cli/utils/git.ts @@ -0,0 +1,48 @@ +import { execSync } from 'node:child_process'; +import * as p from '@sveltejs/clack-prompts'; + +function hasGitInstalled() { + try { + execSync('git --version', { stdio: 'ignore' }); + return true; + } catch { + return false; + } +} + +function isGitRepo(cwd: string) { + try { + return ( + execSync('git rev-parse --is-inside-work-tree', { cwd, stdio: 'pipe' }).toString().trim() === + 'true' + ); + } catch { + return false; + } +} + +export async function initGitRepo(cwd: string) { + execSync('git init', { cwd, stdio: 'ignore' }); + execSync('git add -A', { cwd, stdio: 'ignore' }); +} + +export async function gitInitPrompt(cwd: string): Promise { + const hasGit = hasGitInstalled(); + if (!hasGit) return false; + const alreadyGitRepo = isGitRepo(cwd); + if (alreadyGitRepo) return false; + + const shouldInit = await p.confirm({ + message: 'Do you want to initialize a git repository?', + active: 'yes', + inactive: 'no', + initialValue: true + }); + + if (p.isCancel(shouldInit)) { + p.cancel('Operation cancelled.'); + process.exit(1); + } + + return shouldInit; +}