|
| 1 | +constraints_min_version(1). |
| 2 | + |
| 3 | +% This file is written in Prolog |
| 4 | +% It contains rules that the project must respect. |
| 5 | +% Check with "yarn constraints" (fix w/ "yarn constraints --fix") |
| 6 | +% Yarn Constraints https://yarnpkg.com/features/constraints |
| 7 | +% Reference for other constraints: |
| 8 | +% https://github.com/babel/babel/blob/main/constraints.pro |
| 9 | +% https://github.com/yarnpkg/berry/blob/master/constraints.pro |
| 10 | + |
| 11 | +% This rule will enforce that a workspace MUST depend on the same version of a dependency as the one used by the other workspaces |
| 12 | +gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType) :- |
| 13 | + % Iterates over all dependencies from all workspaces |
| 14 | + workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType), |
| 15 | + % Iterates over similarly-named dependencies from all workspaces (again) |
| 16 | + workspace_has_dependency(OtherWorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType2), |
| 17 | + % Ignore peer dependencies |
| 18 | + DependencyType \= 'peerDependencies', |
| 19 | + DependencyType2 \= 'peerDependencies', |
| 20 | + % Ignore workspace:*: we use both `workspace:*` and real version such as `^28.0.0-alpha.8` to reference package in monorepo |
| 21 | + % TODO: in the future we should make it consistent and remove this ignore |
| 22 | + DependencyRange \= 'workspace:*', |
| 23 | + DependencyRange2 \= 'workspace:*', |
| 24 | + % Get the workspace name |
| 25 | + workspace_ident(WorkspaceCwd, WorkspaceIdent), |
| 26 | + workspace_ident(OtherWorkspaceCwd, OtherWorkspaceIdent), |
| 27 | + % @types/node in the root need to stay on ~12.12.0 |
| 28 | + ( |
| 29 | + (WorkspaceIdent = '@jest/monorepo'; OtherWorkspaceIdent = '@jest/monorepo') -> |
| 30 | + DependencyIdent \= '@types/node' |
| 31 | + ; |
| 32 | + true |
| 33 | + ), |
| 34 | + % Allow enzyme example workspace use a older version react and react-dom, because enzyme don't support react 17 |
| 35 | + ( |
| 36 | + (WorkspaceIdent = 'example-enzyme'; OtherWorkspaceIdent = 'example-enzyme') -> |
| 37 | + \+ member(DependencyIdent, ['react', 'react-dom']) |
| 38 | + ; |
| 39 | + true |
| 40 | + ). |
| 41 | + |
| 42 | +% Enforces that a dependency doesn't appear in both `dependencies` and `devDependencies` |
| 43 | +gen_enforced_dependency(WorkspaceCwd, DependencyIdent, null, 'devDependencies') :- |
| 44 | + workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, 'devDependencies'), |
| 45 | + workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, 'dependencies'). |
| 46 | + |
| 47 | +% Enforces the license in all public workspaces while removing it from private workspaces |
| 48 | +gen_enforced_field(WorkspaceCwd, 'license', 'MIT') :- |
| 49 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 50 | +gen_enforced_field(WorkspaceCwd, 'license', null) :- |
| 51 | + workspace_field(WorkspaceCwd, 'private', true). |
| 52 | + |
| 53 | +% Enforces the repository field for all public workspaces while removing it from private workspaces |
| 54 | +gen_enforced_field(WorkspaceCwd, 'repository.type', 'git') :- |
| 55 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 56 | +gen_enforced_field(WorkspaceCwd, 'repository.url', 'https://github.com/facebook/jest.git') :- |
| 57 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 58 | +gen_enforced_field(WorkspaceCwd, 'repository.directory', WorkspaceCwd) :- |
| 59 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 60 | +gen_enforced_field(WorkspaceCwd, 'repository', null) :- |
| 61 | + workspace_field(WorkspaceCwd, 'private', true). |
| 62 | + |
| 63 | +% Enforces 'publishConfig.access' is set to public for public workspaces while removing it from private workspaces |
| 64 | +gen_enforced_field(WorkspaceCwd, 'publishConfig.access', 'public') :- |
| 65 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 66 | +gen_enforced_field(WorkspaceCwd, 'publishConfig.access', null) :- |
| 67 | + workspace_field(WorkspaceCwd, 'private', true). |
| 68 | + |
| 69 | +% Enforces the engines.node field for public workspace |
| 70 | +gen_enforced_field(WorkspaceCwd, 'engines.node', '^12.13.0 || ^14.15.0 || ^16.13.0 || >=17.0.0') :- |
| 71 | + \+ workspace_field(WorkspaceCwd, 'private', true). |
| 72 | + |
| 73 | +% Enforces the main and types field to start with ./ |
| 74 | +gen_enforced_field(WorkspaceCwd, FieldName, ExpectedValue) :- |
| 75 | + % Fields the rule applies to |
| 76 | + member(FieldName, ['main', 'types']), |
| 77 | + % Get current value |
| 78 | + workspace_field(WorkspaceCwd, FieldName, CurrentValue), |
| 79 | + % Must not start with ./ already |
| 80 | + \+ atom_concat('./', _, CurrentValue), |
| 81 | + % Store './' + CurrentValue in ExpectedValue |
| 82 | + atom_concat('./', CurrentValue, ExpectedValue). |
0 commit comments