Skip to content

Commit 62efb03

Browse files
manuel3108jycouet
andauthored
fix(cli): files will be formatted after create (#827)
* fix(cli): files will be formatted after create * simplify formatFiles udage * rmv the tailwindcss & prettier conflic * add formatFiles util --------- Co-authored-by: jycouet <jycouet@gmail.com>
1 parent c0d9e99 commit 62efb03

File tree

7 files changed

+55
-29
lines changed

7 files changed

+55
-29
lines changed

.changeset/many-melons-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sv': patch
3+
---
4+
5+
fix(cli): files will be formatted after create

packages/addons/prettier/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default defineAddon({
5656
data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet });
5757
}
5858
if (!plugins.includes('prettier-plugin-svelte')) {
59-
data.plugins.unshift('prettier-plugin-svelte');
59+
data.plugins.push('prettier-plugin-svelte');
6060
}
6161

6262
data.overrides ??= [];

packages/addons/tailwindcss/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export default defineAddon({
141141
data.plugins ??= [];
142142
const plugins: string[] = data.plugins;
143143

144-
if (!plugins.includes(PLUGIN_NAME)) plugins.push(PLUGIN_NAME);
144+
if (!plugins.includes(PLUGIN_NAME)) plugins.unshift(PLUGIN_NAME);
145145

146146
data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet });
147147

packages/cli/commands/add/index.ts

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ export async function runAddonsApply({
556556
addonSetupResults?: Record<string, AddonSetupResult>;
557557
workspace: Workspace;
558558
fromCommand: 'create' | 'add';
559-
}): Promise<{ nextSteps: string[]; argsFormattedAddons: string[] }> {
559+
}): Promise<{ nextSteps: string[]; argsFormattedAddons: string[]; filesToFormat: string[] }> {
560560
if (!addonSetupResults) {
561561
const setups = selectedAddons.length
562562
? selectedAddons.map(({ addon }) => addon)
@@ -565,7 +565,8 @@ export async function runAddonsApply({
565565
}
566566
// we'll return early when no addons are selected,
567567
// indicating that installing deps was skipped and no PM was selected
568-
if (selectedAddons.length === 0) return { nextSteps: [], argsFormattedAddons: [] };
568+
if (selectedAddons.length === 0)
569+
return { nextSteps: [], argsFormattedAddons: [], filesToFormat: [] };
569570

570571
// apply addons
571572
const officialDetails = Object.keys(answersOfficial).map((id) => getAddonDetails(id));
@@ -662,19 +663,7 @@ export async function runAddonsApply({
662663
if (packageManager) {
663664
workspace.packageManager = packageManager;
664665
await installDependencies(packageManager, options.cwd);
665-
}
666-
667-
// format modified/created files with prettier (if available)
668-
if (filesToFormat.length > 0 && packageManager && !!workspace.dependencyVersion('prettier')) {
669-
const { start, stop } = p.spinner();
670-
start('Formatting modified files');
671-
try {
672-
await formatFiles({ packageManager, cwd: options.cwd, paths: filesToFormat });
673-
stop('Successfully formatted modified files');
674-
} catch (e) {
675-
stop('Failed to format files');
676-
if (e instanceof Error) p.log.error(e.message);
677-
}
666+
await formatFiles({ packageManager, cwd: options.cwd, filesToFormat });
678667
}
679668

680669
const highlighter = getHighlighter();
@@ -693,7 +682,7 @@ export async function runAddonsApply({
693682
})
694683
.filter((msg) => msg !== undefined);
695684

696-
return { nextSteps, argsFormattedAddons };
685+
return { nextSteps, argsFormattedAddons, filesToFormat };
697686
}
698687

699688
/**

packages/cli/commands/add/utils.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { exec } from 'tinyexec';
55
import { parseJson } from '@sveltejs/cli-core/parsers';
66
import { resolveCommand, type AgentName } from 'package-manager-detector';
77
import type { Highlighter, Workspace } from '@sveltejs/cli-core';
8+
import * as p from '@clack/prompts';
89

910
export type Package = {
1011
name: string;
@@ -35,14 +36,32 @@ export function getPackageJson(cwd: string): {
3536
export async function formatFiles(options: {
3637
packageManager: AgentName;
3738
cwd: string;
38-
paths: string[];
39+
filesToFormat: string[];
3940
}): Promise<void> {
40-
const args = ['prettier', '--write', '--ignore-unknown', ...options.paths];
41+
if (options.filesToFormat.length === 0) return;
42+
const { start, stop } = p.spinner();
43+
start('Formatting modified files');
44+
45+
const args = ['prettier', '--write', '--ignore-unknown', ...options.filesToFormat];
4146
const cmd = resolveCommand(options.packageManager, 'execute-local', args)!;
42-
await exec(cmd.command, cmd.args, {
43-
nodeOptions: { cwd: options.cwd, stdio: 'pipe' },
44-
throwOnError: true
45-
});
47+
48+
try {
49+
const result = await exec(cmd.command, cmd.args, {
50+
nodeOptions: { cwd: options.cwd, stdio: 'pipe' },
51+
throwOnError: true
52+
});
53+
if (result.exitCode !== 0) {
54+
stop('Failed to format files');
55+
p.log.error(result.stderr);
56+
return;
57+
}
58+
} catch (e) {
59+
stop('Failed to format files');
60+
// @ts-expect-error
61+
p.log.error(e?.output?.stderr || 'unknown error');
62+
return;
63+
}
64+
stop('Successfully formatted modified files');
4665
}
4766

4867
export function readFile(cwd: string, filePath: string): string {

packages/cli/commands/create.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
sanitizeAddons,
3838
type SelectedAddon
3939
} from './add/index.ts';
40-
import { commonFilePaths, getPackageJson } from './add/utils.ts';
40+
import { commonFilePaths, formatFiles, getPackageJson } from './add/utils.ts';
4141
import { createWorkspace } from './add/workspace.ts';
4242
import { dist } from '../../create/utils.ts';
4343

@@ -266,12 +266,18 @@ async function createProject(cwd: ProjectPath, options: Options) {
266266

267267
let addOnNextSteps: string[] = [];
268268
let argsFormattedAddons: string[] = [];
269+
let addOnFilesToFormat: string[] = [];
269270
if (options.addOns || options.add.length > 0) {
270-
const { nextSteps, argsFormattedAddons: argsFormatted } = await runAddonsApply({
271+
const {
272+
nextSteps,
273+
argsFormattedAddons: argsFormatted,
274+
filesToFormat
275+
} = await runAddonsApply({
271276
answersOfficial,
272277
answersCommunity,
273278
options: {
274279
cwd: projectPath,
280+
// in the create command, we don't want to install dependencies, we want to do it after the project is created
275281
install: false,
276282
gitCheck: false,
277283
community: [],
@@ -283,7 +289,7 @@ async function createProject(cwd: ProjectPath, options: Options) {
283289
fromCommand: 'create'
284290
});
285291
argsFormattedAddons = argsFormatted;
286-
292+
addOnFilesToFormat = filesToFormat;
287293
addOnNextSteps = nextSteps;
288294
}
289295

@@ -308,7 +314,10 @@ async function createProject(cwd: ProjectPath, options: Options) {
308314
common.logArgs(packageManager, 'create', argsFormatted, [directory]);
309315

310316
await addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']);
311-
if (packageManager) await installDependencies(packageManager, projectPath);
317+
if (packageManager) {
318+
await installDependencies(packageManager, projectPath);
319+
await formatFiles({ packageManager, cwd: projectPath, filesToFormat: addOnFilesToFormat });
320+
}
312321

313322
return { directory: projectPath, addOnNextSteps, packageManager };
314323
}

packages/cli/lib/install.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export async function applyAddons({
6363
const mapped = Object.entries(addons).map(([, addon]) => addon);
6464
const ordered = orderAddons(mapped, addonSetupResults);
6565

66+
let hasFormatter = false;
67+
6668
for (const addon of ordered) {
6769
const workspaceOptions = options[addon.id] || {};
6870

@@ -71,6 +73,8 @@ export async function applyAddons({
7173
cwd: workspace.cwd,
7274
packageManager: workspace.packageManager
7375
});
76+
// If we don't have a formatter yet, check if the addon adds one
77+
if (!hasFormatter) hasFormatter = !!addonWorkspace.dependencyVersion('prettier');
7478

7579
const { files, pnpmBuildDependencies, cancels } = await runAddon({
7680
workspace: addonWorkspace,
@@ -89,7 +93,7 @@ export async function applyAddons({
8993
}
9094

9195
return {
92-
filesToFormat: Array.from(filesToFormat),
96+
filesToFormat: hasFormatter ? Array.from(filesToFormat) : [],
9397
pnpmBuildDependencies: allPnpmBuildDependencies,
9498
status
9599
};

0 commit comments

Comments
 (0)