[Gradle][tests] Install CocoaPods to a temp dir instead of HOME

This commit is contained in:
Ilya Matveev
2021-06-10 16:20:54 +07:00
committed by TeamCityServer
parent aa9ff3d6bb
commit 53a4187427
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Compan
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SETUP_BUILD_TASK_NAME import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SETUP_BUILD_TASK_NAME
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SPEC_TASK_NAME import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SPEC_TASK_NAME
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
import org.jetbrains.kotlin.gradle.util.createTempDir
import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.util.modify
import org.jetbrains.kotlin.gradle.util.runProcess import org.jetbrains.kotlin.gradle.util.runProcess
import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.HostManager
@@ -26,6 +27,7 @@ import org.junit.Before
import org.junit.BeforeClass import org.junit.BeforeClass
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.io.IOException
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -50,7 +52,7 @@ class CocoaPodsIT : BaseGradleIT() {
private val gradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT private val gradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT
override fun defaultBuildOptions(): BuildOptions = override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(customEnvironmentVariables = mapOf("PATH" to getPathEnv())) super.defaultBuildOptions().copy(customEnvironmentVariables = getPathEnvs())
val PODFILE_IMPORT_DIRECTIVE_PLACEHOLDER = "<import_mode_directive>" val PODFILE_IMPORT_DIRECTIVE_PLACEHOLDER = "<import_mode_directive>"
@@ -770,8 +772,7 @@ class CocoaPodsIT : BaseGradleIT() {
hooks.addHook { hooks.addHook {
// Check that a built universal framework includes both device and simulator architectures. // Check that a built universal framework includes both device and simulator architectures.
val framework = fileInWorkingDir("build/cocoapods/framework/cocoapods.framework/cocoapods") val framework = fileInWorkingDir("build/cocoapods/framework/cocoapods.framework/cocoapods")
val env = mapOf("PATH" to getPathEnv()) with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = getPathEnvs())) {
with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = env)) {
assertTrue(isSuccessful) assertTrue(isSuccessful)
assertTrue(output.contains("\\(for architecture x86_64\\):\\s+current ar archive".toRegex())) assertTrue(output.contains("\\(for architecture x86_64\\):\\s+current ar archive".toRegex()))
assertTrue(output.contains("\\(for architecture arm64\\):\\s+current ar archive".toRegex())) assertTrue(output.contains("\\(for architecture arm64\\):\\s+current ar archive".toRegex()))
@@ -1220,7 +1221,7 @@ class CocoaPodsIT : BaseGradleIT() {
) { ) {
val process = ProcessBuilder(command, *args).apply { val process = ProcessBuilder(command, *args).apply {
directory(workingDir) directory(workingDir)
environment()["PATH"] = getPathEnv() environment().putAll(getPathEnvs())
if (inheritIO) { if (inheritIO) {
inheritIO() inheritIO()
} }
@@ -1405,8 +1406,7 @@ class CocoaPodsIT : BaseGradleIT() {
if (cocoapodsInstallationRequired) { if (cocoapodsInstallationRequired) {
if (cocoapodsInstallationAllowed) { if (cocoapodsInstallationAllowed) {
WorkaroundForXcode12_3.apply() WorkaroundForXcode12_3.apply()
gem("install", "--user-install", "cocoapods", "cocoapods-generate") gem("install", "--install-dir", cocoapodsInstallationRoot.absolutePath, "cocoapods", "cocoapods-generate")
cocoapodsInstallationPath = File(getGemUserInstallationPath()).resolve("bin")
} else { } else {
fail( fail(
""" """
@@ -1422,65 +1422,52 @@ class CocoaPodsIT : BaseGradleIT() {
@AfterClass @AfterClass
@JvmStatic @JvmStatic
fun uninstallPodGen() { fun disposeWorkarounds() {
// Do not remove CocoaPods if we didn't install it.
if (cocoapodsInstallationRequired && cocoapodsInstallationAllowed) { if (cocoapodsInstallationRequired && cocoapodsInstallationAllowed) {
val packagesToRemove = gem("list", "--no-versions").lineSequence().filter { WorkaroundForXcode12_3.dispose()
it.startsWith("cocoapods")
}.toList()
try {
gem("uninstall", "--user-install", "-x", *packagesToRemove.toTypedArray())
} finally {
WorkaroundForXcode12_3.dispose()
}
} }
} }
private val cocoapodsInstallationRequired: Boolean = !isCocoapodsInstalled() private val cocoapodsInstallationRequired: Boolean by lazy {
!isCocoapodsInstalled() || !isPodGenInstalled()
}
private val cocoapodsInstallationAllowed: Boolean = System.getProperty("installCocoapods").toBoolean() private val cocoapodsInstallationAllowed: Boolean = System.getProperty("installCocoapods").toBoolean()
private var cocoapodsInstallationPath: File? = null private val cocoapodsInstallationRoot: File by lazy { createTempDir("cocoapods") }
private fun getPathEnv(): String { private fun getPathEnvs(): Map<String, String> {
val oldPath = System.getenv("PATH") val path = cocoapodsInstallationRoot.resolve("bin").absolutePath + File.pathSeparator + System.getenv("PATH")
return cocoapodsInstallationPath?.let { val gemPath = System.getenv("GEM_PATH")?.let {
it.absolutePath + File.pathSeparator + oldPath cocoapodsInstallationRoot.absolutePath + File.pathSeparator + it
} ?: oldPath } ?: cocoapodsInstallationRoot.absolutePath
return mapOf("PATH" to path, "GEM_PATH" to gemPath)
} }
private fun isCocoapodsInstalled(): Boolean { private fun isCocoapodsInstalled(): Boolean {
val installed = gem("list", "--no-versions").lines() // Do not use 'gem list' because the gem may be installed but PATH may miss its executables.
return "cocoapods-generate" in installed && "cocoapods" in installed // Try to access the pod executable directly instead
return try {
val result = runProcess(
listOf("pod", "--version"),
File("."),
environmentVariables = getPathEnvs()
)
result.isSuccessful
} catch (e: IOException) {
false
}
} }
private fun getGemUserInstallationPath(): String { private fun isPodGenInstalled(): Boolean {
val installationDirLine = gem("environment").lineSequence().first { val installed = gem("list", "--no-versions").lines()
it.contains("USER INSTALLATION DIRECTORY:") return "cocoapods-generate" in installed
}
return installationDirLine.substringAfter("USER INSTALLATION DIRECTORY:").trim()
} }
private fun gem(vararg args: String): String { private fun gem(vararg args: String): String {
val process = ProcessBuilder("gem", *args).start() val result = runProcess(listOf("gem", *args), File("."))
val finished = process.waitFor(30, TimeUnit.MINUTES) check(result.isSuccessful) {
val output = process.inputStream.use { it.reader().readText() } "Process 'gem ${args.joinToString(separator = " ")}' exited with error code ${result.exitCode}. See log for details."
check(finished && process.exitValue() == 0) {
if (!finished) {
process.destroyForcibly()
}
val argsString = args.joinToString(separator = " ")
val errors = process.errorStream.use { it.reader().readText() }
println("'gem $argsString' stdout:\n$errors")
println("'gem $argsString' stderr:\n$output")
if (finished) {
"Process 'gem $argsString' exited with error code ${process.exitValue()}. See log for details."
} else {
"Process 'gem $argsString ' killed by timeout. See log for details"
}
} }
return output return result.output
} }
// Workaround the issue with Ruby paths for Xcode 12.3. // Workaround the issue with Ruby paths for Xcode 12.3.