Skip to content

Commit

Permalink
Merge branch 'main' into feat/use-clack-core
Browse files Browse the repository at this point in the history
  • Loading branch information
goisaki committed Sep 8, 2024
2 parents 22c5373 + a60067d commit 8bd4200
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 69 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-hono",
"version": "0.12.0",
"version": "0.13.0",
"scripts": {
"build": "tsx ./build.ts",
"bin": "./bin",
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/after-create.test.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -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'
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/after-create.ts
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
38 changes: 16 additions & 22 deletions src/hooks/dependencies.test.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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 })
Expand Down Expand Up @@ -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 },
)
Expand Down Expand Up @@ -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'
54 changes: 31 additions & 23 deletions src/hooks/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { exec } from 'child_process'
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'
Expand All @@ -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<EventMap>,
) => {
if (excludeTemplate.includes(template)) return

Expand All @@ -52,7 +56,7 @@ const registerInstallationHook = (

if (!installDeps) return

let packageManager
let packageManager: string

if (pmArg && installedPackageManagerNames.includes(pmArg)) {
packageManager = pmArg
Expand All @@ -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
})
Expand All @@ -98,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'
}
Expand Down
48 changes: 29 additions & 19 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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'
Expand All @@ -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'
Expand Down Expand Up @@ -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<EventMap>()

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}: ${
Expand All @@ -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()

0 comments on commit 8bd4200

Please sign in to comment.