diff --git a/packages/react-native-session-replay/android/build.gradle b/packages/react-native-session-replay/android/build.gradle index 8b74366d1..7d528163d 100644 --- a/packages/react-native-session-replay/android/build.gradle +++ b/packages/react-native-session-replay/android/build.gradle @@ -1,3 +1,4 @@ +import java.nio.file.Paths import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { @@ -35,6 +36,29 @@ apply plugin: 'kotlin-android' apply plugin: 'org.jlleitschuh.gradle.ktlint' apply plugin: "io.gitlab.arturbosch.detekt" +/** + * Finds the path of the installed npm package with the given name using Node's + * module resolution algorithm, which searches "node_modules" directories up to + * the file system root. + * This enables us to handle monorepos without requiring the node executable. + * + * The search begins at the given base directory (a File object). The returned + * path is a string. + */ +static def findNodeModulePath(baseDir, packageName) { + def basePath = baseDir.toPath().normalize() + // Node's module resolution algorithm searches up to the root directory, + // after which the base path will be null + while (basePath) { + def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName) + if (candidatePath.toFile().exists()) { + return candidatePath.toString() + } + basePath = basePath.getParent() + } + return null +} + def resolveReactNativeDirectory() { def reactNativeLocation = rootProject.hasProperty("reactNativeDir") ? rootProject.getProperty("reactNativeDir") : null @@ -42,24 +66,10 @@ def resolveReactNativeDirectory() { return file(reactNativeLocation) } - try { - // Resolve React Native location with Node - // This will make sure that we get installation location correctly in monorepos - def reactNativePackageJsonPathStdout = new ByteArrayOutputStream() + def reactNativePath = findNodeModulePath(projectDir, "react-native") - exec { - commandLine("node", "-p", "require.resolve('react-native/package.json')") - ignoreExitValue true - standardOutput = reactNativePackageJsonPathStdout - } - - def reactNativeFromProjectNodeModules = file(reactNativePackageJsonPathStdout.toString().trim()).getParentFile(); - - if (reactNativeFromProjectNodeModules.exists()) { - return reactNativeFromProjectNodeModules - } - } catch (e) { - // Ignore + if (reactNativePath != null) { + return file(reactNativePath) } throw new Exception(