diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactAppExtension.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactAppExtension.kt index 20c948690d..4bb65954da 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactAppExtension.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactAppExtension.kt @@ -9,7 +9,6 @@ package com.facebook.react import com.android.build.gradle.api.BaseVariant import java.io.File -import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.Project open class ReactAppExtension(private val project: Project) { @@ -34,28 +33,4 @@ open class ReactAppExtension(private val project: Project) { var hermesFlagsRelease: List = listOf("-O", "-output-source-map") var resourcesDir: Map = emptyMap() var jsBundleDir: Map = emptyMap() - - internal val osAwareHermesCommand: String - get() = getOSAwareHermesCommand(hermesCommand) - - // Make sure not to inspect the Hermes config unless we need it, - // to avoid breaking any JSC-only setups. - private fun getOSAwareHermesCommand(hermesCommand: String): String { - // If the project specifies a Hermes command, don't second guess it. - if (!hermesCommand.contains("%OS-BIN%")) { - return hermesCommand - } - - // Execution on Windows fails with / as separator - return hermesCommand.replace("%OS-BIN%", getHermesOSBin()).replace('/', File.separatorChar) - } - - private fun getHermesOSBin(): String { - if (Os.isFamily(Os.FAMILY_WINDOWS)) return "win64-bin" - if (Os.isFamily(Os.FAMILY_MAC)) return "osx-bin" - if (Os.isOs(null, "linux", "amd64", null)) return "linux64-bin" - error( - "OS not recognized. Please set project.react.hermesCommand " + - "to the path of a working Hermes compiler.") - } } diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt index b4afb4ad9a..59ca66de38 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt @@ -15,6 +15,7 @@ import com.facebook.react.tasks.BundleJsAndAssetsTask import com.facebook.react.tasks.HermesBinaryTask import com.facebook.react.utils.detectedCliPath import com.facebook.react.utils.detectedEntryFile +import com.facebook.react.utils.detectedHermesCommand import java.io.File import org.gradle.api.Project import org.gradle.api.tasks.Copy @@ -94,7 +95,7 @@ internal fun Project.configureReactTasks(variant: BaseVariant, config: ReactAppE it.description = "bundle hermes resources for $targetName" it.reactRoot = config.reactRoot - it.hermesCommand = config.osAwareHermesCommand + it.hermesCommand = detectedHermesCommand(config) it.hermesFlags = if (isRelease) config.hermesFlagsRelease else config.hermesFlagsDebug it.jsBundleFile = jsBundleFile it.composeSourceMapsCommand = nodeExecutableAndArgs + config.composeSourceMapsPath diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt index 0cfa2bd0d0..3f5e23b351 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt @@ -9,6 +9,7 @@ package com.facebook.react.utils import com.facebook.react.ReactAppExtension import java.io.File +import org.apache.tools.ant.taskdefs.condition.Os /** * Computes the entry file for React Native. The Algo follows this order: @@ -36,6 +37,16 @@ internal fun detectedCliPath( detectCliPath( projectDir = projectDir, reactRoot = config.reactRoot, preconfuredCliPath = config.cliPath) +/** + * Computes the `hermesc` command location. The Algo follows this order: + * 1. The path provided by the `hermesCommand` config in the `reactApp` Gradle extension + * 2. The file located in `node_modules/hermes-engine/%OS-BIN%/hermesc` where `%OS-BIN%` is + * substituted with the correct OS arch. + * 3. Fails otherwise + */ +internal fun detectedHermesCommand(config: ReactAppExtension): String = + detectOSAwareHermesCommand(config.hermesCommand) + private fun detectEntryFile(entryFile: File?, reactRoot: File): File = when { System.getenv("ENTRY_FILE") != null -> File(System.getenv("ENTRY_FILE")) @@ -72,3 +83,24 @@ private fun detectCliPath(projectDir: File, reactRoot: File, preconfuredCliPath: "Couldn't determine CLI location. " + "Please set `project.react.cliPath` to the path of the react-native cli.js") } + +// Make sure not to inspect the Hermes config unless we need it, +// to avoid breaking any JSC-only setups. +private fun detectOSAwareHermesCommand(hermesCommand: String): String { + // If the project specifies a Hermes command, don't second guess it. + if (!hermesCommand.contains("%OS-BIN%")) { + return hermesCommand + } + + // Execution on Windows fails with / as separator + return hermesCommand.replace("%OS-BIN%", getHermesOSBin()).replace('/', File.separatorChar) +} + +private fun getHermesOSBin(): String { + if (Os.isFamily(Os.FAMILY_WINDOWS)) return "win64-bin" + if (Os.isFamily(Os.FAMILY_MAC)) return "osx-bin" + if (Os.isOs(null, "linux", "amd64", null)) return "linux64-bin" + error( + "OS not recognized. Please set project.react.hermesCommand " + + "to the path of a working Hermes compiler.") +} diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/PathUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/PathUtilsTest.kt index a0c7734663..62f1a672e0 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/PathUtilsTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/PathUtilsTest.kt @@ -10,9 +10,10 @@ package com.facebook.react.tests import com.facebook.react.ReactAppExtension import com.facebook.react.utils.detectedCliPath import com.facebook.react.utils.detectedEntryFile +import com.facebook.react.utils.detectedHermesCommand import java.io.File import org.gradle.testfixtures.ProjectBuilder -import org.junit.Assert.assertEquals +import org.junit.Assert.* import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder @@ -88,4 +89,26 @@ class PathUtilsTest { detectedCliPath(project.projectDir, extension) } + + @Test + fun detectedHermesCommand_withPathFromExtension() { + val extension = ReactAppExtension(ProjectBuilder.builder().build()) + val expected = tempFolder.newFile("hermesc") + extension.hermesCommand = expected.toString() + + val actual = detectedHermesCommand(extension) + + assertEquals(expected.toString(), actual) + } + + @Test + fun detectedHermesCommand_withOSSpecificBin() { + val extension = ReactAppExtension(ProjectBuilder.builder().build()) + + val actual = detectedHermesCommand(extension) + + assertTrue(actual.startsWith("node_modules/hermes-engine/")) + assertTrue(actual.endsWith("hermesc")) + assertFalse(actual.contains("%OS-BIN%")) + } }