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()