diff --git a/packages/cli/src/commands/add.ts b/packages/cli/src/commands/add.ts index 7a1672803..13f49d057 100644 --- a/packages/cli/src/commands/add.ts +++ b/packages/cli/src/commands/add.ts @@ -1,14 +1,17 @@ import { existsSync, promises as fs } from "node:fs"; +import { EOL } from "node:os"; import path from "node:path"; import process from "node:process"; -import color from "chalk"; -import { Command } from "commander"; import { execa } from "execa"; +import { Command } from "commander"; +import color from "chalk"; import * as v from "valibot"; +import { handleDependencies } from "../utils/dependencies.js"; +import { ConfigError, error, handleError } from "../utils/errors.js"; import { type Config, getConfig } from "../utils/get-config.js"; import { getEnvProxy } from "../utils/get-env-proxy.js"; -import { getPackageManager } from "../utils/get-package-manager.js"; -import { ConfigError, error, handleError } from "../utils/errors.js"; +import { intro, prettifyList } from "../utils/prompt-helpers.js"; +import * as p from "../utils/prompts.js"; import { fetchTree, getItemTargetPath, @@ -17,8 +20,6 @@ import { resolveTree, } from "../utils/registry"; import { transformImports } from "../utils/transformers.js"; -import * as p from "../utils/prompts.js"; -import { intro, prettifyList } from "../utils/prompt-helpers.js"; const highlight = (...args: unknown[]) => color.bold.cyan(...args); @@ -244,15 +245,19 @@ async function runAdd(cwd: string, config: Config, options: AddOptions) { } // Install dependencies. + const { packageManager, dependencies: missingDeps } = await handleDependencies( + cwd, + dependencies + ); + tasks.push({ - title: "Installing package dependencies", - enabled: dependencies.size > 0, + title: `${highlight(packageManager)} Installing package dependencies`, + enabled: missingDeps.length > 0, async task() { - const packageManager = await getPackageManager(cwd); - await execa(packageManager, ["add", ...dependencies], { + await execa(packageManager, ["add", ...missingDeps], { cwd, }); - return "Dependencies installed"; + return `Dependencies installed:${EOL}\t${color.gray(prettifyList(missingDeps))}`; }, }); diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 7bf455cf5..d9860a244 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -1,21 +1,22 @@ import { existsSync, promises as fs } from "node:fs"; +import { EOL } from "node:os"; import path from "node:path"; import process from "node:process"; +import { execa } from "execa"; +import { Command, Option } from "commander"; import color from "chalk"; import * as v from "valibot"; -import { Command, Option } from "commander"; -import { execa } from "execa"; -import * as cliConfig from "../utils/get-config.js"; -import type { Config } from "../utils/get-config.js"; -import { getPackageManager } from "../utils/get-package-manager.js"; +import { type DetectLanguageResult, detectConfigs, detectLanguage } from "../utils/auto-detect.js"; +import { handleDependencies } from "../utils/dependencies.js"; import { error, handleError } from "../utils/errors.js"; -import { getBaseColors, getRegistryBaseColor, getStyles } from "../utils/registry"; -import * as templates from "../utils/templates.js"; -import * as p from "../utils/prompts.js"; +import type { Config } from "../utils/get-config.js"; +import * as cliConfig from "../utils/get-config.js"; import { intro, prettifyList } from "../utils/prompt-helpers.js"; +import * as p from "../utils/prompts.js"; +import { getBaseColors, getRegistryBaseColor, getStyles } from "../utils/registry"; import { resolveImport } from "../utils/resolve-imports.js"; import { syncSvelteKit } from "../utils/sveltekit.js"; -import { type DetectLanguageResult, detectConfigs, detectLanguage } from "../utils/auto-detect.js"; +import * as templates from "../utils/templates.js"; const PROJECT_DEPENDENCIES = ["tailwind-variants", "clsx", "tailwind-merge"] as const; const highlight = (...args: unknown[]) => color.bold.cyan(...args); @@ -360,15 +361,19 @@ export async function runInit(cwd: string, config: Config, options: InitOptions) // Install dependencies. if (options.deps) { + const { packageManager, dependencies: missingDeps } = await handleDependencies( + cwd, + new Set(PROJECT_DEPENDENCIES) + ); + tasks.push({ - title: "Installing dependencies", + title: `${highlight(packageManager)} Installing package dependencies`, + enabled: missingDeps.length > 0, async task() { - const packageManager = await getPackageManager(cwd); - - await execa(packageManager, ["add", ...PROJECT_DEPENDENCIES], { + await execa(packageManager, ["add", ...missingDeps], { cwd, }); - return "Dependencies installed"; + return `Dependencies installed:${EOL}\t${color.gray(prettifyList(missingDeps))}`; }, }); } diff --git a/packages/cli/src/commands/update.ts b/packages/cli/src/commands/update.ts index 971bbfc76..3db02ad99 100644 --- a/packages/cli/src/commands/update.ts +++ b/packages/cli/src/commands/update.ts @@ -1,19 +1,20 @@ import { existsSync, promises as fs } from "node:fs"; +import { EOL } from "node:os"; import path from "node:path"; import process from "node:process"; -import color from "chalk"; -import { Command } from "commander"; import { execa } from "execa"; +import { Command } from "commander"; +import color from "chalk"; import * as v from "valibot"; -import { type Config, getConfig } from "../utils/get-config.js"; -import { getPackageManager } from "../utils/get-package-manager.js"; +import { handleDependencies } from "../utils/dependencies.js"; import { error, handleError } from "../utils/errors.js"; +import { type Config, getConfig } from "../utils/get-config.js"; +import { getEnvProxy } from "../utils/get-env-proxy.js"; +import { intro, prettifyList } from "../utils/prompt-helpers.js"; +import * as p from "../utils/prompts.js"; import { fetchTree, getItemTargetPath, getRegistryIndex, resolveTree } from "../utils/registry"; import { UTILS, UTILS_JS } from "../utils/templates.js"; import { transformImports } from "../utils/transformers.js"; -import * as p from "../utils/prompts.js"; -import { intro, prettifyList } from "../utils/prompt-helpers.js"; -import { getEnvProxy } from "../utils/get-env-proxy.js"; const highlight = (msg: string) => color.bold.cyan(msg); @@ -225,15 +226,19 @@ async function runUpdate(cwd: string, config: Config, options: UpdateOptions) { } // Install dependencies. + const { packageManager, dependencies: missingDeps } = await handleDependencies( + cwd, + dependencies + ); + tasks.push({ - title: "Installing package dependencies", - enabled: dependencies.size > 0, + title: `${highlight(packageManager)} Installing package dependencies`, + enabled: missingDeps.length > 0, async task() { - const packageManager = await getPackageManager(cwd); - await execa(packageManager, ["add", ...dependencies], { + await execa(packageManager, ["add", ...missingDeps], { cwd, }); - return "Dependencies installed"; + return `Dependencies installed:${EOL}\t${color.gray(prettifyList(missingDeps))}`; }, }); diff --git a/packages/cli/src/utils/dependencies.ts b/packages/cli/src/utils/dependencies.ts new file mode 100644 index 000000000..364d18ee6 --- /dev/null +++ b/packages/cli/src/utils/dependencies.ts @@ -0,0 +1,29 @@ +import fs from "node:fs"; +import { findUp } from "find-up"; +import type { PackageJson } from "type-fest"; +import { getPackageManager } from "./get-package-manager"; + +export async function handleDependencies(targetDir: string, dependencies: Set) { + let missingDependencies: undefined | Set; + const packageManager = await getPackageManager(targetDir); + const packageJsonPath = await findUp("package.json", { cwd: targetDir }); + + // read `dependencies` from package.json + if (packageJsonPath && fs.existsSync(packageJsonPath)) { + try { + const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as PackageJson; + missingDependencies = new Set(); + + dependencies.forEach((dep) => { + if (!pkg.dependencies?.[dep] && !pkg.devDependencies?.[dep]) { + missingDependencies?.add(dep); + } + }); + } catch {} + } + + return { + packageManager, + dependencies: Array.from(missingDependencies || dependencies), + }; +}