@@ -9,69 +9,101 @@ const {defineConfig} = require('@yarnpkg/types');
9
9
* @typedef {import('@yarnpkg/types').Yarn.Constraints.Dependency } Dependency
10
10
*/
11
11
12
+ // Helper Methods
13
+
12
14
/**
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
15
16
* @param {Context } context
17
+ * @returns {Workspace | null } Workspace
16
18
*/
17
- function expectReactNativePeerDependency ( { Yarn} ) {
19
+ const getReactNativeMacOSWorkspace = ( { Yarn} ) => {
18
20
const rnmWorkspace = Yarn . workspace ( { ident : 'react-native-macos' } ) ;
19
21
if ( ! rnmWorkspace ) {
20
22
// Report error on root workspace since react-native-macos doesn't exist
21
23
Yarn . workspace ( ) . error ( 'react-native-macos workspace must exist in the monorepo' ) ;
22
- return ;
23
24
}
25
+ return rnmWorkspace ;
26
+ }
24
27
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' ) ;
32
39
}
40
+ return rnPeerDependency ;
33
41
}
34
42
35
43
/**
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
39
45
* @param {Context } context
46
+ * @returns {boolean }
40
47
*/
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
+ }
48
52
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} ) {
65
60
for ( const dependency of Yarn . dependencies ( ) ) {
66
61
if ( dependency . ident . startsWith ( '@react-native/' ) ) {
67
62
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} ) ;
68
76
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
+ }
75
107
} else {
76
108
dependency . update ( 'workspace:*' ) ;
77
109
}
@@ -80,39 +112,55 @@ function enforceReactNativeVersionConsistency({Yarn}) {
80
112
}
81
113
82
114
/**
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.
85
118
* @param {Context } context
86
119
*/
87
120
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 ;
94
124
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 ;
100
146
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
+ }
108
154
}
109
155
}
110
156
}
111
157
112
158
module . exports = defineConfig ( {
113
159
constraints : async ctx => {
114
- expectReactNativePeerDependency ( ctx ) ;
160
+ enforcePrivateReactNativeScopedPackages ( ctx ) ;
115
161
enforceReactNativeVersionConsistency ( ctx ) ;
162
+ enforceReactNativeDependencyConsistency ( ctx ) ;
116
163
enforceReactNativeMacosVersionConsistency ( ctx ) ;
164
+ enforceReactNativeMacOSDependencyConsistency ( ctx ) ;
117
165
} ,
118
166
} ) ;
0 commit comments