Skip to content

Commit fc328b7

Browse files
committed
refactor: simplify script sorting
1 parent 0e0ac4c commit fc328b7

File tree

2 files changed

+41
-97
lines changed

2 files changed

+41
-97
lines changed

packages/pkg/src/utils.ts

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,87 +14,55 @@ export const sortStringArray = (a: StringLiteral, b: StringLiteral) =>
1414
alphabetSort(a.value, b.value)
1515

1616
const getScriptSortProps = (
17-
currentScriptName: string,
18-
allScriptNames: string[],
17+
scriptName: string,
18+
allScriptNames: Set<string>,
1919
) => {
20-
const ranks: number[] = []
21-
let base = currentScriptName
20+
if (scriptName.length > 3 && scriptName.startsWith('pre')) {
21+
const base = scriptName.slice(3)
2222

23-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
24-
while (true) {
25-
if (base.length > 3 && base.startsWith('pre')) {
26-
const currentBase = base.slice(3)
27-
28-
if (allScriptNames.includes(currentBase)) {
29-
ranks.push(-1)
30-
base = currentBase
31-
continue
23+
if (allScriptNames.has(base)) {
24+
return {
25+
base,
26+
order: -1,
3227
}
3328
}
29+
}
3430

31+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
32+
if (scriptName.length > 4 && scriptName.startsWith('post')) {
3533
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
36-
if (base.length > 4 && base.startsWith('post')) {
37-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
38-
const currentBase = base.slice(4)
34+
const base = scriptName.slice(4)
3935

40-
if (allScriptNames.includes(currentBase)) {
41-
ranks.push(1)
42-
base = currentBase
43-
continue
36+
if (allScriptNames.has(base)) {
37+
return {
38+
base,
39+
order: 1,
4440
}
4541
}
46-
47-
break
4842
}
4943

5044
return {
51-
base,
52-
// eslint-disable-next-line sonarjs/no-misleading-array-reverse
53-
ranks: ranks.reverse(),
45+
base: scriptName,
46+
order: 0,
5447
}
5548
}
5649

5750
export const sortScriptNames = (scriptNames: string[]) => {
58-
scriptNames = [...new Set(scriptNames)]
51+
const scriptNameSet = new Set(scriptNames)
52+
scriptNames = [...scriptNameSet]
5953

60-
return [...scriptNames].sort((a, b) => {
61-
const left = getScriptSortProps(a, scriptNames)
62-
const right = getScriptSortProps(b, scriptNames)
54+
return scriptNames.sort((a, b) => {
55+
const left = getScriptSortProps(a, scriptNameSet)
56+
const right = getScriptSortProps(b, scriptNameSet)
6357

64-
/*
65-
* Attempt to compare resolved base names first. Example: `prebuild`,
66-
* `build`, and `postbuild` all compare on the base name `build`.
67-
*/
6858
if (left.base !== right.base) {
6959
return alphabetSort(left.base, right.base)
7060
}
7161

72-
/*
73-
* For scripts with the same base name, compare rank arrays. Instead of
74-
* a single comparator value, we compare arrays of ranks in order to
75-
* properly handle nested prefixes.
76-
*/
77-
const length = Math.max(left.ranks.length, right.ranks.length)
78-
let priority = 0
79-
80-
for (let i = 0; i < length; i++) {
81-
const leftOrder = left.ranks[i] ?? 0
82-
const rightOrder = right.ranks[i] ?? 0
83-
84-
if (leftOrder !== rightOrder) {
85-
priority = alphabetSort(leftOrder, rightOrder)
86-
break
87-
}
88-
}
89-
90-
if (priority !== 0) {
91-
return priority
62+
if (left.order !== right.order) {
63+
return alphabetSort(left.order, right.order)
9264
}
9365

94-
/*
95-
* If both the base name and ranks are equal, fall back to alphabetical
96-
* comparison of the full script names.
97-
*/
9866
return alphabetSort(a, b)
9967
})
10068
}

packages/pkg/test/utils.spec.ts

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ describe('sortScriptNames', () => {
2121
'test',
2222
'posttest',
2323
])
24+
25+
expect(
26+
sortScriptNames([
27+
/* prettier-ignore */
28+
'postprepare',
29+
'prepare',
30+
'preprepare',
31+
'test',
32+
]),
33+
).toEqual([
34+
/* prettier-ignore */
35+
'preprepare',
36+
'prepare',
37+
'postprepare',
38+
'test',
39+
])
2440
})
2541

2642
test('ignores unmatched pre/post hooks', () => {
@@ -56,44 +72,4 @@ describe('sortScriptNames', () => {
5672
'test',
5773
])
5874
})
59-
60-
test('handles nested pre/post prefixes', () => {
61-
expect(
62-
sortScriptNames([
63-
'format',
64-
'postformat',
65-
'postposttest',
66-
'posttest',
67-
'preformat',
68-
'preposttest',
69-
'prepreformat',
70-
'pretest',
71-
'test',
72-
]),
73-
).toEqual([
74-
'prepreformat',
75-
'preformat',
76-
'format',
77-
'postformat',
78-
'pretest',
79-
'test',
80-
'preposttest',
81-
'posttest',
82-
'postposttest',
83-
])
84-
85-
expect(
86-
sortScriptNames([
87-
/* prettier-ignore */
88-
'prepare',
89-
'postprepare',
90-
'preprepare',
91-
]),
92-
).toEqual([
93-
/* prettier-ignore */
94-
'preprepare',
95-
'prepare',
96-
'postprepare',
97-
])
98-
})
9975
})

0 commit comments

Comments
 (0)