2026-03-08 16:15:26 +08:00

98 lines
2.9 KiB
TypeScript

import type { PromptResult, ResolvedData } from './types.js'
import path from 'node:path'
import process from 'node:process'
import { intro, outro, spinner } from '@clack/prompts'
import { sleep } from '@pengzhanbo/utils'
import spawn from 'nano-spawn'
import colors from 'picocolors'
import { Mode } from './constants.js'
import { generate } from './generate.js'
import { prompt } from './prompt.js'
import { t } from './translate.js'
import { getPackageManager } from './utils/index.js'
/**
* Run the CLI workflow for VuePress project initialization or creation
*
* 执行 VuePress 项目初始化或创建的 CLI 工作流程
*
* @param mode - Operation mode (init or create) / 操作模式(初始化或创建)
* @param root - Root directory path / 根目录路径
*/
export async function run(mode: Mode, root?: string): Promise<void> {
intro(colors.cyan('Welcome to VuePress and vuepress-theme-plume !'))
const result = await prompt(mode, root)
const data = resolveData(result, mode)
const progress = spinner()
progress.start(t('spinner.start'))
try {
await generate(mode, data)
}
catch (e) {
console.error(`${colors.red('generate files error: ')}\n`, e)
process.exit(1)
}
// Delay for some time, I/O may not be completed yet,
// executing subsequent tasks at this point may cause issues.
await sleep(200)
const cwd = path.join(process.cwd(), data.root)
if (data.git) {
progress.message(t('spinner.git'))
try {
await spawn('git', ['init'], { cwd })
}
catch (e) {
console.error(`${colors.red('git init error: ')}\n`, e)
process.exit(1)
}
}
const pm = data.packageManager
if (data.install) {
progress.message(t('spinner.install'))
try {
await spawn(pm, ['install'], { cwd })
}
catch (e) {
console.error(`${colors.red('install dependencies error: ')}\n`, e)
process.exit(1)
}
}
const cdCommand = mode === Mode.create ? colors.green(`cd ${data.root}`) : ''
const runCommand = colors.green(`${pm} run docs:dev`)
const installCommand = colors.green(`${pm} install`)
progress.stop(t('spinner.stop'))
if (mode === Mode.create) {
outro(`${t('spinner.command')}
${cdCommand}
${data.install ? '' : `${installCommand} && `}${runCommand}`)
}
}
/**
* Resolve prompt result into final configuration data.
*
* 将提示结果解析为最终配置数据。
*
* @param result - Prompt result from user input / 用户输入的提示结果
* @param mode - Operation mode (init or create) / 操作模式(初始化或创建)
* @returns Resolved configuration data / 解析后的配置数据
*/
function resolveData(result: PromptResult, mode: Mode): ResolvedData {
return {
...result,
packageManager: getPackageManager(),
docsDir: mode === Mode.create ? 'docs' : result.root.replace(/^\.\//, '').replace(/\/$/, ''),
siteDescription: result.siteDescription || '',
}
}