From 44555b494ca11400c857de51283045d649d3cd4a Mon Sep 17 00:00:00 2001 From: Aditya Mathur <57684218+MathurAditya724@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:10:01 +0530 Subject: [PATCH 1/3] feat: confirm all questions before init repo (#70) * fix: confirm all questions before init repo * fix: used EventEmitter * chore: changed any to unknown --- src/hooks/dependencies.ts | 44 +++++++++++++++++++++++---------------- src/index.ts | 44 ++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/hooks/dependencies.ts b/src/hooks/dependencies.ts index be411be..040e1cc 100644 --- a/src/hooks/dependencies.ts +++ b/src/hooks/dependencies.ts @@ -1,4 +1,5 @@ import { exec } from 'child_process' +import type { EventEmitter } from 'events' import { chdir, exit } from 'process' import confirm from '@inquirer/confirm' import select from '@inquirer/select' @@ -22,10 +23,13 @@ const currentPackageManager = getCurrentPackageManager() // Deno and Netlify need no dependency installation step const excludeTemplate = ['deno', 'netlify'] +export type EventMap = { dependencies: unknown[]; completed: unknown[] } + const registerInstallationHook = ( template: string, installArg: boolean | undefined, pmArg: string, + emitter: EventEmitter, ) => { if (excludeTemplate.includes(template)) return @@ -67,28 +71,32 @@ const registerInstallationHook = ( }) } - chdir(directoryPath) - - if (!knownPackageManagers[packageManager]) { - exit(1) - } + emitter.on('dependencies', async () => { + chdir(directoryPath) - const spinner = createSpinner('Installing project dependencies').start() - const proc = exec(knownPackageManagers[packageManager]) + if (!knownPackageManagers[packageManager]) { + exit(1) + } - const procExit: number = await new Promise((res) => { - proc.on('exit', (code) => res(code == null ? 0xff : code)) - }) + const spinner = createSpinner('Installing project dependencies').start() + const proc = exec(knownPackageManagers[packageManager]) - if (procExit == 0) { - spinner.success() - } else { - spinner.stop({ - mark: chalk.red('×'), - text: 'Failed to install project dependencies', + const procExit: number = await new Promise((res) => { + proc.on('exit', (code) => res(code == null ? 0xff : code)) }) - exit(procExit) - } + + if (procExit == 0) { + spinner.success() + } else { + spinner.stop({ + mark: chalk.red('×'), + text: 'Failed to install project dependencies', + }) + exit(procExit) + } + + emitter.emit('completed') + }) return }) diff --git a/src/index.ts b/src/index.ts index e7a6a31..97fa2a7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +import EventEmitter from 'events' import fs from 'fs' import path from 'path' import confirm from '@inquirer/confirm' @@ -11,6 +12,7 @@ import { version } from '../package.json' import { projectDependenciesHook } from './hook' import { afterCreateHook } from './hooks/after-create' import { + type EventMap, knownPackageManagerNames, registerInstallationHook, } from './hooks/dependencies' @@ -145,30 +147,36 @@ async function main( } const targetDirectoryPath = path.join(process.cwd(), target) - const spinner = createSpinner('Cloning the template').start() - await downloadTemplate( - `gh:${config.user}/${config.repository}/${config.directory}/${templateName}#${config.ref}`, - { - dir: targetDirectoryPath, - offline, - force: true, - }, - ).then(() => spinner.success()) + const emitter = new EventEmitter() - registerInstallationHook(templateName, install, pm) + registerInstallationHook(templateName, install, pm, emitter) try { - afterCreateHook.applyHook(templateName, { - projectName, - directoryPath: targetDirectoryPath, - }) - await Promise.all( projectDependenciesHook.applyHook(templateName, { directoryPath: targetDirectoryPath, }), ) + + const spinner = createSpinner('Cloning the template').start() + + await downloadTemplate( + `gh:${config.user}/${config.repository}/${config.directory}/${templateName}#${config.ref}`, + { + dir: targetDirectoryPath, + offline, + force: true, + }, + ).then(() => { + spinner.success() + emitter.emit('dependencies') + }) + + afterCreateHook.applyHook(templateName, { + projectName, + directoryPath: targetDirectoryPath, + }) } catch (e) { throw new Error( `Error running hook for ${templateName}: ${ @@ -191,8 +199,10 @@ async function main( fs.writeFileSync(packageJsonPath, JSON.stringify(newPackageJson, null, 2)) } - console.log(chalk.green(`🎉 ${chalk.bold('Copied project files')}`)) - console.log(chalk.gray('Get started with:'), chalk.bold(`cd ${target}`)) + emitter.on('completed', () => { + console.log(chalk.green(`🎉 ${chalk.bold('Copied project files')}`)) + console.log(chalk.gray('Get started with:'), chalk.bold(`cd ${target}`)) + }) } program.parse() From 5506a8a3ba27269a2e579e1b1eeddc00233d4963 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Tue, 3 Sep 2024 17:44:00 +0900 Subject: [PATCH 2/3] v0.13.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aeb5082..c0b41a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-hono", - "version": "0.12.0", + "version": "0.13.0", "scripts": { "build": "tsx ./build.ts", "bin": "./bin", From a60067dee5a605b0e4ee28e742f60f8e003d3761 Mon Sep 17 00:00:00 2001 From: Aditya Mathur <57684218+MathurAditya724@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:51:41 +0530 Subject: [PATCH 3/3] refactor: minor linting changes (#71) --- src/hooks/after-create.test.ts | 4 ++-- src/hooks/after-create.ts | 4 ++-- src/hooks/dependencies.test.ts | 38 ++++++++++++++-------------------- src/hooks/dependencies.ts | 14 ++++++------- src/index.ts | 6 +++--- 5 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/hooks/after-create.test.ts b/src/hooks/after-create.test.ts index 7037f45..a7f9ea6 100644 --- a/src/hooks/after-create.test.ts +++ b/src/hooks/after-create.test.ts @@ -1,4 +1,4 @@ -import { join } from 'path' +import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' import { afterCreateHook } from './after-create' @@ -20,7 +20,7 @@ name = "%%PROJECT_NAME%%-staging" writeFileSync: vi.fn(), } }) - const { readFileSync, writeFileSync } = await import('fs') + const { readFileSync, writeFileSync } = await import('node:fs') const projectName = 'test-projectNAME+123' const directoryPath = './tmp' diff --git a/src/hooks/after-create.ts b/src/hooks/after-create.ts index 5623c7d..f5c23c2 100644 --- a/src/hooks/after-create.ts +++ b/src/hooks/after-create.ts @@ -1,5 +1,5 @@ -import { readFileSync, writeFileSync } from 'fs' -import * as path from 'path' +import { readFileSync, writeFileSync } from 'node:fs' +import * as path from 'node:path' import { afterCreateHook } from '../hook' const PROJECT_NAME = new RegExp(/%%PROJECT_NAME.*%%/g) diff --git a/src/hooks/dependencies.test.ts b/src/hooks/dependencies.test.ts index 7fb4a77..a789256 100644 --- a/src/hooks/dependencies.test.ts +++ b/src/hooks/dependencies.test.ts @@ -1,7 +1,6 @@ -import { Buffer } from 'buffer' - -import { existsSync, rmSync } from 'fs' -import { cwd } from 'process' +import { Buffer } from 'node:buffer' +import { existsSync, rmSync } from 'node:fs' +import { cwd } from 'node:process' import { execa, execaSync } from 'execa' import type { ExecaChildProcess } from 'execa' import { afterAll, describe, expect, it } from 'vitest' @@ -54,7 +53,7 @@ describe('dependenciesHook', async () => { env: { ...process.env, npm_config_user_agent: pm }, }, ) - const targetDirectory = 'test-dir/' + generateRandomAlphanumericString(8) + const targetDirectory = `test-dir/${generateRandomAlphanumericString(8)}` afterAll(() => { rmSync(targetDirectory, { recursive: true, force: true }) @@ -108,28 +107,23 @@ describe('dependenciesHook', async () => { }) it('should have installed dependencies', async () => { - while (!existsSync(targetDirectory + '/node_modules')) + while (!existsSync(`${targetDirectory}/node_modules`)) await timeout(5_000) // 3 seconds; expect( - existsSync(targetDirectory + '/node_modules'), + existsSync(`${targetDirectory}/node_modules`), 'node_modules directory exists', ) }) - it( - 'should have package manager specific lock file (' + - packageManagersLockfiles[pm] + - ')', - async () => { - expect( - existsSync(targetDirectory + '/' + packageManagersLockfiles[pm]), - 'lockfile exists', - ) - - cmdBuffer = '' - }, - ) + it(`should have package manager specific lock file (${packageManagersLockfiles[pm]})`, async () => { + expect( + existsSync(`${targetDirectory}/${packageManagersLockfiles[pm]}`), + 'lockfile exists', + ) + + cmdBuffer = '' + }) }, { timeout: 60_000 }, ) @@ -188,6 +182,6 @@ const writeResponse = ( else process.stdin?.write(Buffer.from(response)) } -export const answerWithValue = (value = '') => [value, CONFIRM].flat() +const answerWithValue = (value = '') => [value, CONFIRM].flat() -export const CONFIRM = '\n' +const CONFIRM = '\n' diff --git a/src/hooks/dependencies.ts b/src/hooks/dependencies.ts index 040e1cc..6141aeb 100644 --- a/src/hooks/dependencies.ts +++ b/src/hooks/dependencies.ts @@ -1,6 +1,6 @@ -import { exec } from 'child_process' -import type { EventEmitter } from 'events' -import { chdir, exit } from 'process' +import { exec } from 'node:child_process' +import type { EventEmitter } from 'node:events' +import { chdir, exit } from 'node:process' import confirm from '@inquirer/confirm' import select from '@inquirer/select' import chalk from 'chalk' @@ -56,7 +56,7 @@ const registerInstallationHook = ( if (!installDeps) return - let packageManager + let packageManager: string if (pmArg && installedPackageManagerNames.includes(pmArg)) { packageManager = pmArg @@ -85,7 +85,7 @@ const registerInstallationHook = ( proc.on('exit', (code) => res(code == null ? 0xff : code)) }) - if (procExit == 0) { + if (procExit === 0) { spinner.success() } else { spinner.stop({ @@ -106,8 +106,8 @@ function getCurrentPackageManager(): PackageManager { const agent = process.env.npm_config_user_agent || 'npm' // Types say it might be undefined, just being cautious; if (agent.startsWith('bun')) return 'bun' - else if (agent.startsWith('pnpm')) return 'pnpm' - else if (agent.startsWith('yarn')) return 'yarn' + if (agent.startsWith('pnpm')) return 'pnpm' + if (agent.startsWith('yarn')) return 'yarn' return 'npm' } diff --git a/src/index.ts b/src/index.ts index 97fa2a7..46942f3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ -import EventEmitter from 'events' -import fs from 'fs' -import path from 'path' +import EventEmitter from 'node:events' +import fs from 'node:fs' +import path from 'node:path' import confirm from '@inquirer/confirm' import input from '@inquirer/input' import select from '@inquirer/select'