Skip to content

Commit

Permalink
Export and test detectedHermesCommand function from `ReactAppExtens…
Browse files Browse the repository at this point in the history
…ion`

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
  • Loading branch information
cortinico authored and facebook-github-bot committed Sep 13, 2021
1 parent 801909b commit d246946
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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.")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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.")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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%"))
}
}

0 comments on commit d246946

Please sign in to comment.