[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_SPEC_TASK_NAME
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.runProcess
import org.jetbrains.kotlin.konan.target.HostManager
@@ -26,6 +27,7 @@ import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import java.io.File
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.util.concurrent.TimeUnit
@@ -50,7 +52,7 @@ class CocoaPodsIT : BaseGradleIT() {
private val gradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT
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>"
@@ -770,8 +772,7 @@ class CocoaPodsIT : BaseGradleIT() {
hooks.addHook {
// Check that a built universal framework includes both device and simulator architectures.
val framework = fileInWorkingDir("build/cocoapods/framework/cocoapods.framework/cocoapods")
val env = mapOf("PATH" to getPathEnv())
with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = env)) {
with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = getPathEnvs())) {
assertTrue(isSuccessful)
assertTrue(output.contains("\\(for architecture x86_64\\):\\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 {
directory(workingDir)
environment()["PATH"] = getPathEnv()
environment().putAll(getPathEnvs())
if (inheritIO) {
inheritIO()
}
@@ -1405,8 +1406,7 @@ class CocoaPodsIT : BaseGradleIT() {
if (cocoapodsInstallationRequired) {
if (cocoapodsInstallationAllowed) {
WorkaroundForXcode12_3.apply()
gem("install", "--user-install", "cocoapods", "cocoapods-generate")
cocoapodsInstallationPath = File(getGemUserInstallationPath()).resolve("bin")
gem("install", "--install-dir", cocoapodsInstallationRoot.absolutePath, "cocoapods", "cocoapods-generate")
} else {
fail(
"""
@@ -1422,65 +1422,52 @@ class CocoaPodsIT : BaseGradleIT() {
@AfterClass
@JvmStatic
fun uninstallPodGen() {
// Do not remove CocoaPods if we didn't install it.
fun disposeWorkarounds() {
if (cocoapodsInstallationRequired && cocoapodsInstallationAllowed) {
val packagesToRemove = gem("list", "--no-versions").lineSequence().filter {
it.startsWith("cocoapods")
}.toList()
try {
gem("uninstall", "--user-install", "-x", *packagesToRemove.toTypedArray())
} finally {
WorkaroundForXcode12_3.dispose()
}
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 var cocoapodsInstallationPath: File? = null
private val cocoapodsInstallationRoot: File by lazy { createTempDir("cocoapods") }
private fun getPathEnv(): String {
val oldPath = System.getenv("PATH")
return cocoapodsInstallationPath?.let {
it.absolutePath + File.pathSeparator + oldPath
} ?: oldPath
private fun getPathEnvs(): Map<String, String> {
val path = cocoapodsInstallationRoot.resolve("bin").absolutePath + File.pathSeparator + System.getenv("PATH")
val gemPath = System.getenv("GEM_PATH")?.let {
cocoapodsInstallationRoot.absolutePath + File.pathSeparator + it
} ?: cocoapodsInstallationRoot.absolutePath
return mapOf("PATH" to path, "GEM_PATH" to gemPath)
}
private fun isCocoapodsInstalled(): Boolean {
val installed = gem("list", "--no-versions").lines()
return "cocoapods-generate" in installed && "cocoapods" in installed
// Do not use 'gem list' because the gem may be installed but PATH may miss its executables.
// 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 {
val installationDirLine = gem("environment").lineSequence().first {
it.contains("USER INSTALLATION DIRECTORY:")
}
return installationDirLine.substringAfter("USER INSTALLATION DIRECTORY:").trim()
private fun isPodGenInstalled(): Boolean {
val installed = gem("list", "--no-versions").lines()
return "cocoapods-generate" in installed
}
private fun gem(vararg args: String): String {
val process = ProcessBuilder("gem", *args).start()
val finished = process.waitFor(30, TimeUnit.MINUTES)
val output = process.inputStream.use { it.reader().readText() }
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"
}
val result = runProcess(listOf("gem", *args), File("."))
check(result.isSuccessful) {
"Process 'gem ${args.joinToString(separator = " ")}' exited with error code ${result.exitCode}. See log for details."
}
return output
return result.output
}
// Workaround the issue with Ruby paths for Xcode 12.3.