Skip to content

Commit c31db04

Browse files
committed
Big refactor
1 parent 9f767b7 commit c31db04

File tree

1 file changed

+109
-64
lines changed

1 file changed

+109
-64
lines changed

yarn.config.cjs

Lines changed: 109 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,69 +9,98 @@ const {defineConfig} = require('@yarnpkg/types');
99
* @typedef {import('@yarnpkg/types').Yarn.Constraints.Dependency} Dependency
1010
*/
1111

12+
// Helper Methods
13+
1214
/**
13-
* Enforce that react-native-macos declares a peer dependency on react-native on release branches,
14-
* except on the main branch, where there is no published version of React Native to align to.
15+
* Get the React Native macOS workspace
1516
* @param {Context} context
17+
* @returns {Workspace | null} Workspace
1618
*/
17-
function expectReactNativePeerDependency({Yarn}) {
19+
const getReactNativeMacOSWorkspace = ({Yarn}) => {
1820
const rnmWorkspace = Yarn.workspace({ident: 'react-native-macos'});
1921
if (!rnmWorkspace) {
2022
// Report error on root workspace since react-native-macos doesn't exist
2123
Yarn.workspace().error('react-native-macos workspace must exist in the monorepo');
22-
return;
2324
}
25+
return rnmWorkspace;
26+
}
2427

25-
// Check if react-native-macos version is 1000.0.0 - implying we are on the main branch
26-
const isMainBranch = rnmWorkspace.manifest.version === '1000.0.0';
27-
if (!isMainBranch) {
28-
const rnPeerDependency = rnmWorkspace.pkg.peerDependencies.get('react-native');
29-
if (!rnPeerDependency) {
30-
rnmWorkspace.error('react-native-macos must declare a peer dependency on react-native on release branches');
31-
}
28+
/**
29+
* Get the peer dependency on react-native declared by react-native-macos
30+
* @param {Context} context
31+
* @returns {string | undefined} Peer dependency version
32+
*/
33+
const getReactNativePeerDependency = ({Yarn}) => {
34+
const rnmWorkspace = getReactNativeMacOSWorkspace({Yarn});
35+
36+
const rnPeerDependency = rnmWorkspace?.pkg.peerDependencies.get('react-native');
37+
if (!rnPeerDependency) {
38+
rnmWorkspace?.error('react-native-macos must declare a peer dependency on react-native on release branches');
3239
}
40+
return rnPeerDependency;
3341
}
3442

3543
/**
36-
* Enforce that all @react-native/ scoped packages use the same version
37-
* as the react-native peer dependency declared in react-native-macos.
38-
* Enforce that we use workspace:* for @react-native/ packages.
44+
* // Check if react-native-macos version is 1000.0.0, implying we are on the main branch
3945
* @param {Context} context
46+
* @returns {boolean}
4047
*/
41-
function enforceReactNativeVersionConsistency({Yarn}) {
42-
const rnmWorkspace = Yarn.workspace({ident: 'react-native-macos'});
43-
if (!rnmWorkspace) {
44-
// Report error on root workspace since react-native-macos doesn't exist
45-
Yarn.workspace().error('react-native-macos workspace must exist in the monorepo');
46-
return;
47-
}
48+
const isMainBranch = ({Yarn}) => {
49+
const rnmWorkspace = getReactNativeMacOSWorkspace({Yarn});
50+
return rnmWorkspace?.manifest.version === '1000.0.0';
51+
}
4852

49-
// Check if react-native-macos version is 1000.0.0 - implying we are on the main branch
50-
const isMainBranch = rnmWorkspace.manifest.version === '1000.0.0';
51-
52-
let targetVersion;
53-
if (isMainBranch) {
54-
// On main branch, use workspace:* for @react-native/ packages
55-
targetVersion = 'workspace:*';
56-
} else {
57-
const rnPeerDependency = rnmWorkspace.pkg.peerDependencies.get('react-native');
58-
if (!rnPeerDependency) {
59-
rnmWorkspace.error('react-native-macos must declare a peer dependency on react-native on release branches');
60-
return;
61-
}
62-
targetVersion = rnPeerDependency;
63-
}
64-
// Enforce this version on all @react-native/ scoped packages across all workspaces
53+
// Constraints
54+
55+
/**
56+
* Enforce that all @react-native/ scoped packages are private
57+
* @param {Context} context
58+
*/
59+
function enforcePrivateReactNativeScopedPackages({Yarn}) {
6560
for (const dependency of Yarn.dependencies()) {
6661
if (dependency.ident.startsWith('@react-native/')) {
6762
Yarn.workspace({ident: dependency.ident})?.set('private', true);
63+
}
64+
}
65+
}
66+
67+
/**
68+
* Enforce that react-native-macos declares a peer dependency on react-native on release branches,
69+
* and that this version is consistent across all @react-native/ scoped packages.
70+
* Do not enforce on the main branch, where there is no published version of React Native to align to.
71+
* @param {Context} context
72+
*/
73+
function enforceReactNativeVersionConsistency({Yarn}) {
74+
if (!isMainBranch({Yarn})) {
75+
const reactNativePeerDependency = getReactNativePeerDependency({Yarn});
6876

69-
// Don't use `workspace:*` for `react-native-macos` or `@react-native-macos/` scoped packages (AKA, packages we have forked)
70-
// until nx release with Yarn 4 supports it.
71-
const isRNM = dependency.workspace.ident === 'react-native-macos';
72-
const isRNMForkedPackage = dependency.workspace.ident?.startsWith('@react-native-macos/')
73-
if (isRNM || isRNMForkedPackage) {
74-
dependency.update(targetVersion);
77+
// Enforce this version on all @react-native/ scoped packages
78+
for (const workspace of Yarn.workspaces()) {
79+
if (workspace.ident?.startsWith('@react-native/')) {
80+
workspace.set('version', reactNativePeerDependency);
81+
}
82+
}
83+
}
84+
}
85+
86+
/**
87+
* Enforce that all @react-native/ scoped dependencies use the same version
88+
* as the react-native peer dependency declared in react-native-macos.
89+
* Do not enforce on the main branch, where there is no published version of React Native to align to.
90+
* @param {Context} context
91+
*/
92+
function enforceReactNativeDependencyConsistency({Yarn}) {
93+
for (const dependency of Yarn.dependencies()) {
94+
if (dependency.ident.startsWith('@react-native/')) {
95+
if (!isMainBranch({Yarn})) {
96+
const reactNativeVersion = getReactNativePeerDependency({Yarn});
97+
98+
const isRNM = dependency.workspace.ident === 'react-native-macos';
99+
const isRNMForkedPackage = dependency.workspace.ident?.startsWith('@react-native-macos/');
100+
if (!isRNM || !isRNMForkedPackage) {
101+
// Don't use `workspace:*` for packages we publish until nx release with Yarn 4 supports it.
102+
dependency.update(reactNativeVersion);
103+
}
75104
} else {
76105
dependency.update('workspace:*');
77106
}
@@ -80,39 +109,55 @@ function enforceReactNativeVersionConsistency({Yarn}) {
80109
}
81110

82111
/**
83-
* Enforce that all @react-native-macos/ scoped packages use the same version
84-
* as react-native-macos, but only for non-private packages.
112+
* Enforce that all public @react-native-macos/ scoped packages' versions
113+
* are consistent with react-native-macos
114+
* Do not enforce on the main branch, where we do not publish nightlies yet.
85115
* @param {Context} context
86116
*/
87117
function enforceReactNativeMacosVersionConsistency({Yarn}) {
88-
const rnmWorkspace = Yarn.workspace({ident: 'react-native-macos'});
89-
if (!rnmWorkspace) {
90-
// Report error on root workspace since react-native-macos doesn't exist
91-
Yarn.workspace().error('react-native-macos workspace must exist in the monorepo');
92-
return;
93-
}
118+
if (!isMainBranch({Yarn})) {
119+
const rnmWorkspace = getReactNativeMacOSWorkspace({Yarn});
120+
const rnmVersion = rnmWorkspace?.manifest.version;
94121

95-
const targetVersion = rnmWorkspace.manifest.version;
96-
if (!targetVersion) {
97-
rnmWorkspace.error('react-native-macos must have a version');
98-
return;
99-
}
122+
// Enforce this version on all non-private @react-native-macos/ scoped packages
123+
for (const workspace of Yarn.workspaces()) {
124+
const isReactNativeMacosScoped = workspace.ident && workspace.ident.startsWith('@react-native-macos/');
125+
const isPrivate = workspace.manifest.private;
126+
127+
if (isReactNativeMacosScoped && !isPrivate) {
128+
workspace.set('version', rnmVersion);
129+
}
130+
}
131+
}
132+
}
133+
134+
/**
135+
* Enforce that all @react-native-macos/ scoped dependencies use the same version
136+
* as the react-native-macos
137+
* Do not enforce on the main branch, where there is no published version of React Native to align to.
138+
* @param {Context} context
139+
*/
140+
function enforceReactNativeMacOSDependencyConsistency({Yarn}) {
141+
const rnmWorkspace = getReactNativeMacOSWorkspace({Yarn});
142+
const rnmVersion = rnmWorkspace?.manifest.version;
100143

101-
// Enforce this version on all non-private @react-native-macos/ scoped packages
102-
for (const workspace of Yarn.workspaces()) {
103-
const isReactNativeMacosScoped = workspace.ident && workspace.ident.startsWith('@react-native-macos/');
104-
const isPrivate = workspace.manifest.private;
105-
106-
if (isReactNativeMacosScoped && !isPrivate) {
107-
workspace.set('version', targetVersion);
144+
for (const dependency of Yarn.dependencies()) {
145+
if (dependency.ident.startsWith('@react-native-macos/')) {
146+
if (!isMainBranch({Yarn})) {
147+
dependency.update(rnmVersion);
148+
} else {
149+
dependency.update('workspace:*');
150+
}
108151
}
109152
}
110153
}
111154

112155
module.exports = defineConfig({
113156
constraints: async ctx => {
114-
expectReactNativePeerDependency(ctx);
157+
enforcePrivateReactNativeScopedPackages(ctx);
115158
enforceReactNativeVersionConsistency(ctx);
159+
enforceReactNativeDependencyConsistency(ctx);
116160
enforceReactNativeMacosVersionConsistency(ctx);
161+
enforceReactNativeMacOSDependencyConsistency(ctx);
117162
},
118163
});

0 commit comments

Comments
 (0)