Skip to content

Commit

Permalink
fix: support for sorting dependenciesMeta in Yarn berry (#323)
Browse files Browse the repository at this point in the history
* fix: support for sorting dependenciesMeta in Yarn berry

* refactor: sortObjectByIdent

- renamed getIdent to getPackageName
- moved getPackageName and parseNameAndVersionRange functions to outer scope.
  • Loading branch information
rickh18 authored Aug 21, 2024
1 parent d4bd8e2 commit 7e1dd1f
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 18 deletions.
56 changes: 39 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,24 @@ const overProperty =
: object
const sortGitHooks = sortObjectBy(gitHooks)

const sortObjectBySemver = sortObjectBy((a, b) => {
const parseNameAndVersionRange = (specifier) => {
// Ignore anything after > & rely on fallback alphanumeric sorting for that
const [nameAndVersion] = specifier.split('>')
const atMatches = [...nameAndVersion.matchAll('@')]
if (
!atMatches.length ||
(atMatches.length === 1 && atMatches[0].index === 0)
) {
return { name: specifier }
}
const splitIndex = atMatches.pop().index
return {
name: nameAndVersion.substring(0, splitIndex),
range: nameAndVersion.substring(splitIndex + 1),
}
const parseNameAndVersionRange = (specifier) => {
// Ignore anything after > & rely on fallback alphanumeric sorting for that
const [nameAndVersion] = specifier.split('>')
const atMatches = [...nameAndVersion.matchAll('@')]
if (
!atMatches.length ||
(atMatches.length === 1 && atMatches[0].index === 0)
) {
return { name: specifier }
}
const splitIndex = atMatches.pop().index
return {
name: nameAndVersion.substring(0, splitIndex),
range: nameAndVersion.substring(splitIndex + 1),
}
}

const sortObjectBySemver = sortObjectBy((a, b) => {
const { name: aName, range: aRange } = parseNameAndVersionRange(a)
const { name: bName, range: bRange } = parseNameAndVersionRange(b)

Expand All @@ -87,6 +88,27 @@ const sortObjectBySemver = sortObjectBy((a, b) => {
return semver.compare(semver.minVersion(aRange), semver.minVersion(bRange))
})

const getPackageName = (ident) => {
const parts = ident.split('@')

if (ident.startsWith('@')) {
// Handle cases where package name starts with '@'
return parts.length > 2 ? parts.slice(0, -1).join('@') : ident
}

// Handle cases where package name doesn't start with '@'
return parts.length > 1 ? parts.slice(0, -1).join('@') : ident
}

const sortObjectByIdent = (a, b) => {
const PackageNameA = getPackageName(a)
const PackageNameB = getPackageName(b)

if (PackageNameA < PackageNameB) return -1
if (PackageNameA > PackageNameB) return 1
return 0
}

// https://github.com/eslint/eslint/blob/acc0e47572a9390292b4e313b4a4bf360d236358/conf/config-schema.js
const eslintBaseConfigProperties = [
// `files` and `excludedFiles` are only on `overrides[]`
Expand Down Expand Up @@ -341,7 +363,7 @@ const fields = [
{ key: 'resolutions', over: sortObject },
{ key: 'dependencies', over: sortObject },
{ key: 'devDependencies', over: sortObject },
{ key: 'dependenciesMeta', over: sortObjectBy(undefined, true) },
{ key: 'dependenciesMeta', over: sortObjectBy(sortObjectByIdent, true) },
{ key: 'peerDependencies', over: sortObject },
// TODO: only sort depth = 2
{ key: 'peerDependenciesMeta', over: sortObjectBy(undefined, true) },
Expand Down
35 changes: 35 additions & 0 deletions tests/_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,40 @@ function sortObjectAlphabetically(t, options = {}) {
}
}

function sortObjectWithRangeAlphabetically(t, options = {}) {
const { maxDepth = 1, expect } = options

for (let depth = 1; depth < maxDepth + 1; depth++) {
sortObject(t, {
...options,
value: keysToObject(
[
'@z-package@1.2.3',
'c-package@1.2.3',
'b-package-package@1.2.3',
'@a-package@1.2.3',
'b-package@1.2.3',
'@b-package',
],
depth,
),
expect:
expect ||
keysToObject(
[
'@a-package@1.2.3',
'@b-package',
'@z-package@1.2.3',
'b-package@1.2.3',
'b-package-package@1.2.3',
'c-package@1.2.3',
],
depth,
),
})
}
}

function sortObject(
t,
{
Expand Down Expand Up @@ -211,6 +245,7 @@ export const macro = {
sortObject,
asItIs,
sortObjectAlphabetically,
sortObjectWithRangeAlphabetically,
testCLI,
uniqueArray,
uniqueAndSort,
Expand Down
9 changes: 8 additions & 1 deletion tests/deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ test('peerDependenciesMeta', macro.sortObjectAlphabetically, {
expect: 'snapshot',
})

// peerDependenciesMeta
// dependenciesMeta
test('dependenciesMeta', macro.sortObjectAlphabetically, {
path: 'dependenciesMeta',
maxDepth: 2,
// TODO: don't use snapshot, find a esaier way for review
expect: 'snapshot',
})

test('dependenciesMetaRange', macro.sortObjectWithRangeAlphabetically, {
path: 'dependenciesMeta',
maxDepth: 2,
// TODO: don't use snapshot, find a esaier way for review
expect: 'snapshot',
})
140 changes: 140 additions & 0 deletions tests/snapshots/deps.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,143 @@ Generated by [AVA](https://avajs.dev).
}`,
pretty: true,
}

## dependenciesMetaRange

> Should sort `dependenciesMeta` as object.
{
input: `{␊
"dependenciesMeta": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
}␊
}`,
options: undefined,
output: `{␊
"dependenciesMeta": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
}␊
}`,
pretty: true,
}

> Should sort `dependenciesMeta` as object.
{
input: `{␊
"dependenciesMeta": {␊
"@z-package@1.2.3": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
},␊
"c-package@1.2.3": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
},␊
"b-package-package@1.2.3": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
},␊
"@a-package@1.2.3": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
},␊
"b-package@1.2.3": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
},␊
"@b-package": {␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"@b-package": "@b-package"␊
}␊
}␊
}`,
options: undefined,
output: `{␊
"dependenciesMeta": {␊
"@a-package@1.2.3": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
},␊
"@b-package": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
},␊
"@z-package@1.2.3": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
},␊
"b-package@1.2.3": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
},␊
"b-package-package@1.2.3": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
},␊
"c-package@1.2.3": {␊
"@a-package@1.2.3": "@a-package@1.2.3",␊
"@b-package": "@b-package",␊
"@z-package@1.2.3": "@z-package@1.2.3",␊
"b-package@1.2.3": "b-package@1.2.3",␊
"b-package-package@1.2.3": "b-package-package@1.2.3",␊
"c-package@1.2.3": "c-package@1.2.3"␊
}␊
}␊
}`,
pretty: true,
}
Binary file modified tests/snapshots/deps.js.snap
Binary file not shown.

0 comments on commit 7e1dd1f

Please sign in to comment.