Skip to content

Commit f38ea40

Browse files
committed
fix(format): write files if only whitespace changes
Closes #54
1 parent a61d384 commit f38ea40

14 files changed

Lines changed: 29541 additions & 69 deletions

src/commands/__snapshots__/fix-mismatches.spec.ts.snap

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ Array [
99
},
1010
},
1111
"filePath": "/a/package.json",
12+
"json": "{
13+
\\"dependencies\\": {
14+
\\"foo\\": \\"link:vendor/foo-0.1.0\\"
15+
}
16+
}
17+
",
1218
},
1319
Object {
1420
"contents": Object {
@@ -17,6 +23,12 @@ Array [
1723
},
1824
},
1925
"filePath": "/b/package.json",
26+
"json": "{
27+
\\"dependencies\\": {
28+
\\"foo\\": \\"link:vendor/foo-0.2.0\\"
29+
}
30+
}
31+
",
2032
},
2133
Object {
2234
"contents": Object {
@@ -25,6 +37,12 @@ Array [
2537
},
2638
},
2739
"filePath": "/c/package.json",
40+
"json": "{
41+
\\"dependencies\\": {
42+
\\"foo\\": \\"0.3.0\\"
43+
}
44+
}
45+
",
2846
},
2947
Object {
3048
"contents": Object {
@@ -33,6 +51,12 @@ Array [
3351
},
3452
},
3553
"filePath": "/d/package.json",
54+
"json": "{
55+
\\"dependencies\\": {
56+
\\"foo\\": \\"0.2.0\\"
57+
}
58+
}
59+
",
3660
},
3761
]
3862
`;
@@ -46,6 +70,12 @@ Array [
4670
},
4771
},
4872
"filePath": "/a/package.json",
73+
"json": "{
74+
\\"dependencies\\": {
75+
\\"foo\\": \\"0.1.0\\"
76+
}
77+
}
78+
",
4979
},
5080
Object {
5181
"contents": Object {
@@ -54,13 +84,24 @@ Array [
5484
},
5585
},
5686
"filePath": "/b/package.json",
87+
"json": "{
88+
\\"devDependencies\\": {
89+
\\"foo\\": \\"0.2.0\\"
90+
}
91+
}
92+
",
5793
},
5894
Object {
5995
"contents": Object {
6096
"name": "foo",
6197
"version": "0.0.1",
6298
},
6399
"filePath": "/foo/package.json",
100+
"json": "{
101+
\\"name\\": \\"foo\\",
102+
\\"version\\": \\"0.0.1\\"
103+
}
104+
",
64105
},
65106
]
66107
`;
@@ -74,6 +115,12 @@ Array [
74115
},
75116
},
76117
"filePath": "/a/package.json",
118+
"json": "{
119+
\\"dependencies\\": {
120+
\\"foo\\": \\"0.1.0\\"
121+
}
122+
}
123+
",
77124
},
78125
Object {
79126
"contents": Object {
@@ -82,6 +129,12 @@ Array [
82129
},
83130
},
84131
"filePath": "/b/package.json",
132+
"json": "{
133+
\\"devDependencies\\": {
134+
\\"foo\\": \\"0.2.0\\"
135+
}
136+
}
137+
",
85138
},
86139
]
87140
`;

src/commands/format.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { withJson } from '../../test/mock';
12
import { DEFAULT_CONFIG } from '../constants';
23
import { format } from './format';
34
import { Source, SourceWrapper } from './lib/get-wrappers';
45

5-
const createWrapper = (contents: Source): SourceWrapper => ({ contents, filePath: '' });
6+
const createWrapper = (contents: Source): SourceWrapper => withJson({ contents, filePath: '' });
67

78
describe('format', () => {
89
it('sorts Array properties alphabetically by value', () => {

src/commands/lib/get-wrappers.spec.ts

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { removeSync } from 'fs-extra';
22
import { getWrappers, SourceWrapper } from './get-wrappers';
33
import mock = require('mock-fs');
4+
import { toJson, withJson } from '../../../test/mock';
45

56
describe('getWrappers', () => {
67
afterEach(() => {
@@ -13,21 +14,22 @@ describe('getWrappers', () => {
1314

1415
beforeEach(() => {
1516
mock({
16-
'package.json': JSON.stringify({ name: 'root' }),
17-
'cli/a/package.json': JSON.stringify({ name: 'cli-a' }),
18-
'cli/b/package.json': JSON.stringify({ name: 'cli-b' }),
19-
'lerna.json': JSON.stringify({ packages: ['lerna/*'] }),
20-
'lerna/a/package.json': JSON.stringify({ name: 'lerna-a' }),
21-
'lerna/b/package.json': JSON.stringify({ name: 'lerna-b' }),
22-
'packages/a/package.json': JSON.stringify({ name: 'packages-a' }),
23-
'packages/b/package.json': JSON.stringify({ name: 'packages-b' }),
17+
'package.json': toJson({ name: 'root' }),
18+
'cli/a/package.json': toJson({ name: 'cli-a' }),
19+
'cli/b/package.json': toJson({ name: 'cli-b' }),
20+
'lerna.json': toJson({ packages: ['lerna/*'] }),
21+
'lerna/a/package.json': toJson({ name: 'lerna-a' }),
22+
'lerna/b/package.json': toJson({ name: 'lerna-b' }),
23+
'packages/a/package.json': toJson({ name: 'packages-a' }),
24+
'packages/b/package.json': toJson({ name: 'packages-b' }),
2425
});
2526
});
2627

27-
const getShape = (name: string, filePath: string): SourceWrapper => ({
28-
contents: { name },
29-
filePath: `${process.cwd()}/${filePath}`,
30-
});
28+
const getShape = (name: string, filePath: string): SourceWrapper =>
29+
withJson({
30+
contents: { name },
31+
filePath: `${process.cwd()}/${filePath}`,
32+
});
3133

3234
it('prefers CLI', () => {
3335
const program = { source: ['cli/*/package.json'] };
@@ -64,16 +66,16 @@ describe('getWrappers', () => {
6466
describe('when configuration is an array', () => {
6567
beforeEach(() => {
6668
mock({
67-
'package.json': JSON.stringify({ workspaces: ['as-array/*'] }),
68-
'as-array/a/package.json': JSON.stringify({ name: 'packages-a' }),
69-
'as-array/b/package.json': JSON.stringify({ name: 'packages-b' }),
69+
'package.json': toJson({ workspaces: ['as-array/*'] }),
70+
'as-array/a/package.json': toJson({ name: 'packages-a' }),
71+
'as-array/b/package.json': toJson({ name: 'packages-b' }),
7072
});
7173
});
7274

7375
it('should resolve correctly', () => {
7476
const program = { source: [] };
7577
expect(getWrappers(program)).toEqual([
76-
{ contents: { workspaces: ['as-array/*'] }, filePath: `${process.cwd()}/package.json` },
78+
withJson({ contents: { workspaces: ['as-array/*'] }, filePath: `${process.cwd()}/package.json` }),
7779
getShape('packages-a', 'as-array/a/package.json'),
7880
getShape('packages-b', 'as-array/b/package.json'),
7981
]);
@@ -83,16 +85,19 @@ describe('getWrappers', () => {
8385
describe('when configuration is an object', () => {
8486
beforeEach(() => {
8587
mock({
86-
'package.json': JSON.stringify({ workspaces: { packages: ['as-object/*'] } }),
87-
'as-object/a/package.json': JSON.stringify({ name: 'packages-a' }),
88-
'as-object/b/package.json': JSON.stringify({ name: 'packages-b' }),
88+
'package.json': toJson({ workspaces: { packages: ['as-object/*'] } }),
89+
'as-object/a/package.json': toJson({ name: 'packages-a' }),
90+
'as-object/b/package.json': toJson({ name: 'packages-b' }),
8991
});
9092
});
9193

9294
it('should resolve correctly', () => {
9395
const program = { source: [] };
9496
expect(getWrappers(program)).toEqual([
95-
{ contents: { workspaces: { packages: ['as-object/*'] } }, filePath: `${process.cwd()}/package.json` },
97+
withJson({
98+
contents: { workspaces: { packages: ['as-object/*'] } },
99+
filePath: `${process.cwd()}/package.json`,
100+
}),
96101
getShape('packages-a', 'as-object/a/package.json'),
97102
getShape('packages-b', 'as-object/b/package.json'),
98103
]);
@@ -107,17 +112,17 @@ describe('getWrappers', () => {
107112

108113
beforeEach(() => {
109114
mock({
110-
'package.json': JSON.stringify({ name: 'root' }),
115+
'package.json': toJson({ name: 'root' }),
111116
'pnpm-workspace.yaml': ['packages:', ' - "./*"'].join('\n'),
112-
'a/package.json': JSON.stringify({ name: 'package-a' }),
113-
'b/package.json': JSON.stringify({ name: 'package-b' }),
117+
'a/package.json': toJson({ name: 'package-a' }),
118+
'b/package.json': toJson({ name: 'package-b' }),
114119
});
115120
});
116121

117122
it('should resolve correctly', () => {
118123
const program = { source: [] };
119124
expect(getWrappers(program)).toEqual([
120-
{ contents: { name: 'root' }, filePath: `${process.cwd()}/package.json` },
125+
withJson({ contents: { name: 'root' }, filePath: `${process.cwd()}/package.json` }),
121126
getShape('package-a', 'a/package.json'),
122127
getShape('package-b', 'b/package.json'),
123128
]);

src/commands/lib/get-wrappers.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isArrayOfStrings } from 'expect-more';
2-
import { readJsonSync } from 'fs-extra';
2+
import { readFileSync, readJsonSync } from 'fs-extra';
33
import { sync } from 'glob';
44
import { join, resolve } from 'path';
55
import { sync as readYamlFileSync } from 'read-yaml-file';
@@ -21,14 +21,17 @@ export interface Source {
2121
resolutions?: { [key: string]: string };
2222
scripts?: { [key: string]: string };
2323
version?: string;
24-
[otherProps: string]: string | string[] | { [key: string]: string } | undefined;
24+
workspaces?: string[] | { [key: string]: string[] };
25+
[otherProps: string]: string | string[] | { [key: string]: string | string[] } | undefined;
2526
}
2627

2728
export interface SourceWrapper {
2829
/** the absolute path on disk to this package.json file */
2930
filePath: string;
3031
/** the parsed JSON contents of this package.json file */
3132
contents: Source;
33+
/** the raw file contents of this package.json file */
34+
json: string;
3235
}
3336

3437
const getPatternsFromJson = (
@@ -64,7 +67,14 @@ const getPnpmPatterns = (): string[] | null => {
6467
const getDefaultPatterns = (): string[] => ALL_PATTERNS;
6568
const resolvePattern = (pattern: string): string[] => sync(pattern, { absolute: true });
6669
const reduceFlatArray = (all: string[], next: string[]): string[] => all.concat(next);
67-
const createWrapper = (filePath: string): SourceWrapper => ({ contents: readJsonSync(filePath), filePath });
70+
const createWrapper = (filePath: string): SourceWrapper => {
71+
const json = readFileSync(filePath, { encoding: 'utf8' });
72+
return {
73+
contents: JSON.parse(json),
74+
filePath,
75+
json,
76+
};
77+
};
6878

6979
export const getWrappers = (program: Options): SourceWrapper[] =>
7080
(getCliPatterns(program) || getYarnPatterns() || getPnpmPatterns() || getLernaPatterns() || getDefaultPatterns())

0 commit comments

Comments
 (0)