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 eb965bc0602e6e..1f620aabb35b8f 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 @@ -68,7 +68,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 @@ -82,7 +93,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 c87d5fa3c6e676..4ce8b1d2129c3d 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,44 @@ 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 0ace9be826f805..ae65cc4b338471 100644 --- a/react.gradle +++ b/react.gradle @@ -21,20 +21,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) @@ -45,6 +31,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" @@ -150,7 +173,7 @@ afterEvaluate { // Additional node and packager commandline arguments def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"] - def cliPath = detectCliPath(config) + def cliPath = detectCliPath(config, reactRoot) def execCommand = []