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 302c1d83a7b412..d485aa69bdf424 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 @@ -67,7 +67,18 @@ private fun detectCliPath( ): String { // 1. preconfigured path if (preconfiguredCliPath != null) { - return File(projectDir, preconfiguredCliPath).toString() + val preconfiguredCliJsAbsolute = File(preconfiguredCliPath) + if (preconfiguredCliJsAbsolute.exists()) { + return preconfiguredCliJsAbsolute.absolutePath + } + val preconfiguredCliJsRelativeToReactRoot = File(reactRoot, preconfiguredCliPath) + if (preconfiguredCliJsRelativeToReactRoot.exists()) { + return preconfiguredCliJsRelativeToReactRoot.absolutePath + } + val preconfiguredCliJsRelativeToProject = File(projectDir, preconfiguredCliPath) + if (preconfiguredCliJsRelativeToProject.exists()) { + return preconfiguredCliJsRelativeToProject.absolutePath + } } // 2. node module path @@ -81,7 +92,10 @@ private fun detectCliPath( val nodeProcessOutput = nodeProcess.inputStream.use { it.bufferedReader().readText().trim() } if (nodeProcessOutput.isNotEmpty()) { - return nodeProcessOutput + val nodeModuleCliJs = File(nodeProcessOutput) + if (nodeModuleCliJs.exists()) { + return nodeModuleCliJs.absolutePath + } } // 3. cli.js in the root folder diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt index debba45740b3b0..0c9d3669079059 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt @@ -52,10 +52,47 @@ class PathUtilsTest { } @Test - fun detectedCliPath_withCliPathFromExtension() { + fun detectedCliPath_withCliPathFromExtensionAbsolute() { val project = ProjectBuilder.builder().build() val extension = TestReactExtension(project) - val expected = File(project.projectDir, "fake-cli.sh") + val expected = + File(project.projectDir, "abs/fake-cli.sh").apply { + parentFile.mkdirs() + writeText("") + } + extension.cliPath.set(project.projectDir + "/abs/fake-cli.sh") + + val actual = detectedCliPath(project.projectDir, extension) + + assertEquals(expected.toString(), actual) + } + + @Test + fun detectedCliPath_withCliPathFromExtensionInReactFolder() { + val project = ProjectBuilder.builder().build() + val extension = TestReactExtension(project) + val expected = + File(project.projectDir, "/react-root/fake-cli.sh").apply { + parentFile.mkdirs() + writeText("") + } + extension.cliPath.set("fake-cli.sh") + extension.reactRoot.set(project.projectDir + "/react-root") + + val actual = detectedCliPath(project.projectDir, extension) + + assertEquals(expected.toString(), actual) + } + + @Test + fun detectedCliPath_withCliPathFromExtensionInProjectFolder() { + val project = ProjectBuilder.builder().build() + val extension = TestReactExtension(project) + val expected = + File(project.projectDir, "fake-cli.sh").apply { + parentFile.mkdirs() + writeText("") + } extension.cliPath.set("fake-cli.sh") val actual = detectedCliPath(project.projectDir, extension) diff --git a/react.gradle b/react.gradle index 047560a998fc57..0283a18e73bb7a 100644 --- a/react.gradle +++ b/react.gradle @@ -22,20 +22,6 @@ def detectEntryFile(config) { return "index.js"; } -/** - * Detects CLI location in a similar fashion to the React Native CLI - */ -def detectCliPath(config) { - if (config.cliPath) { - return "${projectDir}/${config.cliPath}" - } - if (new File("${projectDir}/../../node_modules/react-native/cli.js").exists()) { - return "${projectDir}/../../node_modules/react-native/cli.js" - } - throw new Exception("Couldn't determine CLI location. " + - "Please set `project.ext.react.cliPath` to the path of the react-native cli.js file. This file typically resides in `node_modules/react-native/cli.js`"); -} - def composeSourceMapsPath = config.composeSourceMapsPath ?: "node_modules/react-native/scripts/compose-source-maps.js" def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" def entryFile = detectEntryFile(config) @@ -46,6 +32,43 @@ def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : def enableVmCleanup = config.enableVmCleanup == null ? true : config.enableVmCleanup def hermesCommand = config.hermesCommand ?: "../../node_modules/hermes-engine/%OS-BIN%/hermesc" +/** + * Detects CLI location in a similar fashion to the React Native CLI + */ +def detectCliPath(config, reactRoot) { + // 1. preconfigured path + if (config.cliPath) { + def cliJsAbsolute = new File(config.cliPath) + if (cliJsAbsolute.exists()) { + return cliJsAbsolute.getAbsolutePath() + } + def cliJsRelativeToRoot = new File("${rootDir}/${config.cliPath}") + if (cliJsRelativeToRoot.exists()) { + return cliJsRelativeToRoot.getAbsolutePath() + } + def cliJsRelativeToProject = new File("${projectDir}/${config.cliPath}") + if (cliJsRelativeToProject.exists()) { + return cliJsRelativeToProject.getAbsolutePath() + } + } + + // 2. node module path + def cliJsFromNode = new File(["node", "--print", "require.resolve('react-native/cli').bin"].execute(null, rootDir).text.trim()) + if (cliJsFromNode.exists()) { + return cliJsFromNode.getAbsolutePath() + } + + // 3. cli.js in the root folder + def rootCliJs = new File(reactRoot, "node_modules/react-native/cli.js") + if (rootCliJs.exists()) { + return rootCliJs.getAbsolutePath() + } + + throw new Exception("Couldn't determine CLI location. " + + "Please set `project.ext.react.cliPath` to the path of the react-native cli.js file. " + + "This file typically resides in `node_modules/react-native/cli.js`"); +} + def reactNativeDevServerPort() { def value = project.getProperties().get("reactNativeDevServerPort") return value != null ? value : "8081" @@ -164,7 +187,7 @@ afterEvaluate { // Additional node and packager commandline arguments def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"] - def cliPath = detectCliPath(config) + def cliPath = detectCliPath(config, reactRoot) def execCommand = []