fix(core): update yarn-parser to handle yarn v4 syntax (#29067)

Update the yarn-parser so that yarn.lock file generation works with yarn
v4

## Current Behavior
yarn.lock is not correctly created when using yarn v4

```
"":
  version: 1.22.8
  resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin<compat/resolve>::version=1.22.8&hash=c3c19d"
  dependencies:
    is-core-module: "npm:^2.13.0"
    path-parse: "npm:^1.0.7"
    supports-preserve-symlinks-flag: "npm:^1.0.0"
  bin:
    resolve: bin/resolve
  checksum: 0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729
  languageName: node
  linkType: hard
```


## Expected Behavior
yarn.lock should be created correctly with no missing keys


## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #19881
This commit is contained in:
Zach Tindall 2024-12-19 23:07:06 -05:00 committed by GitHub
parent 09800062e7
commit efa5ba2bb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 127 additions and 1 deletions

View File

@ -2678,6 +2678,131 @@ __metadata:
"
`);
});
it('should keep the builtin patch for yarn 4 patch syntax', () => {
const lockFile = `# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
__metadata:
version: 6
cacheKey: 8
"resolve@npm:1.22.8, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:^1.9.0":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A1.22.8#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.12.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.9.0#optional!builtin<compat/resolve>":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin<compat/resolve>::version=1.22.8&hash=c3c19d"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a
languageName: node
linkType: hard
`;
const packageJson: PackageJson = {
name: '@my-ns/example',
version: '0.0.1',
type: 'commonjs',
dependencies: {
resolve: '^1.12.0',
},
};
const hash = uniq('mock-hash');
const externalNodes = getYarnLockfileNodes(lockFile, hash, packageJson);
const pg = {
nodes: {},
dependencies: {},
externalNodes,
};
const ctx: CreateDependenciesContext = {
projects: {},
externalNodes,
fileMap: {
nonProjectFiles: [],
projectFileMap: {},
},
filesToProcess: {
nonProjectFiles: [],
projectFileMap: {},
},
nxJsonConfiguration: null,
workspaceRoot: '/virtual',
};
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
const builder = new ProjectGraphBuilder(pg);
for (const dep of dependencies) {
builder.addDependency(
dep.source,
dep.target,
dep.type,
'sourceFile' in dep ? dep.sourceFile : null
);
}
const graph = builder.getUpdatedProjectGraph();
const prunedGraph = pruneProjectGraph(graph, packageJson);
const result = stringifyYarnLockfile(prunedGraph, lockFile, packageJson);
expect(result).toMatchInlineSnapshot(`
"# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
__metadata:
version: 6
cacheKey: 8
"@my-ns/example@workspace:.":
version: 0.0.0-use.local
resolution: "@my-ns/example@workspace:."
dependencies:
resolve: ^1.12.0
languageName: unknown
linkType: soft
"resolve@npm:^1.12.0":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A^1.12.0#optional!builtin<compat/resolve>":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin<compat/resolve>::version=1.22.8&hash=c3c19d"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a
languageName: node
linkType: hard
"
`);
});
});
});

View File

@ -474,9 +474,10 @@ function mapSnapshots(
const packageName = key.slice(0, key.indexOf('@', 1));
let normalizedKey = key;
if (isBerry && key.includes('@patch:') && key.includes('#')) {
const regEx = new RegExp(`@patch:${packageName}@(npm%3A)?(.*)$`);
normalizedKey = key
.slice(0, key.indexOf('#'))
.replace(`@patch:${packageName}@`, '@npm:');
.replace(regEx, '@npm:$2');
}
if (
!existingKeys.get(packageName) ||