@@ -9,6 +9,7 @@ package com.facebook.react
9
9
10
10
import com.android.build.api.variant.AndroidComponentsExtension
11
11
import com.android.build.gradle.internal.tasks.factory.dependsOn
12
+ import com.facebook.react.internal.PrivateReactExtension
12
13
import com.facebook.react.tasks.BuildCodegenCLITask
13
14
import com.facebook.react.tasks.GenerateCodegenArtifactsTask
14
15
import com.facebook.react.tasks.GenerateCodegenSchemaTask
@@ -34,8 +35,22 @@ class ReactPlugin : Plugin<Project> {
34
35
checkJvmVersion(project)
35
36
val extension = project.extensions.create(" react" , ReactExtension ::class .java, project)
36
37
38
+ // We register a private extension on the rootProject so that project wide configs
39
+ // like codegen config can be propagated from app project to libraries.
40
+ val rootExtension =
41
+ project.rootProject.extensions.findByType(PrivateReactExtension ::class .java)
42
+ ? : project.rootProject.extensions.create(
43
+ " privateReact" , PrivateReactExtension ::class .java, project)
44
+
37
45
// App Only Configuration
38
46
project.pluginManager.withPlugin(" com.android.application" ) {
47
+ // We wire the root extension with the values coming from the app (either user populated or
48
+ // defaults).
49
+ rootExtension.root.set(extension.root)
50
+ rootExtension.reactNativeDir.set(extension.reactNativeDir)
51
+ rootExtension.codegenDir.set(extension.codegenDir)
52
+ rootExtension.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
53
+
39
54
project.afterEvaluate {
40
55
val reactNativeDir = extension.reactNativeDir.get().asFile
41
56
val propertiesFile = File (reactNativeDir, " ReactAndroid/gradle.properties" )
@@ -54,12 +69,12 @@ class ReactPlugin : Plugin<Project> {
54
69
project.configureReactTasks(variant = variant, config = extension)
55
70
}
56
71
}
57
- configureCodegen(project, extension, isLibrary = false )
72
+ configureCodegen(project, extension, rootExtension, isLibrary = false )
58
73
}
59
74
60
75
// Library Only Configuration
61
76
project.pluginManager.withPlugin(" com.android.library" ) {
62
- configureCodegen(project, extension, isLibrary = true )
77
+ configureCodegen(project, extension, rootExtension, isLibrary = true )
63
78
}
64
79
}
65
80
@@ -82,34 +97,36 @@ class ReactPlugin : Plugin<Project> {
82
97
}
83
98
}
84
99
85
- /* *
86
- * A plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for more
87
- * information: https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html
88
- */
100
+ /* * This function sets up `react-native-codegen` in our Gradle plugin. */
89
101
@Suppress(" UnstableApiUsage" )
90
- private fun configureCodegen (project : Project , extension : ReactExtension , isLibrary : Boolean ) {
102
+ private fun configureCodegen (
103
+ project : Project ,
104
+ localExtension : ReactExtension ,
105
+ rootExtension : PrivateReactExtension ,
106
+ isLibrary : Boolean
107
+ ) {
91
108
// First, we set up the output dir for the codegen.
92
109
val generatedSrcDir = File (project.buildDir, " generated/source/codegen" )
93
110
94
111
// We specify the default value (convention) for jsRootDir.
95
112
// It's the root folder for apps (so ../../ from the Gradle project)
96
113
// and the package folder for library (so ../ from the Gradle project)
97
114
if (isLibrary) {
98
- extension .jsRootDir.convention(project.layout.projectDirectory.dir(" ../" ))
115
+ localExtension .jsRootDir.convention(project.layout.projectDirectory.dir(" ../" ))
99
116
} else {
100
- extension .jsRootDir.convention(extension .root)
117
+ localExtension .jsRootDir.convention(localExtension .root)
101
118
}
102
119
103
120
val buildCodegenTask =
104
121
project.tasks.register(" buildCodegenCLI" , BuildCodegenCLITask ::class .java) {
105
- it.codegenDir.set(extension .codegenDir)
122
+ it.codegenDir.set(rootExtension .codegenDir)
106
123
val bashWindowsHome = project.findProperty(" REACT_WINDOWS_BASH" ) as String?
107
124
it.bashWindowsHome.set(bashWindowsHome)
108
125
109
126
// Please note that appNeedsCodegen is triggering a read of the package.json at
110
127
// configuration time as we need to feed the onlyIf condition of this task.
111
128
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
112
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension )
129
+ val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root )
113
130
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
114
131
}
115
132
@@ -118,23 +135,24 @@ class ReactPlugin : Plugin<Project> {
118
135
project.tasks.register(
119
136
" generateCodegenSchemaFromJavaScript" , GenerateCodegenSchemaTask ::class .java) { it ->
120
137
it.dependsOn(buildCodegenTask)
121
- it.nodeExecutableAndArgs.set(extension .nodeExecutableAndArgs)
122
- it.codegenDir.set(extension .codegenDir)
138
+ it.nodeExecutableAndArgs.set(rootExtension .nodeExecutableAndArgs)
139
+ it.codegenDir.set(rootExtension .codegenDir)
123
140
it.generatedSrcDir.set(generatedSrcDir)
124
141
125
142
// We're reading the package.json at configuration time to properly feed
126
143
// the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
127
144
// parsePackageJson should be invoked inside this lambda.
128
- val packageJson = findPackageJsonFile(project, extension )
145
+ val packageJson = findPackageJsonFile(project, rootExtension.root )
129
146
val parsedPackageJson = packageJson?.let { JsonUtils .fromCodegenJson(it) }
130
147
131
148
val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
132
149
if (jsSrcsDirInPackageJson != null ) {
133
150
it.jsRootDir.set(File (packageJson.parentFile, jsSrcsDirInPackageJson))
134
151
} else {
135
- it.jsRootDir.set(extension .jsRootDir)
152
+ it.jsRootDir.set(localExtension .jsRootDir)
136
153
}
137
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
154
+ val needsCodegenFromPackageJson =
155
+ project.needsCodegenFromPackageJson(rootExtension.root)
138
156
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
139
157
}
140
158
@@ -143,17 +161,18 @@ class ReactPlugin : Plugin<Project> {
143
161
project.tasks.register(
144
162
" generateCodegenArtifactsFromSchema" , GenerateCodegenArtifactsTask ::class .java) {
145
163
it.dependsOn(generateCodegenSchemaTask)
146
- it.reactNativeDir.set(extension .reactNativeDir)
147
- it.nodeExecutableAndArgs.set(extension .nodeExecutableAndArgs)
164
+ it.reactNativeDir.set(rootExtension .reactNativeDir)
165
+ it.nodeExecutableAndArgs.set(rootExtension .nodeExecutableAndArgs)
148
166
it.generatedSrcDir.set(generatedSrcDir)
149
- it.packageJsonFile.set(findPackageJsonFile(project, extension ))
150
- it.codegenJavaPackageName.set(extension .codegenJavaPackageName)
151
- it.libraryName.set(extension .libraryName)
167
+ it.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root ))
168
+ it.codegenJavaPackageName.set(localExtension .codegenJavaPackageName)
169
+ it.libraryName.set(localExtension .libraryName)
152
170
153
171
// Please note that appNeedsCodegen is triggering a read of the package.json at
154
172
// configuration time as we need to feed the onlyIf condition of this task.
155
173
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
156
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
174
+ val needsCodegenFromPackageJson =
175
+ project.needsCodegenFromPackageJson(rootExtension.root)
157
176
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
158
177
}
159
178
0 commit comments