@backstage/cli-module-package-manager-yarn 0.1.1-next.0
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/CHANGELOG.md +11 -0
- package/README.md +48 -0
- package/bin/backstage-cli-module-package-manager-yarn +32 -0
- package/dist/commands/pm/verifyPatches.cjs.js +39 -0
- package/dist/commands/pm/verifyPatches.cjs.js.map +1 -0
- package/dist/index.cjs.js +22 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/lib/verifyYarnPatches.cjs.js +842 -0
- package/dist/lib/verifyYarnPatches.cjs.js.map +1 -0
- package/dist/package.json.cjs.js +86 -0
- package/dist/package.json.cjs.js.map +1 -0
- package/package.json +56 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @backstage/cli-module-package-manager-yarn
|
|
2
|
+
|
|
3
|
+
## 0.1.1-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- de957f6: Added `@backstage/cli-module-package-manager-yarn` with `backstage-cli pm
|
|
8
|
+
verify-patches` to validate Yarn patch references, local patch files,
|
|
9
|
+
lockfile consistency, and patched Backstage package versions against the
|
|
10
|
+
selected Backstage release. The command is included in
|
|
11
|
+
`@backstage/cli-defaults`.
|
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @backstage/cli-module-package-manager-yarn
|
|
2
|
+
|
|
3
|
+
Adds `backstage-cli pm verify-patches`, a read-only check for Yarn patch
|
|
4
|
+
references and patched Backstage package versions.
|
|
5
|
+
|
|
6
|
+
The command verifies Yarn's native `patch:` protocol, available in Yarn 2 and
|
|
7
|
+
later. It does not inspect patches managed by tools such as `patch-package` in
|
|
8
|
+
Yarn Classic repositories.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
Run the command from a Yarn repository root:
|
|
13
|
+
|
|
14
|
+
```shell
|
|
15
|
+
yarn backstage-cli pm verify-patches
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The command scans the root `package.json` and every workspace manifest for
|
|
19
|
+
`patch:` references in `resolutions`, `dependencies`, `devDependencies`,
|
|
20
|
+
`optionalDependencies`, and `peerDependencies`. It verifies that referenced
|
|
21
|
+
local patch files exist, files in Yarn's configured `patchFolder` are
|
|
22
|
+
referenced, and manifest declarations agree with `yarn.lock`.
|
|
23
|
+
|
|
24
|
+
When a repository both patches an `@backstage/*` package and declares a
|
|
25
|
+
Backstage release in `backstage.json`, the command also verifies that the
|
|
26
|
+
patched package version matches the selected release manifest. All findings
|
|
27
|
+
are printed together and the command exits unsuccessfully if any are found.
|
|
28
|
+
Repositories without `backstage.json` still receive generic patch validation;
|
|
29
|
+
the Backstage release check is reported as skipped.
|
|
30
|
+
|
|
31
|
+
The command does not run Yarn, install dependencies, or write project files.
|
|
32
|
+
Use it alongside `yarn install --immutable`: immutable installs protect the
|
|
33
|
+
resolved dependency state, while this command verifies that patch declarations,
|
|
34
|
+
patch files, the lockfile, and the selected Backstage release remain aligned.
|
|
35
|
+
|
|
36
|
+
## Release manifest environment
|
|
37
|
+
|
|
38
|
+
For patched Backstage packages, the command loads the manifest for the release
|
|
39
|
+
selected in `backstage.json`. It supports the same manifest environment
|
|
40
|
+
variables as other Backstage version tooling:
|
|
41
|
+
|
|
42
|
+
- `BACKSTAGE_MANIFEST_FILE` — path to a local release manifest, useful for
|
|
43
|
+
offline or mirrored environments.
|
|
44
|
+
- `BACKSTAGE_VERSIONS_BASE_URL` — base URL from which to fetch release
|
|
45
|
+
manifests when a local manifest is not supplied.
|
|
46
|
+
|
|
47
|
+
If manifest validation is required but the selected manifest cannot be loaded
|
|
48
|
+
or does not match the selected release, verification fails.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026 The Backstage Authors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
|
|
20
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
21
|
+
const isLocal = require('node:fs').existsSync(
|
|
22
|
+
path.resolve(__dirname, '../src'),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (isLocal) {
|
|
26
|
+
require('@backstage/cli-node/config/nodeTransform.cjs');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { runCli } = require('@backstage/cli-node');
|
|
30
|
+
const cliModule = require(isLocal ? '../src/index' : '..').default;
|
|
31
|
+
const pkg = require('../package.json');
|
|
32
|
+
runCli({ modules: [cliModule], name: pkg.name, version: pkg.version });
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cliCommon = require('@backstage/cli-common');
|
|
6
|
+
var cleye = require('cleye');
|
|
7
|
+
var verifyYarnPatches = require('../../lib/verifyYarnPatches.cjs.js');
|
|
8
|
+
|
|
9
|
+
function formatPatchReferenceCount(patchCount) {
|
|
10
|
+
return `${patchCount} patch reference${patchCount === 1 ? "" : "s"}`;
|
|
11
|
+
}
|
|
12
|
+
function formatError(error) {
|
|
13
|
+
const location = error.location ? `${error.location} ` : "";
|
|
14
|
+
return ` ${location}[${error.kind}]: ${error.message}
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
var verifyPatches = async ({ args, info }) => {
|
|
18
|
+
cleye.cli({ name: info.usage }, void 0, args);
|
|
19
|
+
const result = await verifyYarnPatches.verifyYarnPatches({
|
|
20
|
+
rootDir: cliCommon.targetPaths.dir,
|
|
21
|
+
env: process.env
|
|
22
|
+
});
|
|
23
|
+
if (result.errors.length > 0) {
|
|
24
|
+
process.stderr.write("Yarn patch verification failed:\n");
|
|
25
|
+
for (const error of result.errors) {
|
|
26
|
+
process.stderr.write(formatError(error));
|
|
27
|
+
}
|
|
28
|
+
throw new Error("Yarn patch verification failed");
|
|
29
|
+
}
|
|
30
|
+
const patchSummary = result.patchCount === 0 ? "no patch references found" : `${formatPatchReferenceCount(result.patchCount)} verified`;
|
|
31
|
+
const backstageSummary = result.backstageCheck === "verified" ? "Backstage release validation passed" : "Backstage release validation was skipped";
|
|
32
|
+
process.stdout.write(
|
|
33
|
+
`Yarn patch verification passed: ${patchSummary}. ${backstageSummary}.
|
|
34
|
+
`
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.default = verifyPatches;
|
|
39
|
+
//# sourceMappingURL=verifyPatches.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyPatches.cjs.js","sources":["../../../src/commands/pm/verifyPatches.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { targetPaths } from '@backstage/cli-common';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { cli } from 'cleye';\nimport {\n verifyYarnPatches,\n type PatchVerificationError,\n} from '../../lib/verifyYarnPatches';\n\nfunction formatPatchReferenceCount(patchCount: number): string {\n return `${patchCount} patch reference${patchCount === 1 ? '' : 's'}`;\n}\n\nfunction formatError(error: PatchVerificationError): string {\n const location = error.location ? `${error.location} ` : '';\n return ` ${location}[${error.kind}]: ${error.message}\\n`;\n}\n\nexport default async ({ args, info }: CliCommandContext) => {\n cli({ name: info.usage }, undefined, args);\n\n const result = await verifyYarnPatches({\n rootDir: targetPaths.dir,\n env: process.env,\n });\n\n if (result.errors.length > 0) {\n process.stderr.write('Yarn patch verification failed:\\n');\n for (const error of result.errors) {\n process.stderr.write(formatError(error));\n }\n throw new Error('Yarn patch verification failed');\n }\n\n const patchSummary =\n result.patchCount === 0\n ? 'no patch references found'\n : `${formatPatchReferenceCount(result.patchCount)} verified`;\n const backstageSummary =\n result.backstageCheck === 'verified'\n ? 'Backstage release validation passed'\n : 'Backstage release validation was skipped';\n process.stdout.write(\n `Yarn patch verification passed: ${patchSummary}. ${backstageSummary}.\\n`,\n );\n};\n"],"names":["cli","verifyYarnPatches","targetPaths"],"mappings":";;;;;;;;AAwBA,SAAS,0BAA0B,UAAA,EAA4B;AAC7D,EAAA,OAAO,GAAG,UAAU,CAAA,gBAAA,EAAmB,UAAA,KAAe,CAAA,GAAI,KAAK,GAAG,CAAA,CAAA;AACpE;AAEA,SAAS,YAAY,KAAA,EAAuC;AAC1D,EAAA,MAAM,WAAW,KAAA,CAAM,QAAA,GAAW,CAAA,EAAG,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAA,GAAM,EAAA;AACzD,EAAA,OAAO,KAAK,QAAQ,CAAA,CAAA,EAAI,MAAM,IAAI,CAAA,GAAA,EAAM,MAAM,OAAO;AAAA,CAAA;AACvD;AAEA,oBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAAA,SAAA,CAAI,EAAE,IAAA,EAAM,IAAA,CAAK,KAAA,EAAM,EAAG,QAAW,IAAI,CAAA;AAEzC,EAAA,MAAM,MAAA,GAAS,MAAMC,mCAAA,CAAkB;AAAA,IACrC,SAASC,qBAAA,CAAY,GAAA;AAAA,IACrB,KAAK,OAAA,CAAQ;AAAA,GACd,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,mCAAmC,CAAA;AACxD,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,WAAA,CAAY,KAAK,CAAC,CAAA;AAAA,IACzC;AACA,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,YAAA,GACJ,OAAO,UAAA,KAAe,CAAA,GAClB,8BACA,CAAA,EAAG,yBAAA,CAA0B,MAAA,CAAO,UAAU,CAAC,CAAA,SAAA,CAAA;AACrD,EAAA,MAAM,gBAAA,GACJ,MAAA,CAAO,cAAA,KAAmB,UAAA,GACtB,qCAAA,GACA,0CAAA;AACN,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,IACb,CAAA,gCAAA,EAAmC,YAAY,CAAA,EAAA,EAAK,gBAAgB,CAAA;AAAA;AAAA,GACtE;AACF,CAAA;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cliNode = require('@backstage/cli-node');
|
|
6
|
+
var _package = require('./package.json.cjs.js');
|
|
7
|
+
|
|
8
|
+
var index = cliNode.createCliModule({
|
|
9
|
+
packageJson: _package.default,
|
|
10
|
+
init: async (reg) => {
|
|
11
|
+
reg.addCommand({
|
|
12
|
+
path: ["pm", "verify-patches"],
|
|
13
|
+
description: "Verify Yarn patch references and Backstage package versions",
|
|
14
|
+
execute: {
|
|
15
|
+
loader: () => import('./commands/pm/verifyPatches.cjs.js')
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
exports.default = index;
|
|
22
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/index.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * CLI module for Yarn package manager commands in the Backstage CLI.\n *\n * @packageDocumentation\n */\n\nimport { createCliModule } from '@backstage/cli-node';\nimport packageJson from '../package.json';\n\nexport default createCliModule({\n packageJson,\n init: async reg => {\n reg.addCommand({\n path: ['pm', 'verify-patches'],\n description:\n 'Verify Yarn patch references and Backstage package versions',\n execute: {\n loader: () => import('./commands/pm/verifyPatches'),\n },\n });\n },\n});\n"],"names":["createCliModule","packageJson"],"mappings":";;;;;;;AAwBA,YAAeA,uBAAA,CAAgB;AAAA,eAC7BC,gBAAA;AAAA,EACA,IAAA,EAAM,OAAM,GAAA,KAAO;AACjB,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,IAAA,EAAM,gBAAgB,CAAA;AAAA,MAC7B,WAAA,EACE,6DAAA;AAAA,MACF,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,MAAM,OAAO,oCAA6B;AAAA;AACpD,KACD,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as _backstage_cli_node from '@backstage/cli-node';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI module for Yarn package manager commands in the Backstage CLI.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: _backstage_cli_node.CliModule;
|
|
9
|
+
|
|
10
|
+
export { _default as default };
|
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var releaseManifests = require('@backstage/release-manifests');
|
|
4
|
+
var core = require('@yarnpkg/core');
|
|
5
|
+
var fslib = require('@yarnpkg/fslib');
|
|
6
|
+
var parsers = require('@yarnpkg/parsers');
|
|
7
|
+
var patchPlugin = require('@yarnpkg/plugin-patch');
|
|
8
|
+
var fs = require('node:fs/promises');
|
|
9
|
+
var path = require('node:path');
|
|
10
|
+
|
|
11
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var patchPlugin__default = /*#__PURE__*/_interopDefaultCompat(patchPlugin);
|
|
14
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
15
|
+
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
16
|
+
|
|
17
|
+
const MANIFEST_FIELDS = [
|
|
18
|
+
"resolutions",
|
|
19
|
+
"dependencies",
|
|
20
|
+
"devDependencies",
|
|
21
|
+
"peerDependencies",
|
|
22
|
+
"optionalDependencies"
|
|
23
|
+
];
|
|
24
|
+
const PATCH_PLUGIN_CONFIGURATION = {
|
|
25
|
+
modules: /* @__PURE__ */ new Map([["@yarnpkg/plugin-patch", patchPlugin__default.default]]),
|
|
26
|
+
plugins: /* @__PURE__ */ new Set(["@yarnpkg/plugin-patch"])
|
|
27
|
+
};
|
|
28
|
+
let configurationEnvironmentQueue = Promise.resolve();
|
|
29
|
+
function relativePath(rootDir, targetPath) {
|
|
30
|
+
return path__default.default.relative(rootDir, targetPath).split(path__default.default.sep).join("/");
|
|
31
|
+
}
|
|
32
|
+
function compareStrings(left, right) {
|
|
33
|
+
if (left < right) {
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
if (left > right) {
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
function sortErrors(errors) {
|
|
42
|
+
return errors.sort((left, right) => {
|
|
43
|
+
return compareStrings(left.location ?? "", right.location ?? "") || compareStrings(left.kind, right.kind) || compareStrings(left.message, right.message);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function isErrorWithCode(error, code) {
|
|
47
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
48
|
+
}
|
|
49
|
+
function getPatchPathWithoutFlags(patchPath) {
|
|
50
|
+
if (patchPath.startsWith("~builtin<")) {
|
|
51
|
+
return patchPath.slice(1);
|
|
52
|
+
}
|
|
53
|
+
const flagIndex = patchPath.lastIndexOf("!");
|
|
54
|
+
return flagIndex === -1 ? patchPath : patchPath.slice(flagIndex + 1);
|
|
55
|
+
}
|
|
56
|
+
function isBuiltinPatchPath(patchPath) {
|
|
57
|
+
const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);
|
|
58
|
+
return pathWithoutFlags.startsWith("builtin<") && pathWithoutFlags.endsWith(">");
|
|
59
|
+
}
|
|
60
|
+
function getPatchParent(rootDir, fallbackDir, locatorValue) {
|
|
61
|
+
if (typeof locatorValue !== "string") {
|
|
62
|
+
return { directory: fallbackDir };
|
|
63
|
+
}
|
|
64
|
+
const parentLocator = core.structUtils.parseLocator(locatorValue, true);
|
|
65
|
+
const locator = core.structUtils.stringifyLocator(parentLocator);
|
|
66
|
+
const parentRange = core.structUtils.parseRange(parentLocator.reference);
|
|
67
|
+
if (parentRange.protocol !== "workspace:") {
|
|
68
|
+
return { locator };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
directory: path__default.default.resolve(rootDir, parentRange.selector),
|
|
72
|
+
locator
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function resolvePatchPath(rootDir, parentDir, patchPath) {
|
|
76
|
+
const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);
|
|
77
|
+
if (isBuiltinPatchPath(pathWithoutFlags)) {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
const portablePatchPath = fslib.npath.toPortablePath(pathWithoutFlags);
|
|
81
|
+
let absolute;
|
|
82
|
+
if (pathWithoutFlags.startsWith("~/")) {
|
|
83
|
+
absolute = path__default.default.resolve(rootDir, pathWithoutFlags.slice(2));
|
|
84
|
+
} else if (fslib.ppath.isAbsolute(portablePatchPath)) {
|
|
85
|
+
absolute = fslib.npath.fromPortablePath(portablePatchPath);
|
|
86
|
+
} else if (parentDir !== void 0) {
|
|
87
|
+
absolute = path__default.default.resolve(parentDir, pathWithoutFlags);
|
|
88
|
+
}
|
|
89
|
+
if (absolute === void 0) {
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
absolute,
|
|
94
|
+
relative: relativePath(rootDir, absolute)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function parsePatchDeclaration(options) {
|
|
98
|
+
const parsedRange = core.structUtils.parseRange(options.range, {
|
|
99
|
+
requireProtocol: "patch:",
|
|
100
|
+
requireSource: true
|
|
101
|
+
});
|
|
102
|
+
const sourceDescriptor = core.structUtils.parseDescriptor(
|
|
103
|
+
parsedRange.source,
|
|
104
|
+
true
|
|
105
|
+
);
|
|
106
|
+
const source = core.structUtils.stringifyDescriptor(sourceDescriptor);
|
|
107
|
+
const parent = getPatchParent(
|
|
108
|
+
options.rootDir,
|
|
109
|
+
options.parentDir,
|
|
110
|
+
parsedRange.params?.locator
|
|
111
|
+
);
|
|
112
|
+
const paths = [];
|
|
113
|
+
let hasDependencyOwnedPath = false;
|
|
114
|
+
let hasProjectRelativePath = false;
|
|
115
|
+
const patchPaths = parsedRange.selector === "" ? [] : parsedRange.selector.split("&");
|
|
116
|
+
const components = patchPaths.map((patchPath) => {
|
|
117
|
+
const flagIndex = patchPath.lastIndexOf("!");
|
|
118
|
+
const flags = flagIndex === -1 ? "" : patchPath.slice(0, flagIndex + 1);
|
|
119
|
+
const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);
|
|
120
|
+
if (isBuiltinPatchPath(patchPath)) {
|
|
121
|
+
return patchPath;
|
|
122
|
+
}
|
|
123
|
+
const localPath = resolvePatchPath(
|
|
124
|
+
options.rootDir,
|
|
125
|
+
parent.directory,
|
|
126
|
+
patchPath
|
|
127
|
+
);
|
|
128
|
+
if (localPath) {
|
|
129
|
+
paths.push(localPath);
|
|
130
|
+
if (!pathWithoutFlags.startsWith("~/") && !fslib.ppath.isAbsolute(fslib.npath.toPortablePath(pathWithoutFlags))) {
|
|
131
|
+
hasProjectRelativePath = true;
|
|
132
|
+
}
|
|
133
|
+
return `${flags}local<${localPath.absolute}>`;
|
|
134
|
+
}
|
|
135
|
+
hasDependencyOwnedPath = true;
|
|
136
|
+
return `${flags}relative<${pathWithoutFlags}>`;
|
|
137
|
+
});
|
|
138
|
+
if (components.length === 0) {
|
|
139
|
+
return void 0;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
patchedIdent: options.patchedIdent,
|
|
143
|
+
source,
|
|
144
|
+
components,
|
|
145
|
+
parentLocator: parent.locator ?? (hasProjectRelativePath ? options.parentLocator : void 0),
|
|
146
|
+
canMatchManifest: !hasDependencyOwnedPath,
|
|
147
|
+
projectOwned: paths.length > 0 || options.origin === "manifest" && !hasDependencyOwnedPath,
|
|
148
|
+
paths,
|
|
149
|
+
location: options.location
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function declarationKey(declaration) {
|
|
153
|
+
return `${declaration.parentLocator ?? ""}\0${declaration.patchedIdent}\0${declaration.source}\0${declaration.components.join("\0")}`;
|
|
154
|
+
}
|
|
155
|
+
function declarationDescription(declaration) {
|
|
156
|
+
return declaration.paths.map((patchPath) => patchPath.relative).join(", ");
|
|
157
|
+
}
|
|
158
|
+
function isRecord(value) {
|
|
159
|
+
return typeof value === "object" && value !== null;
|
|
160
|
+
}
|
|
161
|
+
function isYarnPluginsKey(key) {
|
|
162
|
+
return key.toLowerCase() === "yarn_plugins";
|
|
163
|
+
}
|
|
164
|
+
function setEnvironmentValue(key, value) {
|
|
165
|
+
if (value === void 0) {
|
|
166
|
+
delete process.env[key];
|
|
167
|
+
} else {
|
|
168
|
+
process.env[key] = value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function withConfigurationEnvironment(env, action) {
|
|
172
|
+
const waitForTurn = configurationEnvironmentQueue;
|
|
173
|
+
let releaseTurn = () => {
|
|
174
|
+
};
|
|
175
|
+
const turnComplete = new Promise((resolve) => {
|
|
176
|
+
releaseTurn = resolve;
|
|
177
|
+
});
|
|
178
|
+
configurationEnvironmentQueue = waitForTurn.then(() => turnComplete);
|
|
179
|
+
await waitForTurn;
|
|
180
|
+
const environmentState = /* @__PURE__ */ new Map();
|
|
181
|
+
try {
|
|
182
|
+
const targetEnvironment = env ? { ...env } : void 0;
|
|
183
|
+
if (targetEnvironment) {
|
|
184
|
+
for (const key of Object.keys(targetEnvironment)) {
|
|
185
|
+
if (isYarnPluginsKey(key)) {
|
|
186
|
+
delete targetEnvironment[key];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const keysToScope = new Set(
|
|
191
|
+
targetEnvironment ? [...Object.keys(process.env), ...Object.keys(env ?? {})] : Object.keys(process.env).filter(isYarnPluginsKey)
|
|
192
|
+
);
|
|
193
|
+
for (const key of keysToScope) {
|
|
194
|
+
const previous = process.env[key];
|
|
195
|
+
const applied = isYarnPluginsKey(key) ? void 0 : targetEnvironment?.[key];
|
|
196
|
+
environmentState.set(key, { previous, applied });
|
|
197
|
+
setEnvironmentValue(key, applied);
|
|
198
|
+
}
|
|
199
|
+
return await action();
|
|
200
|
+
} finally {
|
|
201
|
+
for (const [key, { previous, applied }] of environmentState) {
|
|
202
|
+
if (process.env[key] === applied) {
|
|
203
|
+
setEnvironmentValue(key, previous);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
releaseTurn();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function arraysEqual(left, right) {
|
|
210
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
211
|
+
}
|
|
212
|
+
function getNpmResolutionRange(range) {
|
|
213
|
+
if (range.protocol === "npm:" && core.semverUtils.validRange(range.selector) !== null) {
|
|
214
|
+
return range.selector;
|
|
215
|
+
}
|
|
216
|
+
const npmVersion = range.params?.npm;
|
|
217
|
+
if (range.protocol === "backstage:" && range.selector === "^" && typeof npmVersion === "string" && core.semverUtils.clean(npmVersion) !== null) {
|
|
218
|
+
return `^${npmVersion}`;
|
|
219
|
+
}
|
|
220
|
+
return void 0;
|
|
221
|
+
}
|
|
222
|
+
function normalizeNpmAliasSource(descriptor) {
|
|
223
|
+
const range = core.structUtils.parseRange(descriptor.range);
|
|
224
|
+
if (range.protocol !== "npm:") {
|
|
225
|
+
return descriptor;
|
|
226
|
+
}
|
|
227
|
+
const aliasTarget = core.structUtils.tryParseDescriptor(range.selector, true);
|
|
228
|
+
if (!aliasTarget) {
|
|
229
|
+
return descriptor;
|
|
230
|
+
}
|
|
231
|
+
const aliasTargetRange = core.structUtils.parseRange(aliasTarget.range);
|
|
232
|
+
return aliasTargetRange.protocol === null ? core.structUtils.makeDescriptor(aliasTarget, `npm:${aliasTarget.range}`) : aliasTarget;
|
|
233
|
+
}
|
|
234
|
+
function npmSourceAgrees(descriptorRange, locatorRange) {
|
|
235
|
+
if (locatorRange.protocol !== "npm:") {
|
|
236
|
+
return void 0;
|
|
237
|
+
}
|
|
238
|
+
const resolvedVersion = core.semverUtils.clean(locatorRange.selector);
|
|
239
|
+
if (resolvedVersion === null) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
const resolutionRange = getNpmResolutionRange(descriptorRange);
|
|
243
|
+
if (resolutionRange !== void 0) {
|
|
244
|
+
return core.semverUtils.satisfiesWithPrereleases(
|
|
245
|
+
resolvedVersion,
|
|
246
|
+
resolutionRange
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
return descriptorRange.protocol === "npm:" ? core.TAG_REGEXP.test(descriptorRange.selector) : void 0;
|
|
250
|
+
}
|
|
251
|
+
function nonNpmSourceAgrees(descriptorRange, locatorRange) {
|
|
252
|
+
if (descriptorRange.protocol !== locatorRange.protocol) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
if (descriptorRange.protocol === "workspace:") {
|
|
256
|
+
const selector = descriptorRange.selector;
|
|
257
|
+
if (selector === "*" || selector === "^" || selector === "~" || core.semverUtils.validRange(selector) !== null) {
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const descriptorIdentity = descriptorRange.source ?? descriptorRange.selector;
|
|
262
|
+
const locatorIdentity = locatorRange.source ?? locatorRange.selector;
|
|
263
|
+
if (descriptorIdentity !== locatorIdentity) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const descriptorParent = descriptorRange.params?.locator;
|
|
267
|
+
if (typeof descriptorParent === "string" && descriptorParent !== locatorRange.params?.locator) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
if (descriptorRange.source !== null && descriptorRange.selector.startsWith("commit=")) {
|
|
271
|
+
return descriptorRange.selector === locatorRange.selector;
|
|
272
|
+
}
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
function patchDescriptorAgreesWithLocator(options) {
|
|
276
|
+
if (!core.structUtils.areIdentsEqual(options.descriptor, options.locator)) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const descriptorRange = core.structUtils.parseRange(options.descriptor.range, {
|
|
280
|
+
requireProtocol: "patch:",
|
|
281
|
+
requireSource: true
|
|
282
|
+
});
|
|
283
|
+
const locatorRange = core.structUtils.parseRange(options.locator.reference, {
|
|
284
|
+
requireProtocol: "patch:",
|
|
285
|
+
requireSource: true
|
|
286
|
+
});
|
|
287
|
+
const sourceDescriptor = normalizeNpmAliasSource(
|
|
288
|
+
options.configuration.normalizeDependency(
|
|
289
|
+
core.structUtils.parseDescriptor(descriptorRange.source, true)
|
|
290
|
+
)
|
|
291
|
+
);
|
|
292
|
+
const sourceLocator = core.structUtils.parseLocator(locatorRange.source, true);
|
|
293
|
+
if (!core.structUtils.areIdentsEqual(sourceDescriptor, sourceLocator)) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
const descriptorSourceRange = core.structUtils.parseRange(sourceDescriptor.range);
|
|
297
|
+
const locatorSourceRange = core.structUtils.parseRange(sourceLocator.reference);
|
|
298
|
+
const npmAgreement = npmSourceAgrees(
|
|
299
|
+
descriptorSourceRange,
|
|
300
|
+
locatorSourceRange
|
|
301
|
+
);
|
|
302
|
+
if (npmAgreement === false || npmAgreement === void 0 && !nonNpmSourceAgrees(descriptorSourceRange, locatorSourceRange)) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
return options.descriptorDeclaration?.parentLocator === options.locatorDeclaration?.parentLocator && arraysEqual(
|
|
306
|
+
options.descriptorDeclaration?.components ?? [],
|
|
307
|
+
options.locatorDeclaration?.components ?? []
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
async function discoverManifestDeclarations(rootDir, configuration, errors) {
|
|
311
|
+
const project = new core.Project(fslib.npath.toPortablePath(rootDir), { configuration });
|
|
312
|
+
const pendingWorkspaces = [fslib.npath.toPortablePath(rootDir)];
|
|
313
|
+
const visitedWorkspaces = /* @__PURE__ */ new Set();
|
|
314
|
+
const declarations = [];
|
|
315
|
+
while (pendingWorkspaces.length > 0) {
|
|
316
|
+
const workspaceCwd = pendingWorkspaces.shift();
|
|
317
|
+
if (workspaceCwd === void 0 || visitedWorkspaces.has(workspaceCwd)) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
visitedWorkspaces.add(workspaceCwd);
|
|
321
|
+
const workspace = new core.Workspace(workspaceCwd, { project });
|
|
322
|
+
await workspace.setup();
|
|
323
|
+
pendingWorkspaces.push(...workspace.workspacesCwds);
|
|
324
|
+
const manifestDir = fslib.npath.fromPortablePath(workspace.cwd);
|
|
325
|
+
const manifestPath = relativePath(
|
|
326
|
+
rootDir,
|
|
327
|
+
path__default.default.join(manifestDir, "package.json")
|
|
328
|
+
);
|
|
329
|
+
const manifestJson = workspace.manifest.raw;
|
|
330
|
+
const parentLocator = core.structUtils.stringifyLocator(
|
|
331
|
+
workspace.anchoredLocator
|
|
332
|
+
);
|
|
333
|
+
for (const field of MANIFEST_FIELDS) {
|
|
334
|
+
const entries = manifestJson[field];
|
|
335
|
+
if (typeof entries !== "object" || entries === null) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
for (const [name, range] of Object.entries(entries)) {
|
|
339
|
+
if (typeof range !== "string" || !range.startsWith("patch:")) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
const location = `${manifestPath}#${field}.${name}`;
|
|
343
|
+
try {
|
|
344
|
+
const declaration = parsePatchDeclaration({
|
|
345
|
+
rootDir,
|
|
346
|
+
parentDir: manifestDir,
|
|
347
|
+
parentLocator,
|
|
348
|
+
patchedIdent: field === "resolutions" ? parsers.parseResolution(name).descriptor.fullName : core.structUtils.stringifyIdent(core.structUtils.parseIdent(name)),
|
|
349
|
+
range,
|
|
350
|
+
location,
|
|
351
|
+
origin: "manifest"
|
|
352
|
+
});
|
|
353
|
+
if (declaration) {
|
|
354
|
+
declarations.push(declaration);
|
|
355
|
+
}
|
|
356
|
+
} catch (error) {
|
|
357
|
+
errors.push({
|
|
358
|
+
kind: "malformed-patch-reference",
|
|
359
|
+
message: `Invalid patch reference for '${name}' in ${field}: ${String(
|
|
360
|
+
error
|
|
361
|
+
)}`,
|
|
362
|
+
location
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return declarations;
|
|
369
|
+
}
|
|
370
|
+
function discoverLockfileDeclarations(rootDir, configuration, lockfileContent, errors) {
|
|
371
|
+
let lockfileData;
|
|
372
|
+
try {
|
|
373
|
+
lockfileData = parsers.parseSyml(lockfileContent);
|
|
374
|
+
} catch (error) {
|
|
375
|
+
errors.push({
|
|
376
|
+
kind: "malformed-lockfile",
|
|
377
|
+
message: `Failed to parse yarn.lock: ${String(error)}`,
|
|
378
|
+
location: "yarn.lock"
|
|
379
|
+
});
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
const declarations = [];
|
|
383
|
+
for (const [key, lockfileEntry] of Object.entries(lockfileData)) {
|
|
384
|
+
if (key === "__metadata") {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const patchDescriptors = [];
|
|
388
|
+
for (const entry of key.split(", ")) {
|
|
389
|
+
try {
|
|
390
|
+
const descriptor = core.structUtils.parseDescriptor(entry, true);
|
|
391
|
+
if (!descriptor.range.startsWith("patch:")) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
const declaration = parsePatchDeclaration({
|
|
395
|
+
rootDir,
|
|
396
|
+
parentDir: rootDir,
|
|
397
|
+
patchedIdent: core.structUtils.stringifyIdent(descriptor),
|
|
398
|
+
range: descriptor.range,
|
|
399
|
+
location: "yarn.lock",
|
|
400
|
+
origin: "lockfile"
|
|
401
|
+
});
|
|
402
|
+
if (declaration?.canMatchManifest) {
|
|
403
|
+
declarations.push(declaration);
|
|
404
|
+
}
|
|
405
|
+
patchDescriptors.push({ descriptor, declaration });
|
|
406
|
+
} catch (error) {
|
|
407
|
+
errors.push({
|
|
408
|
+
kind: "malformed-lockfile",
|
|
409
|
+
message: `Invalid patch entry '${entry}' in yarn.lock: ${String(
|
|
410
|
+
error
|
|
411
|
+
)}`,
|
|
412
|
+
location: "yarn.lock"
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (patchDescriptors.length === 0) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
const resolution = isRecord(lockfileEntry) ? lockfileEntry.resolution : void 0;
|
|
420
|
+
if (typeof resolution !== "string") {
|
|
421
|
+
errors.push({
|
|
422
|
+
kind: "malformed-lockfile",
|
|
423
|
+
message: `Patch entry '${key}' is missing its resolution locator`,
|
|
424
|
+
location: "yarn.lock"
|
|
425
|
+
});
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
try {
|
|
429
|
+
const locator = core.structUtils.parseLocator(resolution, true);
|
|
430
|
+
if (!locator.reference.startsWith("patch:")) {
|
|
431
|
+
errors.push({
|
|
432
|
+
kind: "lockfile-mismatch",
|
|
433
|
+
message: `Patch entry '${key}' disagrees with its resolution locator '${resolution}'`,
|
|
434
|
+
location: "yarn.lock"
|
|
435
|
+
});
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
const locatorDeclaration = parsePatchDeclaration({
|
|
439
|
+
rootDir,
|
|
440
|
+
parentDir: rootDir,
|
|
441
|
+
patchedIdent: core.structUtils.stringifyIdent(locator),
|
|
442
|
+
range: locator.reference,
|
|
443
|
+
location: "yarn.lock",
|
|
444
|
+
origin: "lockfile"
|
|
445
|
+
});
|
|
446
|
+
const locatorRange = core.structUtils.parseRange(locator.reference, {
|
|
447
|
+
requireProtocol: "patch:",
|
|
448
|
+
requireSource: true
|
|
449
|
+
});
|
|
450
|
+
const resolvedSource = core.structUtils.stringifyLocator(
|
|
451
|
+
core.structUtils.parseLocator(locatorRange.source, true)
|
|
452
|
+
);
|
|
453
|
+
for (const { declaration } of patchDescriptors) {
|
|
454
|
+
if (declaration) {
|
|
455
|
+
declaration.resolvedSource = resolvedSource;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (patchDescriptors.some(
|
|
459
|
+
({ descriptor, declaration }) => !patchDescriptorAgreesWithLocator({
|
|
460
|
+
configuration,
|
|
461
|
+
descriptor,
|
|
462
|
+
descriptorDeclaration: declaration,
|
|
463
|
+
locator,
|
|
464
|
+
locatorDeclaration
|
|
465
|
+
})
|
|
466
|
+
)) {
|
|
467
|
+
errors.push({
|
|
468
|
+
kind: "lockfile-mismatch",
|
|
469
|
+
message: `Patch entry '${key}' disagrees with its resolution locator '${resolution}'`,
|
|
470
|
+
location: "yarn.lock"
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
} catch (error) {
|
|
474
|
+
errors.push({
|
|
475
|
+
kind: "malformed-lockfile",
|
|
476
|
+
message: `Patch entry '${key}' has an invalid resolution locator '${resolution}': ${String(
|
|
477
|
+
error
|
|
478
|
+
)}`,
|
|
479
|
+
location: "yarn.lock"
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return declarations;
|
|
484
|
+
}
|
|
485
|
+
async function readYarnConfiguration(rootDir, env) {
|
|
486
|
+
return withConfigurationEnvironment(env, async () => {
|
|
487
|
+
return core.Configuration.find(
|
|
488
|
+
fslib.npath.toPortablePath(rootDir),
|
|
489
|
+
PATCH_PLUGIN_CONFIGURATION,
|
|
490
|
+
{
|
|
491
|
+
strict: false,
|
|
492
|
+
useRc: false
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
async function findPatchFiles(directory, realpathAncestry = /* @__PURE__ */ new Set()) {
|
|
498
|
+
let realDirectory;
|
|
499
|
+
try {
|
|
500
|
+
realDirectory = await fs__default.default.realpath(directory);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
if (isErrorWithCode(error, "ENOENT")) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
throw error;
|
|
506
|
+
}
|
|
507
|
+
if (realpathAncestry.has(realDirectory)) {
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
const nextAncestry = new Set(realpathAncestry).add(realDirectory);
|
|
511
|
+
let entries;
|
|
512
|
+
try {
|
|
513
|
+
entries = await fs__default.default.readdir(directory, { withFileTypes: true });
|
|
514
|
+
} catch (error) {
|
|
515
|
+
if (isErrorWithCode(error, "ENOENT")) {
|
|
516
|
+
return [];
|
|
517
|
+
}
|
|
518
|
+
throw error;
|
|
519
|
+
}
|
|
520
|
+
const files = await Promise.all(
|
|
521
|
+
entries.map(async (entry) => {
|
|
522
|
+
const entryPath = path__default.default.join(directory, entry.name);
|
|
523
|
+
if (entry.isDirectory()) {
|
|
524
|
+
return findPatchFiles(entryPath, nextAncestry);
|
|
525
|
+
}
|
|
526
|
+
if (entry.isSymbolicLink()) {
|
|
527
|
+
try {
|
|
528
|
+
const targetStats = await fs__default.default.stat(entryPath);
|
|
529
|
+
if (targetStats.isDirectory()) {
|
|
530
|
+
return findPatchFiles(entryPath, nextAncestry);
|
|
531
|
+
}
|
|
532
|
+
} catch (error) {
|
|
533
|
+
if (!isErrorWithCode(error, "ENOENT")) {
|
|
534
|
+
throw error;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return [entryPath];
|
|
538
|
+
}
|
|
539
|
+
return entry.isFile() ? [entryPath] : [];
|
|
540
|
+
})
|
|
541
|
+
);
|
|
542
|
+
return files.flat().sort();
|
|
543
|
+
}
|
|
544
|
+
function uniqueDeclarations(declarations) {
|
|
545
|
+
const unique = /* @__PURE__ */ new Map();
|
|
546
|
+
for (const declaration of declarations) {
|
|
547
|
+
const key = declarationKey(declaration);
|
|
548
|
+
if (!unique.has(key)) {
|
|
549
|
+
unique.set(key, declaration);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return unique;
|
|
553
|
+
}
|
|
554
|
+
function getPatchedBackstagePackages(declarations) {
|
|
555
|
+
const packages = [];
|
|
556
|
+
for (const declaration of declarations) {
|
|
557
|
+
const declaredSource = normalizeNpmAliasSource(
|
|
558
|
+
core.structUtils.parseDescriptor(declaration.source, true)
|
|
559
|
+
);
|
|
560
|
+
const resolvedSource = declaration.resolvedSource;
|
|
561
|
+
const source = resolvedSource ? core.structUtils.parseLocator(resolvedSource, true) : declaredSource;
|
|
562
|
+
if (source.scope !== "backstage") {
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
const range = core.structUtils.parseRange(
|
|
566
|
+
"reference" in source ? source.reference : source.range
|
|
567
|
+
);
|
|
568
|
+
if (range.protocol !== "npm:" || core.semverUtils.clean(range.selector) === null) {
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
packages.push({
|
|
572
|
+
name: core.structUtils.stringifyIdent(source),
|
|
573
|
+
version: range.selector,
|
|
574
|
+
location: declaration.location
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
return packages;
|
|
578
|
+
}
|
|
579
|
+
function isReleaseManifest(value) {
|
|
580
|
+
return isRecord(value) && typeof value.releaseVersion === "string" && Array.isArray(value.packages) && value.packages.every(
|
|
581
|
+
(packageEntry) => isRecord(packageEntry) && typeof packageEntry.name === "string" && typeof packageEntry.version === "string"
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
async function readBackstageVersion(rootDir) {
|
|
585
|
+
try {
|
|
586
|
+
const backstageJson = JSON.parse(
|
|
587
|
+
await fs__default.default.readFile(path__default.default.join(rootDir, "backstage.json"), "utf8")
|
|
588
|
+
);
|
|
589
|
+
if (!isRecord(backstageJson) || typeof backstageJson.version !== "string") {
|
|
590
|
+
throw new Error(
|
|
591
|
+
"backstage.json must contain a string 'version' property"
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
return backstageJson.version;
|
|
595
|
+
} catch (error) {
|
|
596
|
+
if (isErrorWithCode(error, "ENOENT")) {
|
|
597
|
+
return void 0;
|
|
598
|
+
}
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
async function loadReleaseManifest(options) {
|
|
603
|
+
const manifestFile = options.env?.BACKSTAGE_MANIFEST_FILE;
|
|
604
|
+
const fetch = options.fetch ?? (async (url) => {
|
|
605
|
+
const manifest2 = await core.httpUtils.get(url, {
|
|
606
|
+
configuration: options.configuration,
|
|
607
|
+
jsonResponse: true
|
|
608
|
+
});
|
|
609
|
+
return {
|
|
610
|
+
status: 200,
|
|
611
|
+
url,
|
|
612
|
+
json: async () => manifest2
|
|
613
|
+
};
|
|
614
|
+
});
|
|
615
|
+
const manifest = manifestFile ? JSON.parse(await fs__default.default.readFile(manifestFile, "utf8")) : await releaseManifests.getManifestByVersion({
|
|
616
|
+
version: options.backstageVersion,
|
|
617
|
+
versionsBaseUrl: options.env?.BACKSTAGE_VERSIONS_BASE_URL,
|
|
618
|
+
fetch
|
|
619
|
+
});
|
|
620
|
+
if (!isReleaseManifest(manifest)) {
|
|
621
|
+
throw new Error("Backstage release manifest has an invalid format");
|
|
622
|
+
}
|
|
623
|
+
if (manifest.releaseVersion !== options.backstageVersion) {
|
|
624
|
+
throw new Error(
|
|
625
|
+
`Backstage release manifest version '${manifest.releaseVersion}' does not match selected version '${options.backstageVersion}'`
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
return manifest;
|
|
629
|
+
}
|
|
630
|
+
async function validateBackstagePatches(options) {
|
|
631
|
+
const patchedPackages = getPatchedBackstagePackages(options.declarations);
|
|
632
|
+
if (patchedPackages.length === 0) {
|
|
633
|
+
return { backstageCheck: "skipped", errors: [] };
|
|
634
|
+
}
|
|
635
|
+
let backstageVersion;
|
|
636
|
+
try {
|
|
637
|
+
backstageVersion = await readBackstageVersion(options.rootDir);
|
|
638
|
+
} catch (error) {
|
|
639
|
+
return {
|
|
640
|
+
backstageCheck: "verified",
|
|
641
|
+
errors: [
|
|
642
|
+
{
|
|
643
|
+
kind: "backstage-manifest-load-failure",
|
|
644
|
+
message: `Failed to read Backstage release version: ${String(error)}`,
|
|
645
|
+
location: "backstage.json"
|
|
646
|
+
}
|
|
647
|
+
]
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
if (backstageVersion === void 0) {
|
|
651
|
+
return { backstageCheck: "skipped", errors: [] };
|
|
652
|
+
}
|
|
653
|
+
let releaseManifest;
|
|
654
|
+
try {
|
|
655
|
+
releaseManifest = await loadReleaseManifest({
|
|
656
|
+
backstageVersion,
|
|
657
|
+
configuration: options.configuration,
|
|
658
|
+
env: options.env,
|
|
659
|
+
fetch: options.fetch
|
|
660
|
+
});
|
|
661
|
+
} catch (error) {
|
|
662
|
+
return {
|
|
663
|
+
backstageCheck: "verified",
|
|
664
|
+
errors: [
|
|
665
|
+
{
|
|
666
|
+
kind: "backstage-manifest-load-failure",
|
|
667
|
+
message: `Failed to load Backstage release manifest for '${backstageVersion}': ${String(
|
|
668
|
+
error
|
|
669
|
+
)}`,
|
|
670
|
+
location: "backstage.json"
|
|
671
|
+
}
|
|
672
|
+
]
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
const packageVersions = new Map(
|
|
676
|
+
releaseManifest.packages.map((packageEntry) => [
|
|
677
|
+
packageEntry.name,
|
|
678
|
+
packageEntry.version
|
|
679
|
+
])
|
|
680
|
+
);
|
|
681
|
+
const errors = [];
|
|
682
|
+
for (const patchedPackage of patchedPackages) {
|
|
683
|
+
const releaseVersion = packageVersions.get(patchedPackage.name);
|
|
684
|
+
if (releaseVersion === void 0) {
|
|
685
|
+
errors.push({
|
|
686
|
+
kind: "backstage-package-missing",
|
|
687
|
+
message: `Patched package '${patchedPackage.name}' is absent from Backstage release '${backstageVersion}'`,
|
|
688
|
+
location: patchedPackage.location
|
|
689
|
+
});
|
|
690
|
+
} else if (releaseVersion !== patchedPackage.version) {
|
|
691
|
+
errors.push({
|
|
692
|
+
kind: "backstage-patch-holdback",
|
|
693
|
+
message: `Patched package '${patchedPackage.name}' is at version '${patchedPackage.version}', but Backstage release '${backstageVersion}' requires version '${releaseVersion}'`,
|
|
694
|
+
location: patchedPackage.location
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return { backstageCheck: "verified", errors };
|
|
699
|
+
}
|
|
700
|
+
async function verifyYarnPatches(options) {
|
|
701
|
+
const rootDir = path__default.default.resolve(options.rootDir);
|
|
702
|
+
const errors = [];
|
|
703
|
+
const configuration = await readYarnConfiguration(rootDir, options.env);
|
|
704
|
+
const manifestDeclarations = await discoverManifestDeclarations(
|
|
705
|
+
rootDir,
|
|
706
|
+
configuration,
|
|
707
|
+
errors
|
|
708
|
+
);
|
|
709
|
+
const uniqueManifestDeclarations = uniqueDeclarations(manifestDeclarations);
|
|
710
|
+
const referencedPatchFiles = /* @__PURE__ */ new Map();
|
|
711
|
+
for (const declaration of uniqueManifestDeclarations.values()) {
|
|
712
|
+
for (const patchPath of declaration.paths) {
|
|
713
|
+
referencedPatchFiles.set(patchPath.absolute, patchPath);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
for (const [absolute, patchPath] of referencedPatchFiles) {
|
|
717
|
+
try {
|
|
718
|
+
const stats = await fs__default.default.stat(absolute);
|
|
719
|
+
if (!stats.isFile()) {
|
|
720
|
+
errors.push({
|
|
721
|
+
kind: "missing-patch-file",
|
|
722
|
+
message: `Patch path '${patchPath.relative}' is not a regular file`,
|
|
723
|
+
location: patchPath.relative
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
} catch (error) {
|
|
727
|
+
if (!isErrorWithCode(error, "ENOENT")) {
|
|
728
|
+
throw error;
|
|
729
|
+
}
|
|
730
|
+
errors.push({
|
|
731
|
+
kind: "missing-patch-file",
|
|
732
|
+
message: `Patch file '${patchPath.relative}' does not exist`,
|
|
733
|
+
location: patchPath.relative
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
const patchFolder = fslib.npath.fromPortablePath(configuration.get("patchFolder"));
|
|
738
|
+
const patchFiles = await findPatchFiles(patchFolder);
|
|
739
|
+
for (const patchFile of patchFiles) {
|
|
740
|
+
if (!referencedPatchFiles.has(patchFile)) {
|
|
741
|
+
const relative = relativePath(rootDir, patchFile);
|
|
742
|
+
errors.push({
|
|
743
|
+
kind: "orphaned-patch-file",
|
|
744
|
+
message: `Patch file '${relative}' is not referenced by any manifest`,
|
|
745
|
+
location: relative
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
let lockfileContent;
|
|
750
|
+
try {
|
|
751
|
+
lockfileContent = await fs__default.default.readFile(
|
|
752
|
+
path__default.default.join(rootDir, "yarn.lock"),
|
|
753
|
+
"utf8"
|
|
754
|
+
);
|
|
755
|
+
} catch (error) {
|
|
756
|
+
if (!isErrorWithCode(error, "ENOENT")) {
|
|
757
|
+
throw error;
|
|
758
|
+
}
|
|
759
|
+
errors.push({
|
|
760
|
+
kind: "missing-lockfile",
|
|
761
|
+
message: "No yarn.lock found",
|
|
762
|
+
location: "yarn.lock"
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
if (lockfileContent !== void 0) {
|
|
766
|
+
const lockfileDeclarations = uniqueDeclarations(
|
|
767
|
+
discoverLockfileDeclarations(
|
|
768
|
+
rootDir,
|
|
769
|
+
configuration,
|
|
770
|
+
lockfileContent,
|
|
771
|
+
errors
|
|
772
|
+
)
|
|
773
|
+
);
|
|
774
|
+
for (const [key, declaration] of uniqueManifestDeclarations) {
|
|
775
|
+
const lockfileDeclaration = lockfileDeclarations.get(key);
|
|
776
|
+
if (!lockfileDeclaration) {
|
|
777
|
+
errors.push({
|
|
778
|
+
kind: "lockfile-mismatch",
|
|
779
|
+
message: `Patch declaration for '${declaration.source}' using '${declarationDescription(
|
|
780
|
+
declaration
|
|
781
|
+
)}' is missing from yarn.lock`,
|
|
782
|
+
location: declaration.location
|
|
783
|
+
});
|
|
784
|
+
} else {
|
|
785
|
+
declaration.resolvedSource = lockfileDeclaration.resolvedSource;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
for (const [key, declaration] of lockfileDeclarations) {
|
|
789
|
+
if (declaration.projectOwned && !uniqueManifestDeclarations.has(key)) {
|
|
790
|
+
errors.push({
|
|
791
|
+
kind: "lockfile-mismatch",
|
|
792
|
+
message: `yarn.lock contains patch declaration for '${declaration.source}' using '${declarationDescription(
|
|
793
|
+
declaration
|
|
794
|
+
)}' that is absent from manifests`,
|
|
795
|
+
location: "yarn.lock"
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
const sourcesByPatchFile = /* @__PURE__ */ new Map();
|
|
801
|
+
for (const declaration of uniqueManifestDeclarations.values()) {
|
|
802
|
+
for (const patchPath of declaration.paths) {
|
|
803
|
+
let sources = sourcesByPatchFile.get(patchPath.absolute);
|
|
804
|
+
if (!sources) {
|
|
805
|
+
sources = /* @__PURE__ */ new Set();
|
|
806
|
+
sourcesByPatchFile.set(patchPath.absolute, sources);
|
|
807
|
+
}
|
|
808
|
+
sources.add(declaration.resolvedSource ?? declaration.source);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
for (const [absolute, sources] of sourcesByPatchFile) {
|
|
812
|
+
if (sources.size <= 1) {
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
const patchPath = referencedPatchFiles.get(absolute);
|
|
816
|
+
if (!patchPath) {
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
819
|
+
const sortedSources = [...sources].sort();
|
|
820
|
+
errors.push({
|
|
821
|
+
kind: "incompatible-patch-declarations",
|
|
822
|
+
message: `Patch file '${patchPath.relative}' is used for incompatible sources: ${sortedSources.map((source) => `'${source}'`).join(", ")}`,
|
|
823
|
+
location: patchPath.relative
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
const backstageValidation = await validateBackstagePatches({
|
|
827
|
+
rootDir,
|
|
828
|
+
declarations: uniqueManifestDeclarations.values(),
|
|
829
|
+
configuration,
|
|
830
|
+
env: options.env,
|
|
831
|
+
fetch: options.fetch
|
|
832
|
+
});
|
|
833
|
+
errors.push(...backstageValidation.errors);
|
|
834
|
+
return {
|
|
835
|
+
patchCount: referencedPatchFiles.size,
|
|
836
|
+
backstageCheck: backstageValidation.backstageCheck,
|
|
837
|
+
errors: sortErrors(errors)
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
exports.verifyYarnPatches = verifyYarnPatches;
|
|
842
|
+
//# sourceMappingURL=verifyYarnPatches.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyYarnPatches.cjs.js","sources":["../../src/lib/verifyYarnPatches.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n getManifestByVersion,\n type ReleaseManifest,\n} from '@backstage/release-manifests';\nimport {\n Configuration,\n httpUtils,\n semverUtils,\n structUtils,\n} from '@yarnpkg/core';\nimport { Project, TAG_REGEXP, Workspace } from '@yarnpkg/core';\nimport type { Descriptor, PluginConfiguration } from '@yarnpkg/core';\nimport { npath, ppath } from '@yarnpkg/fslib';\nimport { parseResolution, parseSyml } from '@yarnpkg/parsers';\nimport patchPlugin from '@yarnpkg/plugin-patch';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport type PatchVerificationErrorKind =\n | 'backstage-manifest-load-failure'\n | 'backstage-package-missing'\n | 'backstage-patch-holdback'\n | 'incompatible-patch-declarations'\n | 'lockfile-mismatch'\n | 'malformed-lockfile'\n | 'malformed-patch-reference'\n | 'missing-lockfile'\n | 'missing-patch-file'\n | 'orphaned-patch-file';\n\nexport type PatchVerificationError = {\n kind: PatchVerificationErrorKind;\n message: string;\n location?: string;\n};\n\nexport type VerifyYarnPatchesOptions = {\n rootDir: string;\n env?: NodeJS.ProcessEnv;\n fetch?: typeof globalThis.fetch;\n};\n\nexport type VerifyYarnPatchesResult = {\n patchCount: number;\n backstageCheck: 'verified' | 'skipped';\n errors: PatchVerificationError[];\n};\n\ntype PatchDeclaration = {\n patchedIdent: string;\n source: string;\n resolvedSource?: string;\n components: string[];\n parentLocator?: string;\n canMatchManifest: boolean;\n projectOwned: boolean;\n paths: LocalPatchPath[];\n location: string;\n};\n\ntype LocalPatchPath = {\n absolute: string;\n relative: string;\n};\n\ntype PatchedBackstagePackage = {\n name: string;\n version: string;\n location: string;\n};\n\nconst MANIFEST_FIELDS = [\n 'resolutions',\n 'dependencies',\n 'devDependencies',\n 'peerDependencies',\n 'optionalDependencies',\n] as const;\n\nconst PATCH_PLUGIN_CONFIGURATION: PluginConfiguration = {\n modules: new Map([['@yarnpkg/plugin-patch', patchPlugin]]),\n plugins: new Set(['@yarnpkg/plugin-patch']),\n};\n\n// Yarn Configuration.find has no environment parameter and reads process.env.\n// Serialize the narrow overlay so concurrent verifications cannot interleave.\nlet configurationEnvironmentQueue = Promise.resolve();\n\nfunction relativePath(rootDir: string, targetPath: string): string {\n return path.relative(rootDir, targetPath).split(path.sep).join('/');\n}\n\nfunction compareStrings(left: string, right: string): number {\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n return 0;\n}\n\nfunction sortErrors(\n errors: PatchVerificationError[],\n): PatchVerificationError[] {\n return errors.sort((left, right) => {\n return (\n compareStrings(left.location ?? '', right.location ?? '') ||\n compareStrings(left.kind, right.kind) ||\n compareStrings(left.message, right.message)\n );\n });\n}\n\nfunction isErrorWithCode(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n );\n}\n\nfunction getPatchPathWithoutFlags(patchPath: string): string {\n if (patchPath.startsWith('~builtin<')) {\n return patchPath.slice(1);\n }\n const flagIndex = patchPath.lastIndexOf('!');\n return flagIndex === -1 ? patchPath : patchPath.slice(flagIndex + 1);\n}\n\nfunction isBuiltinPatchPath(patchPath: string): boolean {\n const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);\n return (\n pathWithoutFlags.startsWith('builtin<') && pathWithoutFlags.endsWith('>')\n );\n}\n\ntype PatchParent = {\n directory?: string;\n locator?: string;\n};\n\nfunction getPatchParent(\n rootDir: string,\n fallbackDir: string,\n locatorValue: unknown,\n): PatchParent {\n if (typeof locatorValue !== 'string') {\n return { directory: fallbackDir };\n }\n\n const parentLocator = structUtils.parseLocator(locatorValue, true);\n const locator = structUtils.stringifyLocator(parentLocator);\n const parentRange = structUtils.parseRange(parentLocator.reference);\n if (parentRange.protocol !== 'workspace:') {\n return { locator };\n }\n\n return {\n directory: path.resolve(rootDir, parentRange.selector),\n locator,\n };\n}\n\nfunction resolvePatchPath(\n rootDir: string,\n parentDir: string | undefined,\n patchPath: string,\n): LocalPatchPath | undefined {\n const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);\n if (isBuiltinPatchPath(pathWithoutFlags)) {\n return undefined;\n }\n\n const portablePatchPath = npath.toPortablePath(pathWithoutFlags);\n let absolute: string | undefined;\n if (pathWithoutFlags.startsWith('~/')) {\n absolute = path.resolve(rootDir, pathWithoutFlags.slice(2));\n } else if (ppath.isAbsolute(portablePatchPath)) {\n absolute = npath.fromPortablePath(portablePatchPath);\n } else if (parentDir !== undefined) {\n absolute = path.resolve(parentDir, pathWithoutFlags);\n }\n if (absolute === undefined) {\n return undefined;\n }\n return {\n absolute,\n relative: relativePath(rootDir, absolute),\n };\n}\n\nfunction parsePatchDeclaration(options: {\n rootDir: string;\n parentDir: string;\n parentLocator?: string;\n patchedIdent: string;\n range: string;\n location: string;\n origin: 'manifest' | 'lockfile';\n}): PatchDeclaration | undefined {\n const parsedRange = structUtils.parseRange(options.range, {\n requireProtocol: 'patch:',\n requireSource: true,\n });\n const sourceDescriptor = structUtils.parseDescriptor(\n parsedRange.source,\n true,\n );\n const source = structUtils.stringifyDescriptor(sourceDescriptor);\n const parent = getPatchParent(\n options.rootDir,\n options.parentDir,\n parsedRange.params?.locator,\n );\n const paths: LocalPatchPath[] = [];\n let hasDependencyOwnedPath = false;\n let hasProjectRelativePath = false;\n const patchPaths =\n parsedRange.selector === '' ? [] : parsedRange.selector.split('&');\n const components = patchPaths.map(patchPath => {\n const flagIndex = patchPath.lastIndexOf('!');\n const flags = flagIndex === -1 ? '' : patchPath.slice(0, flagIndex + 1);\n const pathWithoutFlags = getPatchPathWithoutFlags(patchPath);\n if (isBuiltinPatchPath(patchPath)) {\n return patchPath;\n }\n\n const localPath = resolvePatchPath(\n options.rootDir,\n parent.directory,\n patchPath,\n );\n if (localPath) {\n paths.push(localPath);\n if (\n !pathWithoutFlags.startsWith('~/') &&\n !ppath.isAbsolute(npath.toPortablePath(pathWithoutFlags))\n ) {\n hasProjectRelativePath = true;\n }\n return `${flags}local<${localPath.absolute}>`;\n }\n hasDependencyOwnedPath = true;\n return `${flags}relative<${pathWithoutFlags}>`;\n });\n\n if (components.length === 0) {\n return undefined;\n }\n\n return {\n patchedIdent: options.patchedIdent,\n source,\n components,\n parentLocator:\n parent.locator ??\n (hasProjectRelativePath ? options.parentLocator : undefined),\n canMatchManifest: !hasDependencyOwnedPath,\n projectOwned:\n paths.length > 0 ||\n (options.origin === 'manifest' && !hasDependencyOwnedPath),\n paths,\n location: options.location,\n };\n}\n\nfunction declarationKey(declaration: PatchDeclaration): string {\n return `${declaration.parentLocator ?? ''}\\0${declaration.patchedIdent}\\0${\n declaration.source\n }\\0${declaration.components.join('\\0')}`;\n}\n\nfunction declarationDescription(declaration: PatchDeclaration): string {\n return declaration.paths.map(patchPath => patchPath.relative).join(', ');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isYarnPluginsKey(key: string): boolean {\n return key.toLowerCase() === 'yarn_plugins';\n}\n\nfunction setEnvironmentValue(key: string, value: string | undefined): void {\n if (value === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = value;\n }\n}\n\nasync function withConfigurationEnvironment<T>(\n env: NodeJS.ProcessEnv | undefined,\n action: () => Promise<T>,\n): Promise<T> {\n const waitForTurn = configurationEnvironmentQueue;\n let releaseTurn = () => {};\n const turnComplete = new Promise<void>(resolve => {\n releaseTurn = resolve;\n });\n configurationEnvironmentQueue = waitForTurn.then(() => turnComplete);\n await waitForTurn;\n\n const environmentState = new Map<\n string,\n { previous: string | undefined; applied: string | undefined }\n >();\n\n try {\n const targetEnvironment = env ? { ...env } : undefined;\n if (targetEnvironment) {\n for (const key of Object.keys(targetEnvironment)) {\n if (isYarnPluginsKey(key)) {\n delete targetEnvironment[key];\n }\n }\n }\n\n const keysToScope = new Set(\n targetEnvironment\n ? [...Object.keys(process.env), ...Object.keys(env ?? {})]\n : Object.keys(process.env).filter(isYarnPluginsKey),\n );\n for (const key of keysToScope) {\n const previous = process.env[key];\n const applied = isYarnPluginsKey(key)\n ? undefined\n : targetEnvironment?.[key];\n environmentState.set(key, { previous, applied });\n setEnvironmentValue(key, applied);\n }\n\n return await action();\n } finally {\n for (const [key, { previous, applied }] of environmentState) {\n // Keep values changed by unrelated async work while Yarn was loading.\n if (process.env[key] === applied) {\n setEnvironmentValue(key, previous);\n }\n }\n releaseTurn();\n }\n}\n\nfunction arraysEqual(left: string[], right: string[]): boolean {\n return (\n left.length === right.length &&\n left.every((value, index) => value === right[index])\n );\n}\n\nfunction getNpmResolutionRange(\n range: ReturnType<typeof structUtils.parseRange>,\n): string | undefined {\n if (\n range.protocol === 'npm:' &&\n semverUtils.validRange(range.selector) !== null\n ) {\n return range.selector;\n }\n\n const npmVersion = range.params?.npm;\n if (\n range.protocol === 'backstage:' &&\n range.selector === '^' &&\n typeof npmVersion === 'string' &&\n semverUtils.clean(npmVersion) !== null\n ) {\n return `^${npmVersion}`;\n }\n\n return undefined;\n}\n\nfunction normalizeNpmAliasSource(descriptor: Descriptor): Descriptor {\n const range = structUtils.parseRange(descriptor.range);\n if (range.protocol !== 'npm:') {\n return descriptor;\n }\n\n const aliasTarget = structUtils.tryParseDescriptor(range.selector, true);\n if (!aliasTarget) {\n return descriptor;\n }\n\n const aliasTargetRange = structUtils.parseRange(aliasTarget.range);\n return aliasTargetRange.protocol === null\n ? structUtils.makeDescriptor(aliasTarget, `npm:${aliasTarget.range}`)\n : aliasTarget;\n}\n\nfunction npmSourceAgrees(\n descriptorRange: ReturnType<typeof structUtils.parseRange>,\n locatorRange: ReturnType<typeof structUtils.parseRange>,\n): boolean | undefined {\n if (locatorRange.protocol !== 'npm:') {\n return undefined;\n }\n\n const resolvedVersion = semverUtils.clean(locatorRange.selector);\n if (resolvedVersion === null) {\n return false;\n }\n\n const resolutionRange = getNpmResolutionRange(descriptorRange);\n if (resolutionRange !== undefined) {\n return semverUtils.satisfiesWithPrereleases(\n resolvedVersion,\n resolutionRange,\n );\n }\n\n return descriptorRange.protocol === 'npm:'\n ? TAG_REGEXP.test(descriptorRange.selector)\n : undefined;\n}\n\nfunction nonNpmSourceAgrees(\n descriptorRange: ReturnType<typeof structUtils.parseRange>,\n locatorRange: ReturnType<typeof structUtils.parseRange>,\n): boolean {\n if (descriptorRange.protocol !== locatorRange.protocol) {\n return false;\n }\n\n if (descriptorRange.protocol === 'workspace:') {\n const selector = descriptorRange.selector;\n if (\n selector === '*' ||\n selector === '^' ||\n selector === '~' ||\n semverUtils.validRange(selector) !== null\n ) {\n return true;\n }\n }\n\n const descriptorIdentity = descriptorRange.source ?? descriptorRange.selector;\n const locatorIdentity = locatorRange.source ?? locatorRange.selector;\n if (descriptorIdentity !== locatorIdentity) {\n return false;\n }\n\n const descriptorParent = descriptorRange.params?.locator;\n if (\n typeof descriptorParent === 'string' &&\n descriptorParent !== locatorRange.params?.locator\n ) {\n return false;\n }\n\n if (\n descriptorRange.source !== null &&\n descriptorRange.selector.startsWith('commit=')\n ) {\n return descriptorRange.selector === locatorRange.selector;\n }\n\n return true;\n}\n\nfunction patchDescriptorAgreesWithLocator(options: {\n configuration: Configuration;\n descriptor: ReturnType<typeof structUtils.parseDescriptor>;\n descriptorDeclaration: PatchDeclaration | undefined;\n locator: ReturnType<typeof structUtils.parseLocator>;\n locatorDeclaration: PatchDeclaration | undefined;\n}): boolean {\n if (!structUtils.areIdentsEqual(options.descriptor, options.locator)) {\n return false;\n }\n\n const descriptorRange = structUtils.parseRange(options.descriptor.range, {\n requireProtocol: 'patch:',\n requireSource: true,\n });\n const locatorRange = structUtils.parseRange(options.locator.reference, {\n requireProtocol: 'patch:',\n requireSource: true,\n });\n const sourceDescriptor = normalizeNpmAliasSource(\n options.configuration.normalizeDependency(\n structUtils.parseDescriptor(descriptorRange.source, true),\n ),\n );\n const sourceLocator = structUtils.parseLocator(locatorRange.source, true);\n if (!structUtils.areIdentsEqual(sourceDescriptor, sourceLocator)) {\n return false;\n }\n\n const descriptorSourceRange = structUtils.parseRange(sourceDescriptor.range);\n const locatorSourceRange = structUtils.parseRange(sourceLocator.reference);\n const npmAgreement = npmSourceAgrees(\n descriptorSourceRange,\n locatorSourceRange,\n );\n if (\n npmAgreement === false ||\n (npmAgreement === undefined &&\n !nonNpmSourceAgrees(descriptorSourceRange, locatorSourceRange))\n ) {\n return false;\n }\n\n return (\n options.descriptorDeclaration?.parentLocator ===\n options.locatorDeclaration?.parentLocator &&\n arraysEqual(\n options.descriptorDeclaration?.components ?? [],\n options.locatorDeclaration?.components ?? [],\n )\n );\n}\n\nasync function discoverManifestDeclarations(\n rootDir: string,\n configuration: Configuration,\n errors: PatchVerificationError[],\n): Promise<PatchDeclaration[]> {\n const project = new Project(npath.toPortablePath(rootDir), { configuration });\n const pendingWorkspaces = [npath.toPortablePath(rootDir)];\n const visitedWorkspaces = new Set<string>();\n const declarations: PatchDeclaration[] = [];\n\n while (pendingWorkspaces.length > 0) {\n const workspaceCwd = pendingWorkspaces.shift();\n if (workspaceCwd === undefined || visitedWorkspaces.has(workspaceCwd)) {\n continue;\n }\n visitedWorkspaces.add(workspaceCwd);\n\n const workspace = new Workspace(workspaceCwd, { project });\n await workspace.setup();\n pendingWorkspaces.push(...workspace.workspacesCwds);\n\n const manifestDir = npath.fromPortablePath(workspace.cwd);\n const manifestPath = relativePath(\n rootDir,\n path.join(manifestDir, 'package.json'),\n );\n const manifestJson: Record<string, unknown> = workspace.manifest.raw;\n const parentLocator = structUtils.stringifyLocator(\n workspace.anchoredLocator,\n );\n\n for (const field of MANIFEST_FIELDS) {\n const entries = manifestJson[field];\n if (typeof entries !== 'object' || entries === null) {\n continue;\n }\n\n for (const [name, range] of Object.entries(entries)) {\n if (typeof range !== 'string' || !range.startsWith('patch:')) {\n continue;\n }\n\n const location = `${manifestPath}#${field}.${name}`;\n try {\n const declaration = parsePatchDeclaration({\n rootDir,\n parentDir: manifestDir,\n parentLocator,\n patchedIdent:\n field === 'resolutions'\n ? parseResolution(name).descriptor.fullName\n : structUtils.stringifyIdent(structUtils.parseIdent(name)),\n range,\n location,\n origin: 'manifest',\n });\n if (declaration) {\n declarations.push(declaration);\n }\n } catch (error) {\n errors.push({\n kind: 'malformed-patch-reference',\n message: `Invalid patch reference for '${name}' in ${field}: ${String(\n error,\n )}`,\n location,\n });\n }\n }\n }\n }\n\n return declarations;\n}\n\nfunction discoverLockfileDeclarations(\n rootDir: string,\n configuration: Configuration,\n lockfileContent: string,\n errors: PatchVerificationError[],\n): PatchDeclaration[] {\n let lockfileData: Record<string, unknown>;\n try {\n lockfileData = parseSyml(lockfileContent);\n } catch (error) {\n errors.push({\n kind: 'malformed-lockfile',\n message: `Failed to parse yarn.lock: ${String(error)}`,\n location: 'yarn.lock',\n });\n return [];\n }\n\n const declarations: PatchDeclaration[] = [];\n for (const [key, lockfileEntry] of Object.entries(lockfileData)) {\n if (key === '__metadata') {\n continue;\n }\n\n const patchDescriptors: Array<{\n descriptor: ReturnType<typeof structUtils.parseDescriptor>;\n declaration: PatchDeclaration | undefined;\n }> = [];\n for (const entry of key.split(', ')) {\n try {\n const descriptor = structUtils.parseDescriptor(entry, true);\n if (!descriptor.range.startsWith('patch:')) {\n continue;\n }\n const declaration = parsePatchDeclaration({\n rootDir,\n parentDir: rootDir,\n patchedIdent: structUtils.stringifyIdent(descriptor),\n range: descriptor.range,\n location: 'yarn.lock',\n origin: 'lockfile',\n });\n if (declaration?.canMatchManifest) {\n declarations.push(declaration);\n }\n patchDescriptors.push({ descriptor, declaration });\n } catch (error) {\n errors.push({\n kind: 'malformed-lockfile',\n message: `Invalid patch entry '${entry}' in yarn.lock: ${String(\n error,\n )}`,\n location: 'yarn.lock',\n });\n }\n }\n\n if (patchDescriptors.length === 0) {\n continue;\n }\n\n const resolution = isRecord(lockfileEntry)\n ? lockfileEntry.resolution\n : undefined;\n if (typeof resolution !== 'string') {\n errors.push({\n kind: 'malformed-lockfile',\n message: `Patch entry '${key}' is missing its resolution locator`,\n location: 'yarn.lock',\n });\n continue;\n }\n\n try {\n const locator = structUtils.parseLocator(resolution, true);\n if (!locator.reference.startsWith('patch:')) {\n errors.push({\n kind: 'lockfile-mismatch',\n message: `Patch entry '${key}' disagrees with its resolution locator '${resolution}'`,\n location: 'yarn.lock',\n });\n continue;\n }\n const locatorDeclaration = parsePatchDeclaration({\n rootDir,\n parentDir: rootDir,\n patchedIdent: structUtils.stringifyIdent(locator),\n range: locator.reference,\n location: 'yarn.lock',\n origin: 'lockfile',\n });\n const locatorRange = structUtils.parseRange(locator.reference, {\n requireProtocol: 'patch:',\n requireSource: true,\n });\n const resolvedSource = structUtils.stringifyLocator(\n structUtils.parseLocator(locatorRange.source, true),\n );\n for (const { declaration } of patchDescriptors) {\n if (declaration) {\n declaration.resolvedSource = resolvedSource;\n }\n }\n if (\n patchDescriptors.some(\n ({ descriptor, declaration }) =>\n !patchDescriptorAgreesWithLocator({\n configuration,\n descriptor,\n descriptorDeclaration: declaration,\n locator,\n locatorDeclaration,\n }),\n )\n ) {\n errors.push({\n kind: 'lockfile-mismatch',\n message: `Patch entry '${key}' disagrees with its resolution locator '${resolution}'`,\n location: 'yarn.lock',\n });\n }\n } catch (error) {\n errors.push({\n kind: 'malformed-lockfile',\n message: `Patch entry '${key}' has an invalid resolution locator '${resolution}': ${String(\n error,\n )}`,\n location: 'yarn.lock',\n });\n }\n }\n\n return declarations;\n}\n\nasync function readYarnConfiguration(\n rootDir: string,\n env: NodeJS.ProcessEnv | undefined,\n): Promise<Configuration> {\n return withConfigurationEnvironment(env, async () => {\n // Yarn still applies inherited rc files when useRc is false; this only\n // prevents project rc files from loading arbitrary third-party plugins.\n return Configuration.find(\n npath.toPortablePath(rootDir),\n PATCH_PLUGIN_CONFIGURATION,\n {\n strict: false,\n useRc: false,\n },\n );\n });\n}\n\nasync function findPatchFiles(\n directory: string,\n realpathAncestry: ReadonlySet<string> = new Set(),\n): Promise<string[]> {\n let realDirectory;\n try {\n realDirectory = await fs.realpath(directory);\n } catch (error) {\n if (isErrorWithCode(error, 'ENOENT')) {\n return [];\n }\n throw error;\n }\n if (realpathAncestry.has(realDirectory)) {\n return [];\n }\n const nextAncestry = new Set(realpathAncestry).add(realDirectory);\n\n let entries;\n try {\n entries = await fs.readdir(directory, { withFileTypes: true });\n } catch (error) {\n if (isErrorWithCode(error, 'ENOENT')) {\n return [];\n }\n throw error;\n }\n\n const files = await Promise.all(\n entries.map(async entry => {\n const entryPath = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n return findPatchFiles(entryPath, nextAncestry);\n }\n if (entry.isSymbolicLink()) {\n try {\n const targetStats = await fs.stat(entryPath);\n if (targetStats.isDirectory()) {\n return findPatchFiles(entryPath, nextAncestry);\n }\n } catch (error) {\n if (!isErrorWithCode(error, 'ENOENT')) {\n throw error;\n }\n }\n return [entryPath];\n }\n return entry.isFile() ? [entryPath] : [];\n }),\n );\n return files.flat().sort();\n}\n\nfunction uniqueDeclarations(\n declarations: PatchDeclaration[],\n): Map<string, PatchDeclaration> {\n const unique = new Map<string, PatchDeclaration>();\n for (const declaration of declarations) {\n const key = declarationKey(declaration);\n if (!unique.has(key)) {\n unique.set(key, declaration);\n }\n }\n return unique;\n}\n\nfunction getPatchedBackstagePackages(\n declarations: Iterable<PatchDeclaration>,\n): PatchedBackstagePackage[] {\n const packages: PatchedBackstagePackage[] = [];\n for (const declaration of declarations) {\n const declaredSource = normalizeNpmAliasSource(\n structUtils.parseDescriptor(declaration.source, true),\n );\n const resolvedSource = declaration.resolvedSource;\n const source = resolvedSource\n ? structUtils.parseLocator(resolvedSource, true)\n : declaredSource;\n if (source.scope !== 'backstage') {\n continue;\n }\n const range = structUtils.parseRange(\n 'reference' in source ? source.reference : source.range,\n );\n if (\n range.protocol !== 'npm:' ||\n semverUtils.clean(range.selector) === null\n ) {\n continue;\n }\n packages.push({\n name: structUtils.stringifyIdent(source),\n version: range.selector,\n location: declaration.location,\n });\n }\n return packages;\n}\n\nfunction isReleaseManifest(value: unknown): value is ReleaseManifest {\n return (\n isRecord(value) &&\n typeof value.releaseVersion === 'string' &&\n Array.isArray(value.packages) &&\n value.packages.every(\n packageEntry =>\n isRecord(packageEntry) &&\n typeof packageEntry.name === 'string' &&\n typeof packageEntry.version === 'string',\n )\n );\n}\n\nasync function readBackstageVersion(\n rootDir: string,\n): Promise<string | undefined> {\n try {\n const backstageJson: unknown = JSON.parse(\n await fs.readFile(path.join(rootDir, 'backstage.json'), 'utf8'),\n );\n if (!isRecord(backstageJson) || typeof backstageJson.version !== 'string') {\n throw new Error(\n \"backstage.json must contain a string 'version' property\",\n );\n }\n return backstageJson.version;\n } catch (error) {\n if (isErrorWithCode(error, 'ENOENT')) {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function loadReleaseManifest(options: {\n backstageVersion: string;\n configuration: Configuration;\n env: NodeJS.ProcessEnv | undefined;\n fetch: typeof globalThis.fetch | undefined;\n}): Promise<ReleaseManifest> {\n const manifestFile = options.env?.BACKSTAGE_MANIFEST_FILE;\n const fetch =\n options.fetch ??\n (async (url: string) => {\n const manifest = await httpUtils.get(url, {\n configuration: options.configuration,\n jsonResponse: true,\n });\n return {\n status: 200,\n url,\n json: async () => manifest,\n };\n });\n const manifest: unknown = manifestFile\n ? JSON.parse(await fs.readFile(manifestFile, 'utf8'))\n : await getManifestByVersion({\n version: options.backstageVersion,\n versionsBaseUrl: options.env?.BACKSTAGE_VERSIONS_BASE_URL,\n fetch,\n });\n if (!isReleaseManifest(manifest)) {\n throw new Error('Backstage release manifest has an invalid format');\n }\n if (manifest.releaseVersion !== options.backstageVersion) {\n throw new Error(\n `Backstage release manifest version '${manifest.releaseVersion}' does not match selected version '${options.backstageVersion}'`,\n );\n }\n return manifest;\n}\n\nasync function validateBackstagePatches(options: {\n rootDir: string;\n declarations: Iterable<PatchDeclaration>;\n configuration: Configuration;\n env: NodeJS.ProcessEnv | undefined;\n fetch: typeof globalThis.fetch | undefined;\n}): Promise<{\n backstageCheck: VerifyYarnPatchesResult['backstageCheck'];\n errors: PatchVerificationError[];\n}> {\n const patchedPackages = getPatchedBackstagePackages(options.declarations);\n if (patchedPackages.length === 0) {\n return { backstageCheck: 'skipped', errors: [] };\n }\n\n let backstageVersion: string | undefined;\n try {\n backstageVersion = await readBackstageVersion(options.rootDir);\n } catch (error) {\n return {\n backstageCheck: 'verified',\n errors: [\n {\n kind: 'backstage-manifest-load-failure',\n message: `Failed to read Backstage release version: ${String(error)}`,\n location: 'backstage.json',\n },\n ],\n };\n }\n if (backstageVersion === undefined) {\n return { backstageCheck: 'skipped', errors: [] };\n }\n\n let releaseManifest: ReleaseManifest;\n try {\n releaseManifest = await loadReleaseManifest({\n backstageVersion,\n configuration: options.configuration,\n env: options.env,\n fetch: options.fetch,\n });\n } catch (error) {\n return {\n backstageCheck: 'verified',\n errors: [\n {\n kind: 'backstage-manifest-load-failure',\n message: `Failed to load Backstage release manifest for '${backstageVersion}': ${String(\n error,\n )}`,\n location: 'backstage.json',\n },\n ],\n };\n }\n\n const packageVersions = new Map(\n releaseManifest.packages.map(packageEntry => [\n packageEntry.name,\n packageEntry.version,\n ]),\n );\n const errors: PatchVerificationError[] = [];\n for (const patchedPackage of patchedPackages) {\n const releaseVersion = packageVersions.get(patchedPackage.name);\n if (releaseVersion === undefined) {\n errors.push({\n kind: 'backstage-package-missing',\n message: `Patched package '${patchedPackage.name}' is absent from Backstage release '${backstageVersion}'`,\n location: patchedPackage.location,\n });\n } else if (releaseVersion !== patchedPackage.version) {\n errors.push({\n kind: 'backstage-patch-holdback',\n message: `Patched package '${patchedPackage.name}' is at version '${patchedPackage.version}', but Backstage release '${backstageVersion}' requires version '${releaseVersion}'`,\n location: patchedPackage.location,\n });\n }\n }\n\n return { backstageCheck: 'verified', errors };\n}\n\nexport async function verifyYarnPatches(\n options: VerifyYarnPatchesOptions,\n): Promise<VerifyYarnPatchesResult> {\n const rootDir = path.resolve(options.rootDir);\n const errors: PatchVerificationError[] = [];\n const configuration = await readYarnConfiguration(rootDir, options.env);\n const manifestDeclarations = await discoverManifestDeclarations(\n rootDir,\n configuration,\n errors,\n );\n const uniqueManifestDeclarations = uniqueDeclarations(manifestDeclarations);\n const referencedPatchFiles = new Map<string, LocalPatchPath>();\n\n for (const declaration of uniqueManifestDeclarations.values()) {\n for (const patchPath of declaration.paths) {\n referencedPatchFiles.set(patchPath.absolute, patchPath);\n }\n }\n\n for (const [absolute, patchPath] of referencedPatchFiles) {\n try {\n const stats = await fs.stat(absolute);\n if (!stats.isFile()) {\n errors.push({\n kind: 'missing-patch-file',\n message: `Patch path '${patchPath.relative}' is not a regular file`,\n location: patchPath.relative,\n });\n }\n } catch (error) {\n if (!isErrorWithCode(error, 'ENOENT')) {\n throw error;\n }\n errors.push({\n kind: 'missing-patch-file',\n message: `Patch file '${patchPath.relative}' does not exist`,\n location: patchPath.relative,\n });\n }\n }\n\n const patchFolder = npath.fromPortablePath(configuration.get('patchFolder'));\n const patchFiles = await findPatchFiles(patchFolder);\n for (const patchFile of patchFiles) {\n if (!referencedPatchFiles.has(patchFile)) {\n const relative = relativePath(rootDir, patchFile);\n errors.push({\n kind: 'orphaned-patch-file',\n message: `Patch file '${relative}' is not referenced by any manifest`,\n location: relative,\n });\n }\n }\n\n let lockfileContent: string | undefined;\n try {\n lockfileContent = await fs.readFile(\n path.join(rootDir, 'yarn.lock'),\n 'utf8',\n );\n } catch (error) {\n if (!isErrorWithCode(error, 'ENOENT')) {\n throw error;\n }\n errors.push({\n kind: 'missing-lockfile',\n message: 'No yarn.lock found',\n location: 'yarn.lock',\n });\n }\n\n if (lockfileContent !== undefined) {\n const lockfileDeclarations = uniqueDeclarations(\n discoverLockfileDeclarations(\n rootDir,\n configuration,\n lockfileContent,\n errors,\n ),\n );\n\n for (const [key, declaration] of uniqueManifestDeclarations) {\n const lockfileDeclaration = lockfileDeclarations.get(key);\n if (!lockfileDeclaration) {\n errors.push({\n kind: 'lockfile-mismatch',\n message: `Patch declaration for '${\n declaration.source\n }' using '${declarationDescription(\n declaration,\n )}' is missing from yarn.lock`,\n location: declaration.location,\n });\n } else {\n declaration.resolvedSource = lockfileDeclaration.resolvedSource;\n }\n }\n\n for (const [key, declaration] of lockfileDeclarations) {\n if (declaration.projectOwned && !uniqueManifestDeclarations.has(key)) {\n errors.push({\n kind: 'lockfile-mismatch',\n message: `yarn.lock contains patch declaration for '${\n declaration.source\n }' using '${declarationDescription(\n declaration,\n )}' that is absent from manifests`,\n location: 'yarn.lock',\n });\n }\n }\n }\n\n const sourcesByPatchFile = new Map<string, Set<string>>();\n for (const declaration of uniqueManifestDeclarations.values()) {\n for (const patchPath of declaration.paths) {\n let sources = sourcesByPatchFile.get(patchPath.absolute);\n if (!sources) {\n sources = new Set();\n sourcesByPatchFile.set(patchPath.absolute, sources);\n }\n sources.add(declaration.resolvedSource ?? declaration.source);\n }\n }\n\n for (const [absolute, sources] of sourcesByPatchFile) {\n if (sources.size <= 1) {\n continue;\n }\n const patchPath = referencedPatchFiles.get(absolute);\n if (!patchPath) {\n continue;\n }\n const sortedSources = [...sources].sort();\n errors.push({\n kind: 'incompatible-patch-declarations',\n message: `Patch file '${\n patchPath.relative\n }' is used for incompatible sources: ${sortedSources\n .map(source => `'${source}'`)\n .join(', ')}`,\n location: patchPath.relative,\n });\n }\n\n const backstageValidation = await validateBackstagePatches({\n rootDir,\n declarations: uniqueManifestDeclarations.values(),\n configuration,\n env: options.env,\n fetch: options.fetch,\n });\n errors.push(...backstageValidation.errors);\n\n return {\n patchCount: referencedPatchFiles.size,\n backstageCheck: backstageValidation.backstageCheck,\n errors: sortErrors(errors),\n };\n}\n"],"names":["patchPlugin","path","structUtils","npath","ppath","semverUtils","TAG_REGEXP","Project","Workspace","parseResolution","parseSyml","Configuration","fs","manifest","httpUtils","getManifestByVersion"],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var name = "@backstage/cli-module-package-manager-yarn";
|
|
6
|
+
var version = "0.1.1-next.0";
|
|
7
|
+
var description = "CLI module for Yarn package manager commands";
|
|
8
|
+
var backstage = {
|
|
9
|
+
role: "cli-module"
|
|
10
|
+
};
|
|
11
|
+
var publishConfig = {
|
|
12
|
+
access: "public",
|
|
13
|
+
main: "dist/index.cjs.js",
|
|
14
|
+
types: "dist/index.d.ts"
|
|
15
|
+
};
|
|
16
|
+
var homepage = "https://backstage.io";
|
|
17
|
+
var repository = {
|
|
18
|
+
type: "git",
|
|
19
|
+
url: "https://github.com/backstage/backstage",
|
|
20
|
+
directory: "packages/cli-module-package-manager-yarn"
|
|
21
|
+
};
|
|
22
|
+
var license = "Apache-2.0";
|
|
23
|
+
var main = "src/index.ts";
|
|
24
|
+
var types = "src/index.ts";
|
|
25
|
+
var bin = "bin/backstage-cli-module-package-manager-yarn";
|
|
26
|
+
var files = [
|
|
27
|
+
"dist",
|
|
28
|
+
"bin"
|
|
29
|
+
];
|
|
30
|
+
var scripts = {
|
|
31
|
+
build: "backstage-cli package build",
|
|
32
|
+
clean: "backstage-cli package clean",
|
|
33
|
+
lint: "backstage-cli package lint",
|
|
34
|
+
prepack: "backstage-cli package prepack",
|
|
35
|
+
postpack: "backstage-cli package postpack",
|
|
36
|
+
test: "backstage-cli package test"
|
|
37
|
+
};
|
|
38
|
+
var dependencies = {
|
|
39
|
+
"@backstage/cli-common": "workspace:^",
|
|
40
|
+
"@backstage/cli-node": "workspace:^",
|
|
41
|
+
"@backstage/release-manifests": "workspace:^",
|
|
42
|
+
"@yarnpkg/core": "^4.4.1",
|
|
43
|
+
"@yarnpkg/fslib": "^3.1.2",
|
|
44
|
+
"@yarnpkg/parsers": "^3.0.0",
|
|
45
|
+
"@yarnpkg/plugin-patch": "^4.0.2",
|
|
46
|
+
cleye: "^2.6.0"
|
|
47
|
+
};
|
|
48
|
+
var devDependencies = {
|
|
49
|
+
"@backstage/backend-test-utils": "workspace:^",
|
|
50
|
+
"@backstage/cli": "workspace:^"
|
|
51
|
+
};
|
|
52
|
+
var packageJson = {
|
|
53
|
+
name: name,
|
|
54
|
+
version: version,
|
|
55
|
+
description: description,
|
|
56
|
+
backstage: backstage,
|
|
57
|
+
publishConfig: publishConfig,
|
|
58
|
+
homepage: homepage,
|
|
59
|
+
repository: repository,
|
|
60
|
+
license: license,
|
|
61
|
+
main: main,
|
|
62
|
+
types: types,
|
|
63
|
+
bin: bin,
|
|
64
|
+
files: files,
|
|
65
|
+
scripts: scripts,
|
|
66
|
+
dependencies: dependencies,
|
|
67
|
+
devDependencies: devDependencies
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
exports.backstage = backstage;
|
|
71
|
+
exports.bin = bin;
|
|
72
|
+
exports.default = packageJson;
|
|
73
|
+
exports.dependencies = dependencies;
|
|
74
|
+
exports.description = description;
|
|
75
|
+
exports.devDependencies = devDependencies;
|
|
76
|
+
exports.files = files;
|
|
77
|
+
exports.homepage = homepage;
|
|
78
|
+
exports.license = license;
|
|
79
|
+
exports.main = main;
|
|
80
|
+
exports.name = name;
|
|
81
|
+
exports.publishConfig = publishConfig;
|
|
82
|
+
exports.repository = repository;
|
|
83
|
+
exports.scripts = scripts;
|
|
84
|
+
exports.types = types;
|
|
85
|
+
exports.version = version;
|
|
86
|
+
//# sourceMappingURL=package.json.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/cli-module-package-manager-yarn",
|
|
3
|
+
"version": "0.1.1-next.0",
|
|
4
|
+
"description": "CLI module for Yarn package manager commands",
|
|
5
|
+
"backstage": {
|
|
6
|
+
"role": "cli-module"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"main": "dist/index.cjs.js",
|
|
11
|
+
"types": "dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://backstage.io",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/backstage/backstage",
|
|
17
|
+
"directory": "packages/cli-module-package-manager-yarn"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"main": "dist/index.cjs.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"bin": "bin/backstage-cli-module-package-manager-yarn",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"bin"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "backstage-cli package build",
|
|
29
|
+
"clean": "backstage-cli package clean",
|
|
30
|
+
"lint": "backstage-cli package lint",
|
|
31
|
+
"prepack": "backstage-cli package prepack",
|
|
32
|
+
"postpack": "backstage-cli package postpack",
|
|
33
|
+
"test": "backstage-cli package test"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@backstage/cli-common": "0.3.0",
|
|
37
|
+
"@backstage/cli-node": "0.3.4",
|
|
38
|
+
"@backstage/release-manifests": "0.0.14",
|
|
39
|
+
"@yarnpkg/core": "^4.4.1",
|
|
40
|
+
"@yarnpkg/fslib": "^3.1.2",
|
|
41
|
+
"@yarnpkg/parsers": "^3.0.0",
|
|
42
|
+
"@yarnpkg/plugin-patch": "^4.0.2",
|
|
43
|
+
"cleye": "^2.6.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@backstage/backend-test-utils": "1.11.7-next.0",
|
|
47
|
+
"@backstage/cli": "0.36.6-next.0"
|
|
48
|
+
},
|
|
49
|
+
"typesVersions": {
|
|
50
|
+
"*": {
|
|
51
|
+
"package.json": [
|
|
52
|
+
"package.json"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|