Skip to content

Commit 99755b7

Browse files
authored
Merge pull request #1056 from Shopify/jb-prettier-ignore
Respect .prettierignore when formatting local files
2 parents a28a157 + 5b5a1f9 commit 99755b7

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

.changeset/old-forks-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'theme-check-vscode': minor
3+
---
4+
5+
Respect .prettierignore when formatting local VSCode files
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import type * as vscode from 'vscode';
3+
import * as prettier from 'prettier';
4+
import { vscodePrettierFormat, nodePrettierFormat } from './formatter';
5+
6+
vi.mock('prettier', () => ({
7+
format: vi.fn(),
8+
getFileInfo: vi.fn(),
9+
resolveConfig: vi.fn(),
10+
}));
11+
12+
vi.mock('vscode', () => ({
13+
workspace: {
14+
getWorkspaceFolder: vi.fn(() => ({
15+
uri: { fsPath: '/workspace' },
16+
})),
17+
},
18+
}));
19+
20+
describe('formatter', () => {
21+
const localFile = {
22+
uri: {
23+
scheme: 'file',
24+
fsPath: '/snippets/button.liquid',
25+
},
26+
getText: vi.fn(() => '<div>{{ product.title }}</div>'),
27+
} as unknown as vscode.TextDocument;
28+
29+
const remoteFile = {
30+
...localFile,
31+
uri: { ...localFile.uri, scheme: 'vscode-remote' },
32+
} as vscode.TextDocument;
33+
34+
beforeEach(() => {
35+
vi.clearAllMocks();
36+
});
37+
38+
describe('vscodePrettierFormat', () => {
39+
it('should format remote files without config options', async () => {
40+
await vscodePrettierFormat(remoteFile);
41+
42+
expect(prettier.getFileInfo).not.toHaveBeenCalled();
43+
expect(prettier.resolveConfig).not.toHaveBeenCalled();
44+
expect(prettier.format).toHaveBeenCalledWith('<div>{{ product.title }}</div>', {
45+
parser: 'liquid-html',
46+
plugins: [expect.anything()],
47+
});
48+
});
49+
50+
it('should format local files with config options', async () => {
51+
await vscodePrettierFormat(localFile);
52+
53+
expect(prettier.getFileInfo).toHaveBeenCalled();
54+
expect(prettier.resolveConfig).toHaveBeenCalled();
55+
expect(prettier.format).toHaveBeenCalledWith('<div>{{ product.title }}</div>', {
56+
parser: 'liquid-html',
57+
plugins: [expect.anything()],
58+
});
59+
});
60+
61+
it('should not format ignored local files', async () => {
62+
vi.mocked(prettier.getFileInfo).mockResolvedValue({
63+
ignored: true,
64+
} as prettier.FileInfoResult);
65+
66+
const result = await nodePrettierFormat(localFile);
67+
68+
expect(prettier.getFileInfo).toHaveBeenCalled();
69+
expect(prettier.resolveConfig).not.toHaveBeenCalled();
70+
expect(prettier.format).not.toHaveBeenCalled();
71+
expect(result).toBe('<div>{{ product.title }}</div>');
72+
});
73+
});
74+
});

packages/vscode-extension/src/node/formatter.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import path from 'node:path';
2+
import { workspace } from 'vscode';
13
import LiquidPrettierPlugin from '@shopify/prettier-plugin-liquid';
24
import * as prettier from 'prettier';
35
import { Format } from '../common/formatter';
@@ -18,6 +20,18 @@ export const vscodePrettierFormat: Format = async (textDocument) => {
1820

1921
export const nodePrettierFormat: Format = async (textDocument) => {
2022
const text = textDocument.getText();
23+
24+
const workspaceFolder = workspace.getWorkspaceFolder(textDocument.uri);
25+
const fileInfo =
26+
workspaceFolder &&
27+
(await prettier.getFileInfo(textDocument.uri.fsPath, {
28+
ignorePath: path.join(workspaceFolder.uri.fsPath, '.prettierignore'),
29+
}));
30+
31+
if (fileInfo?.ignored) {
32+
return text;
33+
}
34+
2135
const options = await prettier.resolveConfig(textDocument.uri.fsPath, { useCache: false });
2236
return prettier.format(text, {
2337
...options,

0 commit comments

Comments
 (0)