Export and test `detectedHermesCommand` function from `ReactAppExtension`

Summary:
Another diff to remove code from `ReactAppExtension` to a Util file and test it.

Changelog:
[Internal] [Changed] - Export and test `detectedHermesCommand` function from `ReactAppExtension`

Reviewed By: feedthejim

Differential Revision: D30866510

fbshipit-source-id: 0023a063793d669ee4b2190679ca7fbd01e9a3fc
This commit is contained in:
Nicola Corti 2021-09-13 03:18:24 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 801909be5b
Коммит d246946fb8
4 изменённых файлов: 58 добавлений и 27 удалений

Просмотреть файл

@ -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<String> = listOf("-O", "-output-source-map")
var resourcesDir: Map<String, File> = emptyMap()
var jsBundleDir: Map<String, File> = 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.")
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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.")
}

Просмотреть файл

@ -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%"))
}
}