mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-21 15:36:50 -05:00
* [AI] Add yarn constraints to enforce consistent dependency versions Adds a `yarn.config.cjs` that uses Yarn 4's built-in constraints feature to detect when the same dependency is declared with different version ranges across workspaces. Workspace protocol references and peerDependencies are excluded from the check. Also adds a `yarn constraints` convenience script and the `@yarnpkg/types` dev dependency for type-checked constraint authoring. https://claude.ai/code/session_01B1xRjZXn6b18anZjo8cbqb * Add release notes for PR #7229 * Add constraints job to GitHub Actions workflow * Fix constraints --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
55 lines
1.7 KiB
JavaScript
55 lines
1.7 KiB
JavaScript
// @ts-check
|
|
|
|
/** @type {import('@yarnpkg/types')} */
|
|
const { defineConfig } = require('@yarnpkg/types');
|
|
|
|
/**
|
|
* Enforce that all workspaces use the same version of any shared dependency.
|
|
* Workspace protocol references (workspace:*) and peerDependencies are
|
|
* excluded since they intentionally use different/wider ranges.
|
|
*
|
|
* @param {import('@yarnpkg/types').Yarn.Constraints.Context} context
|
|
*/
|
|
function enforceConsistentDependencies({ Yarn }) {
|
|
/** @type {Map<string, Map<string, Array<import('@yarnpkg/types').Yarn.Constraints.Workspace>>>} */
|
|
const dependencyVersions = new Map();
|
|
|
|
for (const workspace of Yarn.workspaces()) {
|
|
for (const type of ['dependencies', 'devDependencies']) {
|
|
for (const dep of Yarn.dependencies({ workspace, type })) {
|
|
if (dep.range.startsWith('workspace:')) continue;
|
|
|
|
if (!dependencyVersions.has(dep.ident)) {
|
|
dependencyVersions.set(dep.ident, new Map());
|
|
}
|
|
const versions = dependencyVersions.get(dep.ident);
|
|
if (!versions.has(dep.range)) {
|
|
versions.set(dep.range, []);
|
|
}
|
|
versions.get(dep.range).push(workspace);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const [ident, versions] of dependencyVersions) {
|
|
if (versions.size <= 1) continue;
|
|
|
|
const rangeList = [...versions.keys()].join(', ');
|
|
|
|
for (const [, workspaces] of versions) {
|
|
for (const workspace of workspaces) {
|
|
workspace.error(
|
|
`Package "${ident}" has inconsistent versions across workspaces (${rangeList}). ` +
|
|
`All workspaces must use the same version range.`,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = defineConfig({
|
|
async constraints(ctx) {
|
|
enforceConsistentDependencies(ctx);
|
|
},
|
|
});
|