yarn-berry-deduplicate 6.1.2 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +162 -141
- package/dist/applyClusterFixes.js +246 -0
- package/dist/applyClusterFixes.js.map +1 -0
- package/dist/applyClusterFixes.test.js +306 -0
- package/dist/applyClusterFixes.test.js.map +1 -0
- package/dist/bin/yarn-berry-deduplicate.js +37 -0
- package/dist/bin/yarn-berry-deduplicate.js.map +1 -0
- package/dist/bin/yarn-berry-deduplicate.test.js +177 -0
- package/dist/bin/yarn-berry-deduplicate.test.js.map +1 -0
- package/dist/bin/yarn-berry-why-duplicate.js +23 -0
- package/dist/bin/yarn-berry-why-duplicate.js.map +1 -0
- package/dist/dedupeEndToEnd.test.js +140 -0
- package/dist/dedupeEndToEnd.test.js.map +1 -0
- package/dist/definitions/applyClusterFixes.d.ts +23 -0
- package/dist/definitions/applyClusterFixes.d.ts.map +1 -0
- package/dist/definitions/applyClusterFixes.test.d.ts +2 -0
- package/dist/definitions/applyClusterFixes.test.d.ts.map +1 -0
- package/dist/definitions/bin/yarn-berry-deduplicate.d.ts +3 -0
- package/dist/definitions/bin/yarn-berry-deduplicate.d.ts.map +1 -0
- package/dist/definitions/bin/yarn-berry-deduplicate.test.d.ts +2 -0
- package/dist/definitions/bin/yarn-berry-deduplicate.test.d.ts.map +1 -0
- package/dist/definitions/bin/yarn-berry-why-duplicate.d.ts +3 -0
- package/dist/definitions/bin/yarn-berry-why-duplicate.d.ts.map +1 -0
- package/dist/definitions/dedupeEndToEnd.test.d.ts +2 -0
- package/dist/definitions/dedupeEndToEnd.test.d.ts.map +1 -0
- package/dist/definitions/displayMany.d.ts +17 -0
- package/dist/definitions/displayMany.d.ts.map +1 -0
- package/dist/definitions/displayMany.test.d.ts +2 -0
- package/dist/definitions/displayMany.test.d.ts.map +1 -0
- package/dist/definitions/helpers/applyIdentifiedFixesToYarnLock.d.ts +25 -0
- package/dist/definitions/helpers/applyIdentifiedFixesToYarnLock.d.ts.map +1 -0
- package/dist/definitions/helpers/applyIdentifiedFixesToYarnLock.test.d.ts +2 -0
- package/dist/definitions/helpers/applyIdentifiedFixesToYarnLock.test.d.ts.map +1 -0
- package/dist/definitions/helpers/buildYarnPackagesMap.d.ts +11 -0
- package/dist/definitions/helpers/buildYarnPackagesMap.d.ts.map +1 -0
- package/dist/definitions/helpers/buildYarnPackagesMap.test.d.ts +2 -0
- package/dist/definitions/helpers/buildYarnPackagesMap.test.d.ts.map +1 -0
- package/dist/definitions/helpers/collectWorkspaces.d.ts +25 -0
- package/dist/definitions/helpers/collectWorkspaces.d.ts.map +1 -0
- package/dist/definitions/helpers/collectWorkspaces.test.d.ts +2 -0
- package/dist/definitions/helpers/collectWorkspaces.test.d.ts.map +1 -0
- package/dist/definitions/helpers/collectYarnDependents.d.ts +26 -0
- package/dist/definitions/helpers/collectYarnDependents.d.ts.map +1 -0
- package/dist/definitions/helpers/collectYarnDependents.test.d.ts +2 -0
- package/dist/definitions/helpers/collectYarnDependents.test.d.ts.map +1 -0
- package/dist/definitions/helpers/duplicateSnapshot.d.ts +3 -0
- package/dist/definitions/helpers/duplicateSnapshot.d.ts.map +1 -0
- package/dist/definitions/helpers/fixtures.d.ts +14 -0
- package/dist/definitions/helpers/fixtures.d.ts.map +1 -0
- package/dist/definitions/helpers/packageJsonResolutions.d.ts +8 -0
- package/dist/definitions/helpers/packageJsonResolutions.d.ts.map +1 -0
- package/dist/definitions/helpers/packageJsonResolutions.test.d.ts +2 -0
- package/dist/definitions/helpers/packageJsonResolutions.test.d.ts.map +1 -0
- package/dist/definitions/helpers/parseYarnLockPackages.d.ts +21 -0
- package/dist/definitions/helpers/parseYarnLockPackages.d.ts.map +1 -0
- package/dist/definitions/helpers/parseYarnLockPackages.test.d.ts +2 -0
- package/dist/definitions/helpers/parseYarnLockPackages.test.d.ts.map +1 -0
- package/dist/definitions/helpers/projectDir.d.ts +3 -0
- package/dist/definitions/helpers/projectDir.d.ts.map +1 -0
- package/dist/definitions/helpers/runYarn.d.ts +11 -0
- package/dist/definitions/helpers/runYarn.d.ts.map +1 -0
- package/dist/definitions/helpers/syml.d.ts +27 -0
- package/dist/definitions/helpers/syml.d.ts.map +1 -0
- package/dist/definitions/helpers/tempProjects.d.ts +8 -0
- package/dist/definitions/helpers/tempProjects.d.ts.map +1 -0
- package/dist/definitions/helpers/toLockstepGraph.d.ts +4 -0
- package/dist/definitions/helpers/toLockstepGraph.d.ts.map +1 -0
- package/dist/definitions/helpers/toLockstepGraph.test.d.ts +2 -0
- package/dist/definitions/helpers/toLockstepGraph.test.d.ts.map +1 -0
- package/dist/definitions/helpers/versionsSnapshot.d.ts +5 -0
- package/dist/definitions/helpers/versionsSnapshot.d.ts.map +1 -0
- package/dist/definitions/helpers/writeYarnLockFile.d.ts +3 -0
- package/dist/definitions/helpers/writeYarnLockFile.d.ts.map +1 -0
- package/dist/definitions/helpers/yarnDescriptor.d.ts +6 -0
- package/dist/definitions/helpers/yarnDescriptor.d.ts.map +1 -0
- package/dist/definitions/helpers/yarnDescriptor.test.d.ts +2 -0
- package/dist/definitions/helpers/yarnDescriptor.test.d.ts.map +1 -0
- package/dist/definitions/helpers/yarnProtocol.d.ts +2 -0
- package/dist/definitions/helpers/yarnProtocol.d.ts.map +1 -0
- package/dist/definitions/identifyClusterFixes.d.ts +7 -0
- package/dist/definitions/identifyClusterFixes.d.ts.map +1 -0
- package/dist/definitions/identifyClusterFixes.test.d.ts +2 -0
- package/dist/definitions/identifyClusterFixes.test.d.ts.map +1 -0
- package/dist/definitions/identifyResolutionFixes.test.d.ts +2 -0
- package/dist/definitions/identifyResolutionFixes.test.d.ts.map +1 -0
- package/dist/definitions/index.d.ts +40 -0
- package/dist/definitions/index.d.ts.map +1 -0
- package/dist/definitions/readYarnLock.d.ts +10 -0
- package/dist/definitions/readYarnLock.d.ts.map +1 -0
- package/dist/definitions/readYarnLock.test.d.ts +2 -0
- package/dist/definitions/readYarnLock.test.d.ts.map +1 -0
- package/dist/displayMany.js +61 -0
- package/dist/displayMany.js.map +1 -0
- package/dist/displayMany.test.js +79 -0
- package/dist/displayMany.test.js.map +1 -0
- package/dist/helpers/applyIdentifiedFixesToYarnLock.js +99 -0
- package/dist/helpers/applyIdentifiedFixesToYarnLock.js.map +1 -0
- package/dist/helpers/applyIdentifiedFixesToYarnLock.test.js +245 -0
- package/dist/helpers/applyIdentifiedFixesToYarnLock.test.js.map +1 -0
- package/dist/helpers/buildYarnPackagesMap.js +22 -0
- package/dist/helpers/buildYarnPackagesMap.js.map +1 -0
- package/dist/helpers/buildYarnPackagesMap.test.js +37 -0
- package/dist/helpers/buildYarnPackagesMap.test.js.map +1 -0
- package/dist/helpers/collectWorkspaces.js +53 -0
- package/dist/helpers/collectWorkspaces.js.map +1 -0
- package/dist/helpers/collectWorkspaces.test.js +60 -0
- package/dist/helpers/collectWorkspaces.test.js.map +1 -0
- package/dist/helpers/collectYarnDependents.js +138 -0
- package/dist/helpers/collectYarnDependents.js.map +1 -0
- package/dist/helpers/collectYarnDependents.test.js +156 -0
- package/dist/helpers/collectYarnDependents.test.js.map +1 -0
- package/dist/helpers/duplicateSnapshot.js +5 -0
- package/dist/helpers/duplicateSnapshot.js.map +1 -0
- package/dist/helpers/fixtures.js +20 -0
- package/dist/helpers/fixtures.js.map +1 -0
- package/dist/helpers/packageJsonResolutions.js +16 -0
- package/dist/helpers/packageJsonResolutions.js.map +1 -0
- package/dist/helpers/packageJsonResolutions.test.js +17 -0
- package/dist/helpers/packageJsonResolutions.test.js.map +1 -0
- package/dist/helpers/parseYarnLockPackages.js +47 -0
- package/dist/helpers/parseYarnLockPackages.js.map +1 -0
- package/dist/helpers/parseYarnLockPackages.test.js +63 -0
- package/dist/helpers/parseYarnLockPackages.test.js.map +1 -0
- package/dist/helpers/projectDir.js +10 -0
- package/dist/helpers/projectDir.js.map +1 -0
- package/dist/helpers/runYarn.js +12 -0
- package/dist/helpers/runYarn.js.map +1 -0
- package/dist/helpers/syml.js +9 -0
- package/dist/helpers/syml.js.map +1 -0
- package/dist/helpers/tempProjects.js +85 -0
- package/dist/helpers/tempProjects.js.map +1 -0
- package/dist/helpers/toLockstepGraph.js +44 -0
- package/dist/helpers/toLockstepGraph.js.map +1 -0
- package/dist/helpers/toLockstepGraph.test.js +41 -0
- package/dist/helpers/toLockstepGraph.test.js.map +1 -0
- package/dist/helpers/versionsSnapshot.js +6 -0
- package/dist/helpers/versionsSnapshot.js.map +1 -0
- package/dist/helpers/writeYarnLockFile.js +16 -0
- package/dist/helpers/writeYarnLockFile.js.map +1 -0
- package/dist/helpers/yarnDescriptor.js +25 -0
- package/dist/helpers/yarnDescriptor.js.map +1 -0
- package/dist/helpers/yarnDescriptor.test.js +53 -0
- package/dist/helpers/yarnDescriptor.test.js.map +1 -0
- package/dist/helpers/yarnProtocol.js +2 -0
- package/dist/helpers/yarnProtocol.js.map +1 -0
- package/dist/identifyClusterFixes.js +52 -0
- package/dist/identifyClusterFixes.js.map +1 -0
- package/dist/identifyClusterFixes.test.js +99 -0
- package/dist/identifyClusterFixes.test.js.map +1 -0
- package/dist/identifyResolutionFixes.test.js +79 -0
- package/dist/identifyResolutionFixes.test.js.map +1 -0
- package/dist/index.js +174 -55
- package/dist/index.js.map +1 -1
- package/dist/readYarnLock.js +17 -0
- package/dist/readYarnLock.js.map +1 -0
- package/dist/readYarnLock.test.js +34 -0
- package/dist/readYarnLock.test.js.map +1 -0
- package/package.json +73 -77
- package/src/applyClusterFixes.test.ts +365 -0
- package/src/applyClusterFixes.ts +443 -0
- package/src/bin/yarn-berry-deduplicate.test.ts +249 -0
- package/src/bin/yarn-berry-deduplicate.ts +46 -0
- package/src/bin/yarn-berry-why-duplicate.ts +34 -0
- package/src/dedupeEndToEnd.test.ts +201 -0
- package/src/displayMany.test.ts +103 -0
- package/src/displayMany.ts +106 -0
- package/src/helpers/applyIdentifiedFixesToYarnLock.test.ts +352 -0
- package/src/helpers/applyIdentifiedFixesToYarnLock.ts +130 -0
- package/src/helpers/buildYarnPackagesMap.test.ts +48 -0
- package/src/helpers/buildYarnPackagesMap.ts +45 -0
- package/src/helpers/collectWorkspaces.test.ts +73 -0
- package/src/helpers/collectWorkspaces.ts +90 -0
- package/src/helpers/collectYarnDependents.test.ts +197 -0
- package/src/helpers/collectYarnDependents.ts +232 -0
- package/src/helpers/duplicateSnapshot.ts +20 -0
- package/src/helpers/fixtures.ts +38 -0
- package/src/helpers/packageJsonResolutions.test.ts +28 -0
- package/src/helpers/packageJsonResolutions.ts +24 -0
- package/src/helpers/parseYarnLockPackages.test.ts +88 -0
- package/src/helpers/parseYarnLockPackages.ts +83 -0
- package/src/helpers/projectDir.ts +14 -0
- package/src/helpers/runYarn.ts +30 -0
- package/src/helpers/syml.ts +45 -0
- package/src/helpers/tempProjects.ts +94 -0
- package/src/helpers/toLockstepGraph.test.ts +48 -0
- package/src/helpers/toLockstepGraph.ts +60 -0
- package/src/helpers/versionsSnapshot.ts +12 -0
- package/src/helpers/writeYarnLockFile.ts +25 -0
- package/src/helpers/yarnDescriptor.test.ts +71 -0
- package/src/helpers/yarnDescriptor.ts +41 -0
- package/src/helpers/yarnProtocol.ts +14 -0
- package/src/identifyClusterFixes.test.ts +122 -0
- package/src/identifyClusterFixes.ts +95 -0
- package/src/identifyResolutionFixes.test.ts +115 -0
- package/src/index.ts +327 -0
- package/src/readYarnLock.test.ts +44 -0
- package/src/readYarnLock.ts +22 -0
- package/AUTHORS.md +0 -30
- package/CHANGELOG.md +0 -307
- package/CODE_OF_CONDUCT.md +0 -44
- package/LICENSE.md +0 -160
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -89
- package/dist/cli.js.map +0 -1
- package/dist/computePackageInstances.d.ts +0 -5
- package/dist/computePackageInstances.d.ts.map +0 -1
- package/dist/computePackageInstances.js +0 -89
- package/dist/computePackageInstances.js.map +0 -1
- package/dist/extractPackages.d.ts +0 -27
- package/dist/extractPackages.d.ts.map +0 -1
- package/dist/extractPackages.js +0 -78
- package/dist/extractPackages.js.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/sharedTypes.d.ts +0 -11
- package/dist/sharedTypes.d.ts.map +0 -1
- package/dist/sharedTypes.js +0 -3
- package/dist/sharedTypes.js.map +0 -1
- package/dist/yarnlock.d.ts +0 -12
- package/dist/yarnlock.d.ts.map +0 -1
- package/dist/yarnlock.js +0 -14
- package/dist/yarnlock.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,178 +1,199 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
yarn-berry-deduplicate
|
|
3
|
+
</h1>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
berry
|
|
5
|
+
<p align="center">
|
|
6
|
+
List duplicates and dedupe yarn berry lock file
|
|
7
|
+
</p>
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
[yarn-deduplicate](https://www.npmjs.com/package/yarn-deduplicate) that works with both highest and
|
|
13
|
-
fewer (renamed "mostCommon") strategies as well as a new "fewerHighest" strategy which combines
|
|
14
|
-
"mostCommon" and "highest".
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://npmjs.org/package/yarn-berry-deduplicate"><img src="https://img.shields.io/npm/v/yarn-berry-deduplicate.svg?style=flat-square" alt="npm version"></a>
|
|
11
|
+
<a href="https://npmjs.org/package/yarn-berry-deduplicate"><img src="https://img.shields.io/npm/dw/yarn-berry-deduplicate.svg?style=flat-square" alt="npm downloads"></a>
|
|
12
|
+
<a href="https://npmjs.org/package/yarn-berry-deduplicate"><img src="https://img.shields.io/node/v/yarn-berry-deduplicate.svg?style=flat-square" alt="node version"></a>
|
|
13
|
+
<a href="https://npmjs.org/package/yarn-berry-deduplicate"><img src="https://img.shields.io/npm/types/yarn-berry-deduplicate.svg?style=flat-square" alt="types"></a>
|
|
14
|
+
</p>
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Requires yarn berry (>= 2). Nothing needs to be installed: `yarn dlx` fetches the
|
|
19
|
+
package. The dedupe bin carries the package's own name, so it runs bare; the
|
|
20
|
+
report bin does not, and `-p yarn-berry-deduplicate` is what tells `yarn dlx`
|
|
21
|
+
which package to fetch for it.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
Installing it (`yarn add -D yarn-berry-deduplicate`) is only worth it to pin a
|
|
24
|
+
version — for a CI gate, say. `yarn exec <bin>` then runs the local one.
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
Both bins may be run from any subdirectory of the project: they walk up to the
|
|
27
|
+
nearest `yarn.lock` and operate on that project, naming the lockfile they found
|
|
28
|
+
on stderr when it is not the working directory.
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
### List duplicates, or explain one
|
|
27
31
|
|
|
28
|
-
```
|
|
29
|
-
yarn dlx yarn-berry-deduplicate
|
|
32
|
+
```
|
|
33
|
+
yarn dlx -p yarn-berry-deduplicate yarn-berry-why-duplicate # one line per duplicated package
|
|
34
|
+
yarn dlx -p yarn-berry-deduplicate yarn-berry-why-duplicate --details # every dependent, and the lockstep clusters
|
|
35
|
+
yarn dlx -p yarn-berry-deduplicate yarn-berry-why-duplicate <dependencyName> # explains the matching packages, detailed
|
|
36
|
+
yarn dlx -p yarn-berry-deduplicate yarn-berry-why-duplicate <dependencyName> --all
|
|
30
37
|
```
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Duplicated packages
|
|
38
|
-
|
|
39
|
-
`yarn.lock` contains a list of all the dependencies required by your project (including transitive
|
|
40
|
-
dependencies), and the actual package version installed to satisfy those dependencies.
|
|
41
|
-
|
|
42
|
-
For the context of this project, a "duplicated package" is a package that appears on multiple nodes
|
|
43
|
-
of the dependency tree with overlapping version ranges but resolved to different versions.
|
|
44
|
-
|
|
45
|
-
For example, imagine that your project directly depends on `lodash` and `babel`, and `babel` depends
|
|
46
|
-
on `lodash` as well. Specifically, your project depends on `lodash@^1.0.0` and `babel` depends on
|
|
47
|
-
`lodash@^1.1.0`. Because how the resolution algorithm works in Yarn, you might end up with two
|
|
48
|
-
different copies of `lodash` (for example, version `1.0.1` and `1.2.0`) in your project, even when
|
|
49
|
-
`1.2.0` will suffice to satisfy both requirements for `lodash`. That's a "duplicated package".
|
|
50
|
-
|
|
51
|
-
It is important to note that we do not consider duplicated packages when the version ranges don't
|
|
52
|
-
overlap. For example, if your project depends on `underscore@^1.0.0` and `underscore@^2.0.0`. Your
|
|
53
|
-
project will end up with two versions of `underscore`, and `yarn-deduplicate` won't change that.
|
|
54
|
-
|
|
55
|
-
When using `yarn-deduplicate` remember that **it will change your dependency tree**. There are
|
|
56
|
-
certain code paths that now will run with a different set of dependencies. It is highly recommended
|
|
57
|
-
that you review each change to `yarn.lock`. If the change is too big, use the flag `--packages` to
|
|
58
|
-
deduplicate them gradually.
|
|
59
|
-
|
|
60
|
-
### Why is this necessary?
|
|
61
|
-
|
|
62
|
-
Yarn documentation seems to suggest this package shouldn't be necessary. For example, in
|
|
63
|
-
https://classic.yarnpkg.com/en/docs/cli/dedupe/, it says
|
|
64
|
-
|
|
65
|
-
> The dedupe command isn’t necessary. `yarn install` will already dedupe.
|
|
66
|
-
|
|
67
|
-
This is, however, not exactly true. There are cases where yarn will _not_ deduplicate existing
|
|
68
|
-
packages. For example, this scenario:
|
|
69
|
-
|
|
70
|
-
- Install `libA`. It depends on `libB ^1.1.0`. At this point, the latest version of `libB` is
|
|
71
|
-
`1.1.2`, so it gets installed as a transitive dependency in your repo
|
|
39
|
+
`<dependencyName>` is a glob, so `@babel/*` works, and several may be named.
|
|
40
|
+
`--all` (`-a`) keeps packages that are not duplicated.
|
|
72
41
|
|
|
73
|
-
|
|
74
|
-
|
|
42
|
+
A named package that is not duplicated still gets its dependents listed —
|
|
43
|
+
"nothing found" is not an answer to "why is this duplicated". `--all` is only
|
|
44
|
+
needed to keep single-version matches next to duplicated ones.
|
|
75
45
|
|
|
76
|
-
|
|
46
|
+
By default the report is one line per duplicated package — the versions it
|
|
47
|
+
resolved to, and what it can be deduped to:
|
|
77
48
|
|
|
78
|
-
|
|
49
|
+
```
|
|
50
|
+
- @eslint/plugin-kit resolved to 2 versions (0.7.1, 0.6.1)
|
|
51
|
+
- picomatch resolved to 3 versions (4.0.4, 4.0.3, 2.3.1), can be deduped to 2 versions
|
|
52
|
+
```
|
|
79
53
|
|
|
80
|
-
|
|
81
|
-
- [De-duplicating yarn.lock](https://medium.com/@scinos/de-duplicating-yarn-lock-ae30be4aa41a)
|
|
82
|
-
- https://github.com/yarnpkg/yarn/issues/3778
|
|
54
|
+
`can be deduped to N versions` always means N remain, never N merged away.
|
|
83
55
|
|
|
84
|
-
|
|
56
|
+
`--details` (`-d`), implied when a package is named, files every dependent under
|
|
57
|
+
the version it resolved to, so the range that keeps each copy alive is read off
|
|
58
|
+
the version it sits under:
|
|
85
59
|
|
|
86
|
-
|
|
60
|
+
```
|
|
61
|
+
@eslint/plugin-kit — 2 versions
|
|
62
|
+
0.7.1
|
|
63
|
+
- check-package-dependencies requires "^0.7.1"
|
|
64
|
+
- eslint requires "^0.7.1"
|
|
65
|
+
0.6.1
|
|
66
|
+
- @eslint/json requires "^0.6.1"
|
|
67
|
+
```
|
|
87
68
|
|
|
88
|
-
|
|
89
|
-
|
|
69
|
+
After the packages come the lockstep clusters — families published together,
|
|
70
|
+
whose duplicates only go away when the whole family moves. A package a cluster
|
|
71
|
+
converges carries the family's target and a `(cluster N)` reference.
|
|
90
72
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
version "1.2.0"
|
|
73
|
+
The dedupable count is a floor: merging a package collapses its own dependency
|
|
74
|
+
edges too, so a run can remove copies no per-package fix predicted.
|
|
94
75
|
|
|
95
|
-
|
|
96
|
-
version "1.2.0"
|
|
76
|
+
### Dedupe
|
|
97
77
|
|
|
98
|
-
|
|
99
|
-
|
|
78
|
+
```
|
|
79
|
+
yarn dlx yarn-berry-deduplicate # apply
|
|
80
|
+
yarn dlx yarn-berry-deduplicate --dry-run # print the plan, change nothing, exit 0
|
|
81
|
+
yarn dlx yarn-berry-deduplicate --check # print the plan, change nothing, exit 1 if anything would change
|
|
100
82
|
```
|
|
101
83
|
|
|
102
|
-
|
|
84
|
+
`--check` is the CI gate; `--dry-run` (`-n`) is the same output without the
|
|
85
|
+
failing exit code.
|
|
103
86
|
|
|
104
|
-
|
|
105
|
-
|
|
87
|
+
Two passes run: the cluster pass edits `package.json` and runs `yarn install`,
|
|
88
|
+
reaching versions the lockfile does not carry; the pure-lock pass then collapses
|
|
89
|
+
the leaves yarn did not merge on its own, by merging descriptors onto one entry.
|
|
90
|
+
`--no-clusters` runs only the second.
|
|
106
91
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
92
|
+
The cluster pass writes `resolutions` in the workspace root `package.json` as
|
|
93
|
+
scaffolding only: it re-resolves without them, and a fix that yarn resolves back
|
|
94
|
+
away from once the resolution is gone is reverted rather than applied. A dedupe
|
|
95
|
+
that needs a standing `resolutions` entry is not one this tool makes.
|
|
110
96
|
|
|
111
|
-
|
|
112
|
-
version "3.0.0"
|
|
97
|
+
A run that changes something ends with what it merged, one line per package:
|
|
113
98
|
|
|
114
|
-
|
|
115
|
-
|
|
99
|
+
```
|
|
100
|
+
Deduped 2 packages, 2 copies merged:
|
|
101
|
+
barcode-detector: 2 versions (3.0.3, 3.2.2) -> 1 version (3.0.3)
|
|
102
|
+
zxing-wasm: 2 versions (2.2.4, 3.1.3) -> 1 version (2.2.4)
|
|
103
|
+
No duplicate left.
|
|
116
104
|
```
|
|
117
105
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
106
|
+
Both passes are covered by that one summary. Both sides of a line are counted
|
|
107
|
+
and named, so a family converging onto an older release reads as two copies
|
|
108
|
+
becoming one rather than as a downgrade; a package only partly collapsed lists
|
|
109
|
+
the versions it still has. The last line counts the duplicates left, as
|
|
110
|
+
`yarn-berry-why-duplicate` counts them.
|
|
122
111
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
is specified again.
|
|
112
|
+
A rewritten lockfile is not an installed one: the run says `yarn.lock updated`
|
|
113
|
+
and asks for a `yarn install` to bring the project in line with it.
|
|
126
114
|
|
|
127
115
|
### Progressive deduplication
|
|
128
116
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
list. This option is recommended when the number of duplicated packages in `yarn.lock` is too big to
|
|
133
|
-
be easily reviewed by a human. This will allow for a more controlled and progressive deduplication
|
|
134
|
-
of `yarn.lock`.
|
|
135
|
-
|
|
136
|
-
`--scopes <scope1> <scope2> <scopeN>`
|
|
137
|
-
|
|
138
|
-
Receives a list of scopes to deduplicate. It will ignore any other duplicated package not in the
|
|
139
|
-
list. This option is recommended when deduplicating a large number of inter-dependent packages from
|
|
140
|
-
a single scope, such as @babel. This will allow for a more controlled and progressive deduplication
|
|
141
|
-
of `yarn.lock` without specifying each package individually.
|
|
142
|
-
|
|
143
|
-
### Excluding packages
|
|
144
|
-
|
|
145
|
-
`--exclude <package1> <package2> <packageN`
|
|
146
|
-
|
|
147
|
-
`--exclude-scopes <scope1> <scope2> <scopeN>`
|
|
117
|
+
Deduping the whole lockfile is the default: a run told nothing takes everything
|
|
118
|
+
it can. In case you only need to dedupe part of it, these flags bound a run to
|
|
119
|
+
the packages you name, and work on both commands:
|
|
148
120
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
By default, `yarn-deduplicate` will only match pre-release versions if they share they share the
|
|
155
|
-
same `major`, `minor` and `patch` versions (example: `^1.2.3-alpha.1` and `1.2.3-alpha.2` can be
|
|
156
|
-
deduplicated, but `^1.2.3` and `1.2.4-alpha.1` can't). This matches the behaviour of
|
|
157
|
-
[semver](https://docs.npmjs.com/misc/semver#prerelease-tags).
|
|
158
|
-
|
|
159
|
-
To change this behaviour you can use the flag `--includePrerelease`. This will treat all pre-release
|
|
160
|
-
versionas as if they were normal versions (`^1.2.3` and `1.2.4-alpha.1` can be deduplicated).
|
|
161
|
-
|
|
162
|
-
### Usage in CI
|
|
163
|
-
|
|
164
|
-
This tool can be used as part of a CI workflow. Adding the flag `--fail` will force the process to
|
|
165
|
-
exit with status 1 if there are duplicated packages. Example:
|
|
166
|
-
|
|
167
|
-
```sh
|
|
168
|
-
# Print the list of duplicated packages and exit with status 1
|
|
169
|
-
yarn dlx yarn-berry-deduplicate --list --fail
|
|
170
|
-
|
|
171
|
-
# Deduplicate yarn.lock and exit with status 1 if changes were required
|
|
172
|
-
yarn dlx yarn-berry-deduplicate --fail
|
|
121
|
+
```
|
|
122
|
+
yarn dlx yarn-berry-deduplicate --dry-run --scopes @babel # one scope
|
|
123
|
+
yarn dlx yarn-berry-deduplicate --dry-run --packages 'lodash,@babel/**' # names or globs
|
|
124
|
+
yarn dlx yarn-berry-deduplicate --dry-run --exclude lodash # everything but these
|
|
125
|
+
yarn dlx yarn-berry-deduplicate --dry-run --exclude-scopes @types
|
|
173
126
|
```
|
|
174
127
|
|
|
175
|
-
|
|
128
|
+
Each flag takes a comma list or is repeated (`--packages a --packages b`).
|
|
129
|
+
Selecting nothing selects everything. `--packages`/`--scopes` say what may be
|
|
130
|
+
touched; `--exclude`/`--exclude-scopes` win over them, so a scope can be taken
|
|
131
|
+
minus a few of its packages. Patterns are globs whose `*` stops at `/`, so
|
|
132
|
+
`@babel/*` matches `@babel/core` and a bare `*` matches only unscoped names.
|
|
133
|
+
|
|
134
|
+
A lockstep cluster moves as one, so a fix is kept only when the filter selects
|
|
135
|
+
every member of its family — otherwise it is skipped and the plan names the
|
|
136
|
+
members that blocked it. Widen the filter to take the family, or leave it for
|
|
137
|
+
another run.
|
|
138
|
+
|
|
139
|
+
`yarn install` still runs during the cluster pass, and it may move entries the
|
|
140
|
+
filter did not select if it considers them stale.
|
|
141
|
+
|
|
142
|
+
Colors follow the terminal: `NO_COLOR` and a piped stdout turn them off,
|
|
143
|
+
`FORCE_COLOR` turns them on.
|
|
144
|
+
|
|
145
|
+
## Peer dependencies
|
|
146
|
+
|
|
147
|
+
A `peerDependencies` range constrains its requester's resolved version exactly
|
|
148
|
+
as a dependency range does, and `yarn.lock` is where the _edge_ goes missing:
|
|
149
|
+
yarn folds a peer provision into the virtual package's `dependencies`, and
|
|
150
|
+
virtual packages are not written to the lockfile. So peer ranges sit in a block
|
|
151
|
+
of their own, with nothing saying who provided them.
|
|
152
|
+
|
|
153
|
+
Peer requesters are therefore read from `peerDependencies` directly, optional
|
|
154
|
+
ones included: whether a peer was actually provided cannot be told from the
|
|
155
|
+
lockfile, and a constraint that may not bind costs a suppressed merge, where a
|
|
156
|
+
missing one costs a merge that breaks a peer. Such a dependent is marked with a
|
|
157
|
+
dim `(peer)` after its range in the report.
|
|
158
|
+
|
|
159
|
+
A peer range never explains why a second version exists — yarn resolves peers
|
|
160
|
+
against what is already in the tree and warns instead of backtracking. It is an
|
|
161
|
+
extra constraint on a package duplicated for other reasons, which is why keeping
|
|
162
|
+
it changes the fixes.
|
|
163
|
+
|
|
164
|
+
Cluster membership is built from `dependencies` only. Adding peers there would
|
|
165
|
+
union unrelated packages into a family: `eslint-plugin-x@9.0.0` peer-depending on
|
|
166
|
+
`eslint@^9.0.0` is co-versioned by coincidence, not published in lockstep.
|
|
167
|
+
|
|
168
|
+
## Notes
|
|
169
|
+
|
|
170
|
+
- `nodeLinker` never reaches the lockfile. Resolution runs before linking, so
|
|
171
|
+
`yarn.lock` is byte-identical under `pnp` and `node-modules`, and nothing here
|
|
172
|
+
reads an installed tree — the same fixes apply either way.
|
|
173
|
+
- Non-npm protocols (`workspace:`, `patch:`, `portal:`, git…) are parsed and
|
|
174
|
+
reported but never merged: only `npm:` resolutions are semver-comparable.
|
|
175
|
+
- The bins run on node (`>=22.18.0`), not on bun.
|
|
176
|
+
|
|
177
|
+
## API
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
import {
|
|
181
|
+
fixDuplicates,
|
|
182
|
+
listDuplicates,
|
|
183
|
+
whyDuplicate,
|
|
184
|
+
} from "yarn-berry-deduplicate";
|
|
185
|
+
|
|
186
|
+
listDuplicates({ details: true });
|
|
187
|
+
whyDuplicate({ filter: { include: ["@babel/*"] }, all: true, details: true });
|
|
188
|
+
fixDuplicates({
|
|
189
|
+
mode: "dry-run",
|
|
190
|
+
clusters: true,
|
|
191
|
+
filter: { includeScopes: ["@babel"] },
|
|
192
|
+
});
|
|
193
|
+
```
|
|
176
194
|
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
`mode` is `"apply"`, `"dry-run"` or `"check"` — the same three the CLI exposes.
|
|
196
|
+
The lockfile parsing and graph building steps are exported too
|
|
197
|
+
(`readAndParseYarnLock`, `parseYarnLockPackages`, `buildYarnPackagesMap`,
|
|
198
|
+
`collectYarnDependents`, `toLockstepGraph`, `writeYarnLockFile`), for building
|
|
199
|
+
something else on top; the algorithm itself lives in [pm-dedup-core](../pm-dedup-core).
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { applyWorkspaceRangeEdit, captureFiles, createPackageFilter, describeSkippedClusterFix, diffDuplicates, partitionUnconditionalOverrides, planClusterApply, renderApplyPlan, restoreFiles, selectClusterFixes, shouldColorize, } from "pm-dedup-core";
|
|
4
|
+
import { buildYarnPackagesMap } from "./helpers/buildYarnPackagesMap.js";
|
|
5
|
+
import { collectWorkspaces, createManifestReader, } from "./helpers/collectWorkspaces.js";
|
|
6
|
+
import { readDuplicateSnapshot } from "./helpers/duplicateSnapshot.js";
|
|
7
|
+
import { addResolutions } from "./helpers/packageJsonResolutions.js";
|
|
8
|
+
import { parseYarnLockPackages } from "./helpers/parseYarnLockPackages.js";
|
|
9
|
+
import { lockPathOf } from "./helpers/projectDir.js";
|
|
10
|
+
import { runYarn } from "./helpers/runYarn.js";
|
|
11
|
+
import { identifyClusterFixes } from "./identifyClusterFixes.js";
|
|
12
|
+
import { readAndParseYarnLock } from "./readYarnLock.js";
|
|
13
|
+
const issuesUrl = "https://github.com/christophehurpeau/pm-tools/issues";
|
|
14
|
+
const defaultReadFixes = (projectDir) => {
|
|
15
|
+
const entries = readAndParseYarnLock(lockPathOf(projectDir));
|
|
16
|
+
const packages = parseYarnLockPackages(entries);
|
|
17
|
+
return identifyClusterFixes(buildYarnPackagesMap(packages), packages, collectWorkspaces(packages, createManifestReader(projectDir)));
|
|
18
|
+
};
|
|
19
|
+
// the root workspace is keyed "", which `join` already treats as the project
|
|
20
|
+
// directory itself
|
|
21
|
+
const manifestPathOf = (projectDir, importerPath) => join(projectDir, importerPath, "package.json");
|
|
22
|
+
const describeOverride = (override) => `"${override.packageName}": "${override.version}"`;
|
|
23
|
+
/**
|
|
24
|
+
* A yarn resolution is matched against the package a descriptor resolves to, so
|
|
25
|
+
* an edge declared through an npm alias
|
|
26
|
+
* (`"psc-pinned": "npm:printable-shell-command@~5.0.0"`) is repointed by a
|
|
27
|
+
* resolution on the *target* name. The resolution is still written, because an
|
|
28
|
+
* in-cluster requester declaring the package directly is repointed by it too,
|
|
29
|
+
* but naming the alias-only requesters keeps a revert from saying nothing.
|
|
30
|
+
*/
|
|
31
|
+
const aliasOnlyRequesters = (fixes, packageName) => {
|
|
32
|
+
const constraints = fixes
|
|
33
|
+
.flatMap((fix) => fix.externalConstraints)
|
|
34
|
+
.filter((constraint) => constraint.packageName === packageName);
|
|
35
|
+
return constraints.length > 0 && constraints.every((c) => c.isAlias === true)
|
|
36
|
+
? constraints.map((constraint) => constraint.requester)
|
|
37
|
+
: [];
|
|
38
|
+
};
|
|
39
|
+
const reuseKeys = (fixes) => new Set(fixes.flatMap((fix) => fix.reuseFixes.map((reuse) => `${reuse.requesterName}>${reuse.packageName}@${reuse.to}`)));
|
|
40
|
+
export const applyClusterFixes = ({ projectDir, dryRun = false, log = console.log,
|
|
41
|
+
// `yarn install` is the only way to reach a version whose manifest the
|
|
42
|
+
// lockfile does not carry, and the only thing that cascades a family's
|
|
43
|
+
// internal pins
|
|
44
|
+
resolve = () => runYarn(["install"], { cwd: projectDir }).status,
|
|
45
|
+
// the result has to be what CI would install from the manifests alone
|
|
46
|
+
verifyFrozen = () => runYarn(["install", "--immutable"], { cwd: projectDir }).status, readFixes = defaultReadFixes, readDuplicates = readDuplicateSnapshot, filter, packageManagerResiduals, color = shouldColorize(), }) => {
|
|
47
|
+
const packageFilter = createPackageFilter(filter);
|
|
48
|
+
const readSelectedFixes = (dir) => selectClusterFixes(readFixes(dir), packageFilter);
|
|
49
|
+
const lockPath = lockPathOf(projectDir);
|
|
50
|
+
const rootManifestPath = join(projectDir, "package.json");
|
|
51
|
+
const before = readDuplicates(lockPath);
|
|
52
|
+
const unchanged = (status, plannedChangeCount = 0) => ({
|
|
53
|
+
status,
|
|
54
|
+
before,
|
|
55
|
+
after: before,
|
|
56
|
+
stickyOverrides: [],
|
|
57
|
+
plannedChangeCount,
|
|
58
|
+
});
|
|
59
|
+
const { selected: fixes, skipped: filteredOut } = readSelectedFixes(projectDir);
|
|
60
|
+
const plan = planClusterApply(fixes);
|
|
61
|
+
// a yarn resolution applies to every requester of the package, so one a
|
|
62
|
+
// third-party range rejects would force that dependent too
|
|
63
|
+
const { safe: plannedOverrides, rejected } = partitionUnconditionalOverrides(fixes, plan.overrides);
|
|
64
|
+
const skipped = [
|
|
65
|
+
...filteredOut.map(describeSkippedClusterFix),
|
|
66
|
+
...plan.unresolvableChanges.map((unresolvable) => `${unresolvable}: no workspace file recorded for it`),
|
|
67
|
+
...plan.conflicts.map((conflict) => `${conflict.packageName}: keeping ${conflict.kept}, ignoring ${conflict.dropped} asked by another cluster`),
|
|
68
|
+
...rejected.flatMap(({ override, rejectedBy }) => rejectedBy.map((constraint) => `resolution ${describeOverride(override)}: ${constraint.requesterName ?? "workspace"} requires "${constraint.range}", and a yarn resolution would force it too`)),
|
|
69
|
+
];
|
|
70
|
+
const changeCount = plan.manifestEdits.length + plannedOverrides.length;
|
|
71
|
+
const relativeManifestPath = (importerPath) => relative(projectDir, manifestPathOf(projectDir, importerPath));
|
|
72
|
+
const planFileChanges = () => [
|
|
73
|
+
...[
|
|
74
|
+
...new Set(plan.manifestEdits.map((edit) => relativeManifestPath(edit.importerPath))),
|
|
75
|
+
].map((path) => ({
|
|
76
|
+
path,
|
|
77
|
+
changes: plan.manifestEdits
|
|
78
|
+
.filter((edit) => relativeManifestPath(edit.importerPath) === path)
|
|
79
|
+
.map((edit) => `"${edit.packageName}": "${edit.range}" -> "${edit.to}" (${edit.depType})`),
|
|
80
|
+
})),
|
|
81
|
+
{
|
|
82
|
+
path: `${relative(projectDir, rootManifestPath)} resolutions`,
|
|
83
|
+
transient: "removed once the result is verified",
|
|
84
|
+
changes: plannedOverrides.map((override) => `${describeOverride(override)} (${override.reason})`),
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
// A dry run prints the plan through the shared renderer and stops.
|
|
88
|
+
const reportPlan = () => {
|
|
89
|
+
renderApplyPlan({
|
|
90
|
+
fileChanges: changeCount === 0 ? [] : planFileChanges(),
|
|
91
|
+
skipped,
|
|
92
|
+
packageManagerResiduals,
|
|
93
|
+
dedupeCommand: "yarn-berry-deduplicate",
|
|
94
|
+
log,
|
|
95
|
+
color,
|
|
96
|
+
});
|
|
97
|
+
return unchanged("dry-run", changeCount);
|
|
98
|
+
};
|
|
99
|
+
if (!dryRun) {
|
|
100
|
+
for (const entry of skipped) {
|
|
101
|
+
log(` Skipped ${entry}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (changeCount === 0) {
|
|
105
|
+
return dryRun ? reportPlan() : unchanged("nothing-to-do");
|
|
106
|
+
}
|
|
107
|
+
if (dryRun) {
|
|
108
|
+
return reportPlan();
|
|
109
|
+
}
|
|
110
|
+
const touchedPaths = [
|
|
111
|
+
...new Set([
|
|
112
|
+
...plan.manifestEdits.map((edit) => manifestPathOf(projectDir, edit.importerPath)),
|
|
113
|
+
rootManifestPath,
|
|
114
|
+
]),
|
|
115
|
+
lockPath,
|
|
116
|
+
];
|
|
117
|
+
const originalSnapshot = captureFiles(touchedPaths);
|
|
118
|
+
const revertTo = (snapshot) => {
|
|
119
|
+
restoreFiles(snapshot);
|
|
120
|
+
resolve();
|
|
121
|
+
};
|
|
122
|
+
const editManifests = (edits) => edits.every((edit) => {
|
|
123
|
+
const path = manifestPathOf(projectDir, edit.importerPath);
|
|
124
|
+
const updated = applyWorkspaceRangeEdit(readFileSync(path, "utf8"), edit);
|
|
125
|
+
if (updated === undefined) {
|
|
126
|
+
log(` ${path} no longer declares "${edit.packageName}": "${edit.range}" — the lockfile is out of date`);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
log(` ${path}: "${edit.packageName}" ${edit.range} -> ${edit.to} in ${edit.depType}`);
|
|
130
|
+
writeFileSync(path, updated);
|
|
131
|
+
return true;
|
|
132
|
+
});
|
|
133
|
+
// A reuse fix removes no duplicate — both copies keep their dependents — so
|
|
134
|
+
// the duplicate set cannot tell whether it took. The detector can: the fix is
|
|
135
|
+
// gone from its output once the edge points at the anchored version.
|
|
136
|
+
const readState = () => ({
|
|
137
|
+
duplicates: readDuplicates(lockPath),
|
|
138
|
+
reuses: reuseKeys(readSelectedFixes(projectDir).selected),
|
|
139
|
+
});
|
|
140
|
+
// A step keeps its edits as long as it broke nothing: a widened range often
|
|
141
|
+
// deduplicates nothing on its own and only makes the resolutions applicable.
|
|
142
|
+
const resolveAndCheck = (label) => {
|
|
143
|
+
if (resolve() !== 0) {
|
|
144
|
+
log(` \`yarn install\` failed after ${label} — reverting`);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
const state = readState();
|
|
148
|
+
const { added } = diffDuplicates(before, state.duplicates);
|
|
149
|
+
if (added.length > 0) {
|
|
150
|
+
log(` ${label} introduced ${added.length} new duplicate(s) — reverting`);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return state;
|
|
154
|
+
};
|
|
155
|
+
if (plan.manifestEdits.length > 0) {
|
|
156
|
+
log("Editing workspace ranges:");
|
|
157
|
+
if (!editManifests(plan.manifestEdits)) {
|
|
158
|
+
revertTo(originalSnapshot);
|
|
159
|
+
return unchanged("reverted", changeCount);
|
|
160
|
+
}
|
|
161
|
+
if (resolveAndCheck("the workspace range edits") === null) {
|
|
162
|
+
revertTo(originalSnapshot);
|
|
163
|
+
return unchanged("reverted", changeCount);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const withoutOverridesSnapshot = captureFiles(touchedPaths);
|
|
167
|
+
const rootManifestBefore = withoutOverridesSnapshot.find((snapshot) => snapshot.path === rootManifestPath);
|
|
168
|
+
const remaining = readState();
|
|
169
|
+
// A resolution is still worth writing while its package is duplicated, or
|
|
170
|
+
// while the edge it repoints is still resolving elsewhere.
|
|
171
|
+
const outstanding = plannedOverrides.filter((override) => [...remaining.duplicates].some((resolution) => resolution.startsWith(`${override.packageName}@`)) ||
|
|
172
|
+
[...remaining.reuses].some((key) => key.endsWith(`>${override.packageName}@${override.version}`)));
|
|
173
|
+
// The result is only a fix if CI can install it from the manifests as they
|
|
174
|
+
// stand, resolutions removed and all.
|
|
175
|
+
const frozenFailure = () => {
|
|
176
|
+
if (verifyFrozen() === 0)
|
|
177
|
+
return null;
|
|
178
|
+
log(" `yarn install --immutable` rejects the result — reverting, the lockfile it produced is not one CI can reuse");
|
|
179
|
+
revertTo(withoutOverridesSnapshot);
|
|
180
|
+
return {
|
|
181
|
+
status: "reverted",
|
|
182
|
+
before,
|
|
183
|
+
after: readDuplicates(lockPath),
|
|
184
|
+
stickyOverrides: [],
|
|
185
|
+
plannedChangeCount: changeCount,
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
if (outstanding.length === 0) {
|
|
189
|
+
return (frozenFailure() ?? {
|
|
190
|
+
status: "applied",
|
|
191
|
+
before,
|
|
192
|
+
after: remaining.duplicates,
|
|
193
|
+
stickyOverrides: [],
|
|
194
|
+
plannedChangeCount: changeCount,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
log(`Adding resolutions to ${rootManifestPath}:`);
|
|
198
|
+
for (const override of outstanding) {
|
|
199
|
+
log(` ${describeOverride(override)} (${override.reason})`);
|
|
200
|
+
const aliased = aliasOnlyRequesters(fixes, override.packageName);
|
|
201
|
+
if (aliased.length > 0) {
|
|
202
|
+
log(` every requester of ${override.packageName} declares it through an alias (${aliased.join(", ")}); a yarn resolution repoints the target, not those keys`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
writeFileSync(rootManifestPath, addResolutions(rootManifestBefore.content ?? "{}", new Map(outstanding.map((override) => [override.packageName, override.version]))));
|
|
206
|
+
const withOverrides = resolveAndCheck("the resolutions");
|
|
207
|
+
if (withOverrides === null) {
|
|
208
|
+
revertTo(withoutOverridesSnapshot);
|
|
209
|
+
return unchanged("reverted", changeCount);
|
|
210
|
+
}
|
|
211
|
+
// The resolutions are scaffolding: yarn has to hold the deduplicated result
|
|
212
|
+
// on its own, or the fix is not one we can ship.
|
|
213
|
+
log("Removing the resolutions and re-resolving to check the result holds:");
|
|
214
|
+
restoreFiles([rootManifestBefore]);
|
|
215
|
+
if (resolve() !== 0) {
|
|
216
|
+
log(" `yarn install` failed without the resolutions — reverting");
|
|
217
|
+
revertTo(withoutOverridesSnapshot);
|
|
218
|
+
return unchanged("reverted", changeCount);
|
|
219
|
+
}
|
|
220
|
+
const after = readState();
|
|
221
|
+
const returnedDuplicates = diffDuplicates(withOverrides.duplicates, after.duplicates).added;
|
|
222
|
+
const returnedReuses = [...after.reuses].filter((key) => !withOverrides.reuses.has(key));
|
|
223
|
+
if (returnedDuplicates.length > 0 || returnedReuses.length > 0) {
|
|
224
|
+
log(" The resolutions were the only thing holding the result: yarn resolves back without them. A fix that needs a standing resolution is not one this tool applies.");
|
|
225
|
+
log(` Please report this cluster at ${issuesUrl}:`);
|
|
226
|
+
for (const override of outstanding) {
|
|
227
|
+
log(` ${describeOverride(override)}`);
|
|
228
|
+
}
|
|
229
|
+
revertTo(withoutOverridesSnapshot);
|
|
230
|
+
return {
|
|
231
|
+
status: "reverted",
|
|
232
|
+
before,
|
|
233
|
+
after: readDuplicates(lockPath),
|
|
234
|
+
stickyOverrides: outstanding,
|
|
235
|
+
plannedChangeCount: changeCount,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return (frozenFailure() ?? {
|
|
239
|
+
status: "applied",
|
|
240
|
+
before,
|
|
241
|
+
after: after.duplicates,
|
|
242
|
+
stickyOverrides: [],
|
|
243
|
+
plannedChangeCount: changeCount,
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
//# sourceMappingURL=applyClusterFixes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyClusterFixes.js","sourceRoot":"","sources":["../src/applyClusterFixes.ts"],"names":[],"mappings":"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"}
|