diff --git a/packages/create-bot/src/cli.ts b/packages/create-bot/src/cli.ts index 201fa394..7502bf0f 100644 --- a/packages/create-bot/src/cli.ts +++ b/packages/create-bot/src/cli.ts @@ -6,6 +6,7 @@ import { readConfig, UserConfigPersisted, writeConfig } from './config.js' import { TELEGRAM_APPS_PAGE } from './constants.js' import { getFeatureChoices } from './features/cli.js' import { MtcuteFeature } from './features/types.js' +import { getPackageManager, PackageManager } from './package-manager.js' interface UserConfigAnswers { reuse?: boolean @@ -19,6 +20,7 @@ export interface UserConfig extends UserConfigPersisted { name: string botToken?: string features: MtcuteFeature[] + packageManager: PackageManager } export async function askForConfigPersisted(): Promise { @@ -135,6 +137,7 @@ export async function askForConfig(): Promise { return { ...persisted, name: '', // will be filled later + packageManager: getPackageManager(), botToken: botToken || undefined, features, } diff --git a/packages/create-bot/src/dependencies.ts b/packages/create-bot/src/dependencies.ts index 425225f6..37130571 100644 --- a/packages/create-bot/src/dependencies.ts +++ b/packages/create-bot/src/dependencies.ts @@ -1,5 +1,6 @@ import { UserConfig } from './cli.js' import { MtcuteFeature } from './features/types.js' +import { getInstallCommand } from './package-manager.js' import { exec } from './utils.js' export function buildDependenciesList(config: UserConfig) { @@ -52,6 +53,6 @@ export function buildDependenciesList(config: UserConfig) { export async function installDependencies(cwd: string, config: UserConfig) { const { dependencies, devDepdenencies } = buildDependenciesList(config) - await exec(cwd, 'pnpm', 'add', ...dependencies) - await exec(cwd, 'pnpm', 'add', '--save-dev', ...devDepdenencies) + await exec(cwd, ...getInstallCommand({ mgr: config.packageManager, packages: dependencies })) + await exec(cwd, ...getInstallCommand({ mgr: config.packageManager, packages: devDepdenencies, dev: true })) } diff --git a/packages/create-bot/src/main.ts b/packages/create-bot/src/main.ts index c1c3053f..55f1210b 100644 --- a/packages/create-bot/src/main.ts +++ b/packages/create-bot/src/main.ts @@ -1,3 +1,4 @@ +#!/usr/bin/env node import * as colors from 'colorette' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' @@ -5,6 +6,7 @@ import { fileURLToPath } from 'node:url' import { askForConfig } from './cli.js' import { installDependencies } from './dependencies.js' import { MtcuteFeature } from './features/types.js' +import { getExecCommand } from './package-manager.js' import { runTemplater } from './templater.js' import { exec } from './utils.js' @@ -35,10 +37,10 @@ if (config.features.includes(MtcuteFeature.Linters)) { await exec(outDir, 'chmod', '+x', '.husky/pre-commit') } - await exec(outDir, 'pnpm', 'exec', 'husky', 'install') + await exec(outDir, ...getExecCommand(config.packageManager, 'husky', 'install')) } console.log(`✅ Scaffolded new project at ${colors.blue(outDir)}`) console.log('🚀 Run it with:') console.log(` ${colors.blue('$')} cd ${projectName}`) -console.log(` ${colors.blue('$')} pnpm start`) +console.log(` ${colors.blue('$')} ${config.packageManager} start`) diff --git a/packages/create-bot/src/package-manager.ts b/packages/create-bot/src/package-manager.ts new file mode 100644 index 00000000..5dbd0245 --- /dev/null +++ b/packages/create-bot/src/package-manager.ts @@ -0,0 +1,70 @@ +export enum PackageManager { + Npm = 'npm', + Yarn = 'yarn', + Pnpm = 'pnpm', + Bun = 'bun', +} + +export function getPackageManager(): PackageManager { + const userAgent = process.env.npm_config_user_agent + + if (!userAgent) { + return PackageManager.Pnpm // fall back to the most based one + } + + const name = userAgent.split('/')[0] + + switch (name) { + case 'pnpm': + return PackageManager.Pnpm + case 'yarn': + return PackageManager.Yarn + case 'npm': + return PackageManager.Npm + case 'bun': + return PackageManager.Bun + default: + throw new Error(`Unsupported package manager: ${name}`) + } +} + +export function getInstallCommand(params: { mgr: PackageManager; packages: string[]; dev?: boolean }): string[] { + const { mgr, packages, dev } = params + + const exec: string[] = [mgr] + + switch (mgr) { + case PackageManager.Npm: + exec.push('install', dev ? '--save-dev' : '--save') + break + case PackageManager.Yarn: + exec.push('add') + if (dev) exec.push('-D') + break + case PackageManager.Pnpm: + exec.push('add') + if (dev) exec.push('--save-dev') + break + case PackageManager.Bun: + exec.push('add') + if (dev) exec.push('-D') + break + } + + exec.push(...packages) + + return exec +} + +export function getExecCommand(mgr: PackageManager, ...cmd: string[]) { + switch (mgr) { + case PackageManager.Npm: + return ['npx', ...cmd] + case PackageManager.Yarn: + return ['yarn', ...cmd] + case PackageManager.Pnpm: + return ['pnpm', 'exec', ...cmd] + case PackageManager.Bun: + return ['bun', 'run', ...cmd] + } +}