Skip to content

Commit 646f884

Browse files
committed
feat: implement dry-run
1 parent b9b30a2 commit 646f884

5 files changed

Lines changed: 2512 additions & 2 deletions

File tree

.changeset/twenty-nails-start.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"shadcn": major
3+
---
4+
5+
add --dry-run, --diff and --view to the add command

packages/shadcn/src/commands/add.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import { registryItemTypeSchema } from "@/src/registry/schema"
88
import { isUniversalRegistryItem } from "@/src/registry/utils"
99
import { getTemplateForFramework } from "@/src/templates/index"
1010
import { addComponents } from "@/src/utils/add-components"
11+
import { dryRunComponents } from "@/src/utils/dry-run"
12+
import { formatDryRunResult } from "@/src/utils/dry-run-formatter"
1113
import { createProject } from "@/src/utils/create-project"
1214
import { loadEnvFiles } from "@/src/utils/env-loader"
15+
import { spinner } from "@/src/utils/spinner"
1316
import * as ERRORS from "@/src/utils/errors"
1417
import { createConfig, getConfig } from "@/src/utils/get-config"
1518
import { getProjectInfo } from "@/src/utils/get-project-info"
@@ -35,6 +38,9 @@ export const addOptionsSchema = z.object({
3538
all: z.boolean(),
3639
path: z.string().optional(),
3740
silent: z.boolean(),
41+
dryRun: z.boolean(),
42+
diff: z.string().optional(),
43+
view: z.string().optional(),
3844
})
3945

4046
export const add = new Command()
@@ -51,6 +57,9 @@ export const add = new Command()
5157
.option("-a, --all", "add all available components", false)
5258
.option("-p, --path <path>", "the path to add the component to.")
5359
.option("-s, --silent", "mute output.", false)
60+
.option("--dry-run", "preview changes without writing files.", false)
61+
.option("--diff <path>", "show diff for a file.")
62+
.option("--view <path>", "show file contents.")
5463
.action(async (components, opts) => {
5564
try {
5665
const options = addOptionsSchema.parse({
@@ -94,13 +103,15 @@ export const add = new Command()
94103
itemType !== "registry:style" &&
95104
itemType !== "registry:base"
96105

97-
if (isUniversalRegistryItem(registryItem)) {
106+
const isDryRun = options.dryRun || options.diff || options.view
107+
108+
if (isUniversalRegistryItem(registryItem) && !isDryRun) {
98109
await addComponents(components, initialConfig, options)
99110
return
100111
}
101-
102112
if (
103113
!options.yes &&
114+
!isDryRun &&
104115
(itemType === "registry:style" || itemType === "registry:theme")
105116
) {
106117
logger.break()
@@ -256,6 +267,30 @@ export const add = new Command()
256267
)
257268
config = updatedConfig
258269

270+
// Dry-run mode: preview changes without writing files.
271+
// --diff and --view imply --dry-run.
272+
if (options.dryRun || options.diff || options.view) {
273+
const dryRunSpinner = spinner("Resolving items.", {
274+
silent: options.silent,
275+
}).start()
276+
const dryRunResult = await dryRunComponents(
277+
options.components,
278+
config,
279+
{
280+
overwrite: options.overwrite,
281+
}
282+
)
283+
dryRunSpinner.stop()
284+
285+
logger.log(
286+
formatDryRunResult(dryRunResult, options.components, {
287+
diff: options.diff,
288+
view: options.view,
289+
})
290+
)
291+
return
292+
}
293+
259294
if (!initHasRun) {
260295
await addComponents(options.components, config, options)
261296
}

0 commit comments

Comments
 (0)