Skip to content

Commit 9e065b9

Browse files
authored
fix(prettier-plugin-pkg): group default lifecycle script hooks together (#503)
1 parent d759b19 commit 9e065b9

File tree

3 files changed

+115
-20
lines changed

3 files changed

+115
-20
lines changed

.changeset/witty-lions-decide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"prettier-plugin-pkg": patch
3+
---
4+
5+
Fixed an omission in script sorting where default `pre`/`post` lifecycle scripts were treated as unrelated hooks and not sorted together.

packages/pkg/src/utils.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
import type { ObjectProperty, StringLiteral } from './types.js'
22

3+
/**
4+
* The list of default lifecycle scripts defined by `npm`.
5+
* @see https://docs.npmjs.com/cli/v11/using-npm/scripts
6+
*/
7+
const DEFAULT_LIFECYCLE_SCRIPTS = new Set([
8+
'dependencies',
9+
'install',
10+
'pack',
11+
'prepare',
12+
'publish',
13+
'restart',
14+
'shrinkwrap',
15+
'start',
16+
'stop',
17+
'test',
18+
'version',
19+
])
20+
321
export function alphabetSort(a: number, b: number): number
422
export function alphabetSort(a: string, b: string): number
523
export function alphabetSort(a: number | string, b: number | string) {
@@ -17,15 +35,17 @@ const getScriptSortProps = (
1735
scriptName: string,
1836
allScriptNames: Set<string>,
1937
) => {
20-
// 1. Ensuring that `prepare` doesn’t get treated as `pare`
21-
if (
22-
scriptName.length > 3 &&
23-
scriptName.startsWith('pre') &&
24-
scriptName !== 'prepare' /* 1 */
25-
) {
38+
if (DEFAULT_LIFECYCLE_SCRIPTS.has(scriptName)) {
39+
return {
40+
base: scriptName,
41+
order: 0,
42+
}
43+
}
44+
45+
if (scriptName.length > 3 && scriptName.startsWith('pre')) {
2646
const base = scriptName.slice(3)
2747

28-
if (allScriptNames.has(base)) {
48+
if (allScriptNames.has(base) || DEFAULT_LIFECYCLE_SCRIPTS.has(base)) {
2949
return {
3050
base,
3151
order: -1,
@@ -38,7 +58,7 @@ const getScriptSortProps = (
3858
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
3959
const base = scriptName.slice(4)
4060

41-
if (allScriptNames.has(base)) {
61+
if (allScriptNames.has(base) || DEFAULT_LIFECYCLE_SCRIPTS.has(base)) {
4262
return {
4363
base,
4464
order: 1,

packages/pkg/test/utils.spec.ts

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,148 @@ describe('sortScriptNames', () => {
44
test('sorts pre/post hooks around base script names', () => {
55
expect(
66
sortScriptNames([
7-
/* prettier-ignore */
87
'format',
98
'postformat',
109
'posttest',
1110
'preformat',
1211
'pretest',
1312
'test',
13+
'watch', // control
14+
'patch', // control
15+
'migrate', // control
16+
'ignore', // control
17+
'build', // control
1418
]),
1519
).toEqual([
16-
/* prettier-ignore */
20+
'build', // control
1721
'preformat',
1822
'format',
1923
'postformat',
24+
'ignore', // control
25+
'migrate', // control
26+
'patch', // control
2027
'pretest',
2128
'test',
2229
'posttest',
30+
'watch', // control
2331
])
2432
})
2533

2634
test('ignores unmatched pre/post hooks', () => {
2735
expect(
2836
sortScriptNames([
29-
/* prettier-ignore */
30-
'postformat',
37+
'postformat', // (unmatched)
3138
'posttest',
32-
'prelint',
39+
'prelint', // (unmatched)
3340
'pretest',
3441
'test',
42+
'watch', // control
43+
'patch', // control
44+
'migrate', // control
45+
'ignore', // control
46+
'build', // control
3547
]),
3648
).toEqual([
37-
/* prettier-ignore */
38-
'postformat',
39-
'prelint',
49+
'build', // control
50+
'ignore', // control
51+
'migrate', // control
52+
'patch', // control
53+
'postformat', // (unmatched)
54+
'prelint', // (unmatched)
4055
'pretest',
4156
'test',
4257
'posttest',
58+
'watch', // control
4359
])
4460

4561
expect(
4662
sortScriptNames([
47-
/* prettier-ignore */
4863
'test',
4964
'pre',
5065
'post',
66+
'watch', // control
67+
'patch', // control
68+
'migrate', // control
69+
'ignore', // control
70+
'build', // control
5171
]),
5272
).toEqual([
53-
/* prettier-ignore */
73+
'build', // control
74+
'ignore', // control
75+
'migrate', // control
76+
'patch', // control
5477
'post',
5578
'pre',
5679
'test',
80+
'watch', // control
5781
])
5882
})
5983

6084
test('respects default lifecycle scripts', () => {
85+
// `pare` isn’t grouped with `prepare`
6186
expect(
6287
sortScriptNames([
63-
/* prettier-ignore */
6488
'postprepare',
6589
'prepare',
6690
'preprepare',
6791
'test',
6892
'postpare',
6993
'pare',
94+
'watch', // control
95+
'patch', // control
96+
'migrate', // control
97+
'ignore', // control
98+
'build', // control
7099
]),
71100
).toEqual([
72-
/* prettier-ignore */
101+
'build', // control
102+
'ignore', // control
103+
'migrate', // control
73104
'pare',
74105
'postpare',
106+
'patch', // control
75107
'preprepare',
76108
'prepare',
77109
'postprepare',
78110
'test',
111+
'watch', // control
112+
])
113+
114+
// DLS hooks are grouped together even though their base is missing
115+
expect(
116+
sortScriptNames([
117+
'test',
118+
'postversion', // (single DLS hook)
119+
'postinstall',
120+
'postmerge', // (not a DLS)
121+
'postpack',
122+
'posttest',
123+
'preinstall',
124+
'premerge', // (not a DLS)
125+
'prepack',
126+
'pretest',
127+
'watch', // control
128+
'patch', // control
129+
'migrate', // control
130+
'ignore', // control
131+
'build', // control
132+
]),
133+
).toEqual([
134+
'build', // control
135+
'ignore', // control
136+
'preinstall',
137+
'postinstall',
138+
'migrate', // control
139+
'prepack',
140+
'postpack',
141+
'patch', // control
142+
'postmerge', // (not a DLS)
143+
'premerge', // (not a DLS)
144+
'pretest',
145+
'test',
146+
'posttest',
147+
'postversion', // (single DLS hook)
148+
'watch', // control
79149
])
80150
})
81151
})

0 commit comments

Comments
 (0)