Skip to content

Commit 074e3f0

Browse files
cortinicofacebook-github-bot
authored andcommitted
RNGP - Introduce the BundleAndHermesCTask
Summary: This is part of a series of tasks to make the React Native Gradle Plugin (RNGP) variant-aware. Here I'm creating a new task BundleAndHermesCTask that is variant-aware. Historically we had problems with the Bundle and the Hermes task being separated and overriding their own output. Consolidating those two steps in a single one will make it easier to support seaprate variants. I'm going to use this task in a subsequent diff. Changelog: [Internal] [Changed] - RNGP - Introduce the BundleAndHermesCTask Reviewed By: cipolleschi Differential Revision: D40633108 fbshipit-source-id: 89f6d32ef219626ed5d4c5a0b8ac804c6704b2d6
1 parent 9a87db2 commit 074e3f0

File tree

4 files changed

+510
-1
lines changed

4 files changed

+510
-1
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.tasks
9+
10+
import com.facebook.react.utils.detectOSAwareHermesCommand
11+
import com.facebook.react.utils.moveTo
12+
import com.facebook.react.utils.windowsAwareCommandLine
13+
import java.io.File
14+
import org.gradle.api.DefaultTask
15+
import org.gradle.api.file.ConfigurableFileTree
16+
import org.gradle.api.file.DirectoryProperty
17+
import org.gradle.api.file.RegularFileProperty
18+
import org.gradle.api.provider.ListProperty
19+
import org.gradle.api.provider.Property
20+
import org.gradle.api.tasks.*
21+
22+
abstract class BundleHermesCTask : DefaultTask() {
23+
24+
init {
25+
group = "react"
26+
}
27+
28+
@get:Internal abstract val root: DirectoryProperty
29+
30+
@get:InputFiles
31+
val sources: ConfigurableFileTree =
32+
project.fileTree(root) {
33+
it.include("**/*.js")
34+
it.include("**/*.jsx")
35+
it.include("**/*.ts")
36+
it.include("**/*.tsx")
37+
it.exclude("**/android/**/*")
38+
it.exclude("**/ios/**/*")
39+
it.exclude("**/build/**/*")
40+
it.exclude("**/node_modules/**/*")
41+
}
42+
43+
@get:Input abstract val nodeExecutableAndArgs: ListProperty<String>
44+
45+
@get:Input abstract val cliPath: Property<String>
46+
47+
@get:Input abstract val composeSourceMapsPath: Property<String>
48+
49+
@get:Input abstract val bundleCommand: Property<String>
50+
51+
@get:InputFile abstract val entryFile: RegularFileProperty
52+
53+
@get:InputFile @get:Optional abstract val bundleConfig: RegularFileProperty
54+
55+
@get:Input abstract val bundleAssetName: Property<String>
56+
57+
@get:Input abstract val minifyEnabled: Property<Boolean>
58+
59+
@get:Input abstract val hermesEnabled: Property<Boolean>
60+
61+
@get:Input abstract val devEnabled: Property<Boolean>
62+
63+
@get:Input abstract val extraPackagerArgs: ListProperty<String>
64+
65+
@get:Input abstract val hermesCommand: Property<String>
66+
67+
@get:Input abstract val hermesFlags: ListProperty<String>
68+
69+
@get:OutputDirectory abstract val jsBundleDir: DirectoryProperty
70+
71+
@get:OutputDirectory abstract val resourcesDir: DirectoryProperty
72+
73+
@get:OutputDirectory abstract val jsIntermediateSourceMapsDir: RegularFileProperty
74+
75+
@get:OutputDirectory abstract val jsSourceMapsDir: DirectoryProperty
76+
77+
@TaskAction
78+
fun run() {
79+
jsBundleDir.get().asFile.mkdirs()
80+
resourcesDir.get().asFile.mkdirs()
81+
jsIntermediateSourceMapsDir.get().asFile.mkdirs()
82+
jsSourceMapsDir.get().asFile.mkdirs()
83+
val bundleAssetFilename = bundleAssetName.get()
84+
85+
val bundleFile = File(jsBundleDir.get().asFile, bundleAssetFilename)
86+
val packagerSourceMap = resolvePackagerSourceMapFile(bundleAssetFilename)
87+
88+
val bundleCommand = getBundleCommand(bundleFile, packagerSourceMap)
89+
runCommand(bundleCommand)
90+
91+
if (hermesEnabled.get()) {
92+
val detectedHermesCommand = detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get())
93+
val bytecodeTempFile = File("${bundleFile}.hbc")
94+
val outputSourceMap = resolveOutputSourceMap(bundleAssetFilename)
95+
val compilerSourceMap = resolveCompilerSourceMap(bundleAssetFilename)
96+
97+
val hermesCommand = getHermescCommand(detectedHermesCommand, bundleFile, packagerSourceMap)
98+
runCommand(hermesCommand)
99+
bytecodeTempFile.moveTo(bundleFile)
100+
101+
if (hermesFlags.get().contains("-output-source-map")) {
102+
val hermesTempSourceMapFile = File("$bytecodeTempFile.map")
103+
hermesTempSourceMapFile.moveTo(compilerSourceMap)
104+
val composeSourceMapsCommand =
105+
getComposeSourceMapsCommand(packagerSourceMap, compilerSourceMap, outputSourceMap)
106+
runCommand(composeSourceMapsCommand)
107+
}
108+
}
109+
}
110+
111+
internal fun resolvePackagerSourceMapFile(bundleAssetName: String) =
112+
if (hermesEnabled.get()) {
113+
File(jsIntermediateSourceMapsDir.get().asFile, "$bundleAssetName.packager.map")
114+
} else {
115+
resolveOutputSourceMap(bundleAssetName)
116+
}
117+
118+
internal fun resolveOutputSourceMap(bundleAssetName: String) =
119+
File(jsSourceMapsDir.get().asFile, "$bundleAssetName.map")
120+
121+
internal fun resolveCompilerSourceMap(bundleAssetName: String) =
122+
File(jsIntermediateSourceMapsDir.get().asFile, "$bundleAssetName.compiler.map")
123+
124+
private fun runCommand(command: List<Any>) {
125+
project.exec {
126+
it.workingDir(root.get().asFile)
127+
it.commandLine(command)
128+
}
129+
}
130+
131+
internal fun getBundleCommand(bundleFile: File, sourceMapFile: File): List<Any> =
132+
windowsAwareCommandLine(
133+
buildList {
134+
addAll(nodeExecutableAndArgs.get())
135+
add(cliPath.get())
136+
add(bundleCommand.get())
137+
add("--platform")
138+
add("android")
139+
add("--dev")
140+
add(devEnabled.get().toString())
141+
add("--reset-cache")
142+
add("--entry-file")
143+
add(entryFile.get().asFile.toString())
144+
add("--bundle-output")
145+
add(bundleFile.toString())
146+
add("--assets-dest")
147+
add(resourcesDir.get().asFile.toString())
148+
add("--sourcemap-output")
149+
add(sourceMapFile.toString())
150+
if (bundleConfig.isPresent) {
151+
add("--config")
152+
add(bundleConfig.get().asFile.absolutePath)
153+
}
154+
add("--minify")
155+
add(minifyEnabled.get().toString())
156+
addAll(extraPackagerArgs.get())
157+
add("--verbose")
158+
})
159+
160+
internal fun getHermescCommand(
161+
hermesCommand: String,
162+
bundleFile: File,
163+
outputFile: File
164+
): List<Any> =
165+
windowsAwareCommandLine(
166+
hermesCommand,
167+
"-emit-binary",
168+
"-out",
169+
outputFile.absolutePath,
170+
bundleFile.absolutePath,
171+
*hermesFlags.get().toTypedArray())
172+
173+
internal fun getComposeSourceMapsCommand(
174+
packagerSourceMap: File,
175+
compilerSourceMap: File,
176+
outputSourceMap: File
177+
): List<Any> =
178+
windowsAwareCommandLine(
179+
*nodeExecutableAndArgs.get().toTypedArray(),
180+
composeSourceMapsPath.get(),
181+
packagerSourceMap.toString(),
182+
compilerSourceMap.toString(),
183+
"-o",
184+
outputSourceMap.toString())
185+
}

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/TaskUtils.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
package com.facebook.react.utils
99

1010
internal fun windowsAwareCommandLine(vararg args: Any): List<Any> =
11+
windowsAwareCommandLine(args.toList())
12+
13+
internal fun windowsAwareCommandLine(args: List<Any>): List<Any> =
1114
if (Os.isWindows()) {
1215
listOf("cmd", "/c") + args
1316
} else {
14-
args.toList()
17+
args
1518
}
1619

1720
internal fun windowsAwareBashCommandLine(

0 commit comments

Comments
 (0)