Skip to content

Commit d3703fd

Browse files
committed
feat(fmt): ignore common lock files by default
1 parent 3ab85fa commit d3703fd

7 files changed

Lines changed: 54 additions & 10 deletions

File tree

‎.agents/skills/migrate-to-rstack-cli/references/prettier.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Read this reference when the project uses the `prettier` CLI or API, `package.js
1515
7. Delete old config and ignore files only after their behavior is represented in `define.fmt`.
1616
8. Remove direct dependencies only when no script, config, API call, plugin peer requirement, or other tool still needs them.
1717

18+
`rs fmt` ignores `package-lock.json` and `pnpm-lock.yaml` by default. Drop redundant ignore entries during migration, but keep intentional negations.
19+
1820
`rs fmt` does not read Prettier configuration files, `.prettierignore`, or `.editorconfig`.
1921

2022
Keep `.editorconfig` when editors or other tools use it. Keep Prettier when application code uses APIs such as `prettier.format()`; `rs fmt` is not a drop-in replacement for the programmatic API.

‎packages/rstack/src/fmt/discovery.ts‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ const discoverFmtFiles = async ({
2424
return [];
2525
}
2626

27-
const isFmtIgnored = config.ignorePatterns.length ? createFmtIgnoreMatcher(config) : undefined;
28-
const filePaths = isFmtIgnored
29-
? candidates.filter((filePath) => !isFmtIgnored(filePath))
30-
: candidates;
27+
const isFmtIgnored = createFmtIgnoreMatcher(config);
28+
const filePaths = candidates.filter((filePath) => !isFmtIgnored(filePath));
3129
const resolvePlugins = createFmtPluginResolver(config.rootPath);
3230

3331
return filePaths.map((filePath) => createFileRequest(filePath, config, resolvePlugins));

‎packages/rstack/src/fmt/ignore.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ import { relative } from 'node:path';
22
import fastIgnore from 'fast-ignore';
33
import type { ResolvedFmtConfig } from './types.ts';
44

5-
/** Creates a reusable matcher for config-level ignore patterns. */
5+
/**
6+
* Common lock files that Prettier can format but `rs fmt` leaves to package managers.
7+
*
8+
* Prettier already skips other generated lock files when it cannot infer a parser, so this list
9+
* contains only the additional defaults owned by `rs fmt`.
10+
*/
11+
const defaultIgnorePatterns = ['package-lock.json', 'pnpm-lock.yaml'];
12+
13+
/** Creates a reusable matcher for default and config-level ignore patterns. */
614
const createFmtIgnoreMatcher = (config: ResolvedFmtConfig): ((filePath: string) => boolean) => {
7-
const matches = fastIgnore(config.ignorePatterns.join('\n'));
15+
const matches = fastIgnore([...defaultIgnorePatterns, ...config.ignorePatterns].join('\n'));
816

917
return (filePath) => matches(relative(config.rootPath, filePath));
1018
};

‎packages/rstack/tests/fmt/ignore.test.ts‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,22 @@ test('matches gitignore patterns relative to the config root', () => {
2222
test('applies negated patterns in declaration order', () => {
2323
const isIgnored = createMatcher(['*.js', '!src/keep.js']);
2424
const isIgnoredAgain = createMatcher(['*.js', '!src/keep.js', 'src/keep.js']);
25-
const isReincluded = createMatcher(['dist', '!dist']);
25+
const isIgnoredAfterReinclude = createMatcher(['dist', '!dist']);
2626
const filePath = path.join(rootPath, 'src/keep.js');
2727

2828
expect(isIgnored(filePath)).toBe(false);
2929
expect(isIgnored(path.join(rootPath, 'src/drop.js'))).toBe(true);
3030
expect(isIgnoredAgain(filePath)).toBe(true);
31-
expect(isReincluded(path.join(rootPath, 'dist'))).toBe(false);
31+
expect(isIgnoredAfterReinclude(path.join(rootPath, 'dist'))).toBe(false);
32+
});
33+
34+
test('ignores common lock files by default and allows explicit negation', () => {
35+
const isIgnored = createMatcher([]);
36+
const isIgnoredAfterReinclude = createMatcher(['!pnpm-lock.yaml']);
37+
38+
expect(isIgnored(path.join(rootPath, 'package-lock.json'))).toBe(true);
39+
expect(isIgnored(path.join(rootPath, 'packages/app/pnpm-lock.yaml'))).toBe(true);
40+
expect(isIgnoredAfterReinclude(path.join(rootPath, 'pnpm-lock.yaml'))).toBe(false);
3241
});
3342

3443
test('does not let explicit files bypass ignore patterns', () => {
@@ -45,7 +54,7 @@ test('matches parent directory patterns without validation', () => {
4554
expect(isIgnored(path.join(rootPath, 'shared/index.js'))).toBe(false);
4655
});
4756

48-
test('does not ignore files when no patterns are configured', () => {
57+
test('does not ignore other files when no patterns are configured', () => {
4958
const isIgnored = createMatcher([]);
5059

5160
expect(isIgnored(path.join(rootPath, 'src/index.js'))).toBe(false);

‎rstack.config.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ define.lint(async () => {
4040
});
4141

4242
define.fmt({
43-
ignorePatterns: ['**/dist/**', 'pnpm-lock.yaml'],
4443
printWidth: 100,
4544
singleQuote: true,
4645
sortPackageJson: true,

‎website/docs/en/guide/formatting.mdx‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ define.fmt({
8585

8686
Patterns follow Gitignore syntax and are resolved relative to the directory containing the Rstack configuration file. Because they are applied after the files are selected, they also exclude files passed explicitly on the command line.
8787

88+
### Lock files
89+
90+
By default, `rs fmt` ignores common lock files, including `package-lock.json` and `pnpm-lock.yaml`.
91+
92+
To format these files, use a negated pattern to explicitly include them:
93+
94+
```ts title="rstack.config.ts"
95+
import { define } from 'rstack';
96+
97+
define.fmt({
98+
ignorePatterns: ['!pnpm-lock.yaml'],
99+
});
100+
```
101+
88102
## Sort package.json fields \{#sort-package-json}
89103

90104
Enable `sortPackageJson` to sort fields in each selected `package.json` with [`sort-package-json`](https://github.com/keithamus/sort-package-json):

‎website/docs/zh/guide/formatting.mdx‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ define.fmt({
8585

8686
这些模式遵循 Gitignore 语法,并且基于 Rstack 配置文件所在的目录解析。由于规则会在确定格式化范围后生效,因此也会排除命令行中显式传入的文件。
8787

88+
### Lock 文件 \{#lock-files}
89+
90+
`rs fmt` 默认忽略常见的 lock 文件,包括 `package-lock.json` 和 `pnpm-lock.yaml`。
91+
92+
如果你需要格式化这些文件,可以使用否定模式主动包含它们:
93+
94+
```ts title="rstack.config.ts"
95+
import { define } from 'rstack';
96+
97+
define.fmt({
98+
ignorePatterns: ['!pnpm-lock.yaml'],
99+
});
100+
```
101+
88102
## 排序 package.json 字段 \{#sort-package-json}
89103

90104
启用 `sortPackageJson` 后,`rs fmt` 会使用 [`sort-package-json`](https://github.com/keithamus/sort-package-json) 对每个待格式化的 `package.json` 中的字段排序:

0 commit comments

Comments
 (0)