Skip to content

Commit e49037b

Browse files
committed
f
1 parent 9f767b7 commit e49037b

File tree

1 file changed

+112
-64
lines changed

1 file changed

+112
-64
lines changed

yarn.config.cjs

Lines changed: 112 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,69 +9,101 @@ 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+
101+
if (isRNM || isRNMForkedPackage) {
102+
// Don't use `workspace:*` for packages we publish until nx release with Yarn 4 supports it.
103+
dependency.update(reactNativeVersion);
104+
} else {
105+
dependency.update('workspace:*');
106+
}
75107
} else {
76108
dependency.update('workspace:*');
77109
}
@@ -80,39 +112,55 @@ function enforceReactNativeVersionConsistency({Yarn}) {
80112
}
81113

82114
/**
83-
* Enforce that all @react-native-macos/ scoped packages use the same version
84-
* as react-native-macos, but only for non-private packages.
115+
* Enforce that all public @react-native-macos/ scoped packages' versions
116+
* are consistent with react-native-macos
117+
* Do not enforce on the main branch, where we do not publish nightlies yet.
85118
* @param {Context} context
86119
*/
87120
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-
}
121+
if (!isMainBranch({Yarn})) {
122+
const rnmWorkspace = getReactNativeMacOSWorkspace({Yarn});
123+
const rnmVersion = rnmWorkspace?.manifest.version;
94124

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

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);
147+
for (const dependency of Yarn.dependencies()) {
148+
if (dependency.ident.startsWith('@react-native-macos/')) {
149+
if (!isMainBranch({Yarn})) {
150+
dependency.update(rnmVersion);
151+
} else {
152+
dependency.update('workspace:*');
153+
}
108154
}
109155
}
110156
}
111157

112158
module.exports = defineConfig({
113159
constraints: async ctx => {
114-
expectReactNativePeerDependency(ctx);
160+
enforcePrivateReactNativeScopedPackages(ctx);
115161
enforceReactNativeVersionConsistency(ctx);
162+
enforceReactNativeDependencyConsistency(ctx);
116163
enforceReactNativeMacosVersionConsistency(ctx);
164+
enforceReactNativeMacOSDependencyConsistency(ctx);
117165
},
118166
});

0 commit comments

Comments
 (0)