migrated git connected cocoapods test to new test dsl (junit 5 and gradle test kit)
#KT-51553 In Progress
This commit is contained in:
committed by
Space Team
parent
35b475f9f7
commit
267068546f
@@ -87,6 +87,7 @@ dependencies {
|
||||
testImplementation(commonDependency("org.jetbrains.intellij.deps", "trove4j"))
|
||||
testImplementation(commonDependency("io.ktor", "ktor-server-test-host"))
|
||||
testImplementation(commonDependency("io.ktor", "ktor-server-core"))
|
||||
testImplementation(commonDependency("io.ktor", "ktor-client-cio"))
|
||||
testImplementation(commonDependency("io.ktor", "ktor-server-netty"))
|
||||
testImplementation(commonDependency("io.ktor", "ktor-client-mock"))
|
||||
|
||||
|
||||
+4
-4
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import io.ktor.application.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.request.*
|
||||
import io.ktor.response.*
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.engine.*
|
||||
import io.ktor.server.netty.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.util.*
|
||||
import io.ktor.util.collections.*
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
+3
@@ -9,6 +9,7 @@ import org.gradle.api.JavaVersion
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.condition.OS
|
||||
import kotlin.io.path.absolutePathString
|
||||
@@ -574,6 +575,8 @@ class AppleFrameworkIT : KGPBaseTest() {
|
||||
)
|
||||
}
|
||||
|
||||
subProject("iosApp").buildGradleKts.replaceText("<applePluginTestVersion>", "\"${TestVersions.AppleGradlePlugin.V222_0_21}\"")
|
||||
|
||||
build(*dependencyInsight("iosAppIosX64DebugImplementation")) {
|
||||
assertContainsVariant("mainDynamicDebugFrameworkIos")
|
||||
}
|
||||
|
||||
+509
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.native
|
||||
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.util.*
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_BUILD_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_GEN_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_IMPORT_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_INSTALL_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.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.assertProcessRunResult
|
||||
import org.jetbrains.kotlin.gradle.util.capitalize
|
||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||
import org.junit.jupiter.api.Assumptions
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.condition.OS
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@OsCondition(supportedOn = [OS.MAC], enabledOnCI = [OS.MAC])
|
||||
@DisplayName("Git connected K/N tests with cocoapods")
|
||||
@NativeGradlePluginTests
|
||||
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_0)
|
||||
@OptIn(EnvironmentalVariablesOverride::class)
|
||||
class CocoaPodsGitIT : KGPBaseTest() {
|
||||
|
||||
override val defaultBuildOptions = super.defaultBuildOptions.copy(
|
||||
nativeOptions = super.defaultBuildOptions.nativeOptions.copy(
|
||||
cocoapodsGenerateWrapper = true
|
||||
)
|
||||
)
|
||||
|
||||
private val templateProjectName = "native-cocoapods-template"
|
||||
private val groovyTemplateProjectName = "native-cocoapods-template-groovy"
|
||||
|
||||
private val defaultPodRepo = "https://github.com/AFNetworking/AFNetworking"
|
||||
private val defaultPodName = "AFNetworking"
|
||||
private val defaultTarget = "IOS"
|
||||
private val defaultFamily = "ios"
|
||||
private val defaultSDK = "iphonesimulator"
|
||||
private val cinteropTaskName = ":cinterop"
|
||||
private val defaultCinteropTaskName = cinteropTaskName + defaultPodName + defaultTarget
|
||||
|
||||
private val podImportTaskName = ":$POD_IMPORT_TASK_NAME"
|
||||
private val podspecTaskName = ":$POD_SPEC_TASK_NAME"
|
||||
private val podGenTaskName = ":$POD_GEN_TASK_NAME"
|
||||
private val podSetupBuildTaskName = ":$POD_SETUP_BUILD_TASK_NAME"
|
||||
private val podBuildTaskName = ":$POD_BUILD_TASK_NAME"
|
||||
private val podInstallTaskName = ":$POD_INSTALL_TASK_NAME"
|
||||
|
||||
private val defaultPodInstallSyntheticTaskName = ":podInstallSyntheticIos"
|
||||
private val defaultPodGenTaskName = podGenFullTaskName()
|
||||
private val defaultBuildTaskName = podBuildFullTaskName()
|
||||
private val defaultSetupBuildTaskName = podSetupBuildFullTaskName()
|
||||
|
||||
private fun podGenFullTaskName(familyName: String = defaultFamily) =
|
||||
podGenTaskName + familyName.capitalize()
|
||||
|
||||
private fun podSetupBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||
podSetupBuildTaskName + podName.capitalize() + sdkName.capitalize()
|
||||
|
||||
private fun podBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||
podBuildTaskName + podName.capitalize() + sdkName.capitalize()
|
||||
|
||||
private fun cinteropFullTaskName(podName: String = defaultPodName, targetName: String = defaultTarget) =
|
||||
cinteropTaskName + podName.capitalize() + targetName.capitalize()
|
||||
|
||||
@BeforeAll
|
||||
fun setUp() {
|
||||
ensureCocoapodsInstalled()
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git without specifying neither tag not commit")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitNoTagNorCommit(gradleVersion: GradleVersion) {
|
||||
doTestGit(gradleVersion)
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git with specifying tag")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitTag(gradleVersion: GradleVersion) {
|
||||
doTestGit(gradleVersion, tag = "4.0.0")
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git with specifying commit")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitCommit(gradleVersion: GradleVersion) {
|
||||
doTestGit(gradleVersion, commit = "9c07ac0a5645abb58850253eeb109ed0dca515c1")
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git with specifying branch")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitBranch(gradleVersion: GradleVersion) {
|
||||
doTestGit(gradleVersion, branch = "2974")
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod's subspec from git")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitSubspec(gradleVersion: GradleVersion) {
|
||||
doTestGit(
|
||||
gradleVersion,
|
||||
repo = "https://github.com/SDWebImage/SDWebImage.git",
|
||||
pod = "SDWebImage/MapKit",
|
||||
tag = "5.9.2"
|
||||
)
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git with specifying branch and commit")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitBranchAndCommit(gradleVersion: GradleVersion) {
|
||||
doTestGit(
|
||||
gradleVersion,
|
||||
branch = "2974",
|
||||
commit = "21637dd6164c0641e414bdaf3885af6f1ef15aee"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@DisplayName("Downloading pod from git (tag priority is bigger than branch priority)")
|
||||
@GradleTest
|
||||
fun testPodDownloadGitBranchAndTag(gradleVersion: GradleVersion) {
|
||||
doTestGit(
|
||||
gradleVersion,
|
||||
tag = "4.0.0",
|
||||
branch = "2974"
|
||||
)
|
||||
}
|
||||
|
||||
@DisplayName("Downloading pod from git with specifying tag for groovy build file")
|
||||
@GradleTest
|
||||
fun testGroovyDownloadAndImport(gradleVersion: GradleVersion) {
|
||||
doTestGit(
|
||||
gradleVersion,
|
||||
groovyTemplateProjectName,
|
||||
tag = "4.0.0",
|
||||
isGradleBuildScript = true
|
||||
)
|
||||
}
|
||||
|
||||
@DisplayName("Checks that task cinterop is up to date during the second build")
|
||||
@GradleTest
|
||||
fun testCinteropUpToDate(gradleVersion: GradleVersion) {
|
||||
doTestGit(gradleVersion) {
|
||||
|
||||
build(
|
||||
"syncFramework",
|
||||
buildOptions = defaultBuildOptions.copy(
|
||||
nativeOptions = defaultBuildOptions.nativeOptions.copy(
|
||||
cocoapodsGenerateWrapper = true,
|
||||
cocoapodsArchs = "x86_64",
|
||||
cocoapodsConfiguration = "Debug",
|
||||
cocoapodsPlatform = "iphonesimulator",
|
||||
)
|
||||
)
|
||||
) {
|
||||
assertTasksUpToDate(
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DisplayName("UTD test")
|
||||
@GradleTest
|
||||
fun basicUTDTest(gradleVersion: GradleVersion) {
|
||||
val tasks = listOf(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultPodInstallSyntheticTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName,
|
||||
)
|
||||
doTestGit(
|
||||
gradleVersion,
|
||||
testImportAssertions = { assertTasksExecuted(tasks) }
|
||||
) {
|
||||
testImport {
|
||||
assertTasksUpToDate(tasks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("UTD with adding and removing pod")
|
||||
@GradleTest
|
||||
fun testUTDPodAdded(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
testImport()
|
||||
|
||||
val anotherPodName = "Alamofire"
|
||||
val anotherPodRepo = "https://github.com/Alamofire/Alamofire"
|
||||
buildGradleKts.addPod(anotherPodName, produceGitBlock(anotherPodRepo))
|
||||
testImport(listOf(defaultPodRepo, anotherPodRepo)) {
|
||||
|
||||
assertTasksExecuted(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
podSetupBuildFullTaskName(anotherPodName),
|
||||
podBuildFullTaskName(anotherPodName),
|
||||
cinteropFullTaskName(anotherPodName)
|
||||
)
|
||||
assertTasksUpToDate(
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
|
||||
buildGradleKts.removePod(anotherPodName)
|
||||
|
||||
testImport {
|
||||
assertOutputDoesNotContain(podBuildFullTaskName(anotherPodName))
|
||||
assertOutputDoesNotContain(cinteropFullTaskName(anotherPodName))
|
||||
assertTasksUpToDate(
|
||||
defaultBuildTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("UTD with adding and removing target")
|
||||
@GradleTest
|
||||
fun testUTDTargetAdded(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
|
||||
testImport()
|
||||
|
||||
buildGradleKts.addCocoapodsBlock("osx.deploymentTarget = \"10.15\"")
|
||||
testImport()
|
||||
|
||||
val tasks = listOf(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
val anotherTarget = "MacosX64"
|
||||
val anotherSdk = "macosx"
|
||||
val anotherFamily = "macos"
|
||||
buildGradleKts.addKotlinBlock(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()")
|
||||
|
||||
testImport {
|
||||
assertTasksExecuted(
|
||||
podGenFullTaskName(anotherFamily),
|
||||
podSetupBuildFullTaskName(sdkName = anotherSdk),
|
||||
podBuildFullTaskName(sdkName = anotherSdk),
|
||||
cinteropFullTaskName(targetName = anotherTarget)
|
||||
)
|
||||
assertTasksUpToDate(tasks)
|
||||
}
|
||||
|
||||
buildGradleKts.replaceText(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()", "")
|
||||
testImport {
|
||||
assertOutputDoesNotContain(podGenFullTaskName(anotherFamily))
|
||||
assertOutputDoesNotContain(podSetupBuildFullTaskName(sdkName = anotherSdk))
|
||||
assertOutputDoesNotContain(podBuildFullTaskName(sdkName = anotherSdk))
|
||||
assertOutputDoesNotContain(cinteropFullTaskName(targetName = anotherTarget))
|
||||
assertTasksUpToDate(tasks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("UTD build")
|
||||
@GradleTest
|
||||
fun testUTDBuild(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
|
||||
testImport {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
|
||||
val anotherTarget = "MacosX64"
|
||||
val anotherSdk = "macosx"
|
||||
val anotherSdkDefaultPodTaskName = podBuildFullTaskName(sdkName = anotherSdk)
|
||||
buildGradleKts.addCocoapodsBlock("osx.deploymentTarget = \"10.15\"")
|
||||
buildGradleKts.addKotlinBlock(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()")
|
||||
|
||||
testImport {
|
||||
assertTasksUpToDate(defaultBuildTaskName)
|
||||
assertTasksExecuted(anotherSdkDefaultPodTaskName)
|
||||
}
|
||||
testImport {
|
||||
assertTasksUpToDate(defaultBuildTaskName, anotherSdkDefaultPodTaskName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Pod Build UTD after clean")
|
||||
@GradleTest
|
||||
fun testPodBuildUTDClean(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
|
||||
testImport {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
build(":clean")
|
||||
testImport {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Link with use of dynamic framework ")
|
||||
@GradleTest
|
||||
fun testUseDynamicFramework(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
buildGradleKts.addFrameworkBlock("isStatic = false")
|
||||
|
||||
build("linkPodDebugFrameworkIOS") {
|
||||
val framework = projectPath.resolve("build/bin/iOS/podDebugFramework/cocoapods.framework/cocoapods")
|
||||
val processRunResult = runProcess(
|
||||
listOf("file", framework.absolutePathString()),
|
||||
workingDir = projectPath.toFile(),
|
||||
environmentVariables = environmentVariables.environmentalVariables
|
||||
)
|
||||
assertProcessRunResult(processRunResult) {
|
||||
assertTrue(isSuccessful)
|
||||
assertTrue(output.contains("dynamically linked shared library"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Link with use of static framework ")
|
||||
@GradleTest
|
||||
fun testUseStaticFramework(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
buildGradleKts.addPod(defaultPodName, produceGitBlock())
|
||||
buildGradleKts.addFrameworkBlock("isStatic = true")
|
||||
|
||||
build("linkPodDebugFrameworkIOS") {
|
||||
val framework = projectPath.resolve("build/bin/iOS/podDebugFramework/cocoapods.framework/cocoapods")
|
||||
val processRunResult = runProcess(
|
||||
listOf("file", framework.absolutePathString()),
|
||||
workingDir = projectPath.toFile(),
|
||||
environmentVariables = environmentVariables.environmentalVariables
|
||||
)
|
||||
assertProcessRunResult(processRunResult) {
|
||||
assertTrue(isSuccessful)
|
||||
assertTrue(output.contains("current ar archive"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("UTD with different spec repo")
|
||||
@GradleTest
|
||||
fun testUTDPodGen(gradleVersion: GradleVersion) {
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(gradleVersion = gradleVersion) {
|
||||
|
||||
buildGradleKts.addPod(defaultPodName)
|
||||
val repos = listOf(
|
||||
"https://github.com/alozhkin/spec_repo_example",
|
||||
"https://github.com/alozhkin/spec_repo_example_2"
|
||||
)
|
||||
|
||||
isRepoAvailable(repos)
|
||||
|
||||
build(defaultPodGenTaskName) {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
}
|
||||
|
||||
buildGradleKts.addSpecRepo("https://github.com/alozhkin/spec_repo_example")
|
||||
build(defaultPodGenTaskName) {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
}
|
||||
|
||||
buildGradleKts.addSpecRepo("https://github.com/alozhkin/spec_repo_example_2")
|
||||
build(defaultPodGenTaskName) {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
}
|
||||
|
||||
build(defaultPodGenTaskName) {
|
||||
assertTasksUpToDate(defaultPodGenTaskName)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun doTestGit(
|
||||
gradleVersion: GradleVersion,
|
||||
projectName: String = templateProjectName,
|
||||
repo: String = defaultPodRepo,
|
||||
pod: String = defaultPodName,
|
||||
branch: String? = null,
|
||||
commit: String? = null,
|
||||
tag: String? = null,
|
||||
isGradleBuildScript: Boolean = false,
|
||||
testImportAssertions: BuildResult.() -> Unit = {},
|
||||
block: TestProject.() -> Unit = {},
|
||||
) {
|
||||
|
||||
nativeProjectWithCocoapodsAndIosAppPodFile(projectName, gradleVersion) {
|
||||
val buildScript = if (isGradleBuildScript) buildGradle else buildGradleKts
|
||||
buildScript.addPod(pod, produceGitBlock(repo, branch, commit, tag))
|
||||
|
||||
testImport(listOf(repo)) {
|
||||
podImportAsserts(buildScript)
|
||||
testImportAssertions()
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun produceGitBlock(
|
||||
repo: String = defaultPodRepo,
|
||||
branchName: String? = null,
|
||||
commitName: String? = null,
|
||||
tagName: String? = null,
|
||||
): String {
|
||||
val branch = if (branchName != null) "branch = \"$branchName\"" else ""
|
||||
val commit = if (commitName != null) "commit = \"$commitName\"" else ""
|
||||
val tag = if (tagName != null) "tag = \"$tagName\"" else ""
|
||||
return """source = git("$repo") {
|
||||
| $branch
|
||||
| $commit
|
||||
| $tag
|
||||
|}
|
||||
""".trimMargin()
|
||||
}
|
||||
|
||||
private fun BuildResult.podImportAsserts(
|
||||
buildScript: Path,
|
||||
projectName: String? = null,
|
||||
) {
|
||||
|
||||
val buildScriptText = buildScript.readText()
|
||||
val taskPrefix = projectName?.let { ":$it" } ?: ""
|
||||
val podspec = "podspec"
|
||||
|
||||
if ("noPodspec()" in buildScriptText) {
|
||||
assertTasksSkipped("$taskPrefix:$podspec")
|
||||
}
|
||||
|
||||
if ("podfile" in buildScriptText) {
|
||||
assertTasksExecuted("$taskPrefix$podInstallTaskName")
|
||||
} else {
|
||||
assertTasksSkipped("$taskPrefix$podInstallTaskName")
|
||||
}
|
||||
if (buildScriptText.matches("pod\\(.*\\)".toRegex())) {
|
||||
assertTasksExecuted(listOf("$taskPrefix:$POD_GEN_TASK_NAME"))
|
||||
}
|
||||
|
||||
with(listOf(POD_SETUP_BUILD_TASK_NAME, POD_BUILD_TASK_NAME).map { "$taskPrefix:$it" }) {
|
||||
if (buildScriptText.matches("pod\\(.*\\)".toRegex())) {
|
||||
assertTasksExecuted(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isRepoAvailable(repos: List<String>) = runBlocking {
|
||||
HttpClient(CIO).use { client ->
|
||||
val nonAvailableRepos = repos
|
||||
.map { repo ->
|
||||
async { repo to runCatching { client.get(repo).status }.recover { it }.getOrNull() }
|
||||
}
|
||||
.awaitAll()
|
||||
.filter { (_, status) -> status != HttpStatusCode.OK }
|
||||
Assumptions.assumeTrue(nonAvailableRepos.isEmpty()) {
|
||||
"The following repositories of ${repos.joinToString()} are not available: ${nonAvailableRepos.joinToString()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestProject.testImport(
|
||||
repos: List<String> = listOf(defaultPodRepo),
|
||||
vararg args: String,
|
||||
assertions: BuildResult.() -> Unit = {},
|
||||
) {
|
||||
|
||||
isRepoAvailable(repos)
|
||||
|
||||
build(podImportTaskName, *args) {
|
||||
assertions()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+58
-520
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Compan
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_INSTALL_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.util.createTempDir
|
||||
import org.jetbrains.kotlin.gradle.testbase.ImportMode
|
||||
import org.jetbrains.kotlin.gradle.testbase.cocoaPodsEnvironmentVariables
|
||||
import org.jetbrains.kotlin.gradle.testbase.ensureCocoapodsInstalled
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
@@ -22,7 +24,6 @@ import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.zip.ZipFile
|
||||
@@ -40,7 +41,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
private val gradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT
|
||||
|
||||
override fun defaultBuildOptions(): BuildOptions =
|
||||
super.defaultBuildOptions().copy(customEnvironmentVariables = getEnvs())
|
||||
super.defaultBuildOptions().copy(customEnvironmentVariables = cocoaPodsEnvironmentVariables())
|
||||
|
||||
private val podfileImportDirectivePlaceholder = "<import_mode_directive>"
|
||||
private val podfileImportPodPlaceholder = "#import_pod_directive"
|
||||
@@ -48,54 +49,24 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
private val cocoapodsSingleKtPod = "native-cocoapods-single"
|
||||
private val cocoapodsMultipleKtPods = "native-cocoapods-multiple"
|
||||
private val templateProjectName = "native-cocoapods-template"
|
||||
private val groovyTemplateProjectName = "native-cocoapods-template-groovy"
|
||||
private val cocoapodsTestsProjectName = "native-cocoapods-tests"
|
||||
private val cocoapodsCommonizationProjectName = "native-cocoapods-commonization"
|
||||
|
||||
private val dummyTaskName = ":$DUMMY_FRAMEWORK_TASK_NAME"
|
||||
private val podspecTaskName = ":$POD_SPEC_TASK_NAME"
|
||||
private val podGenTaskName = ":$POD_GEN_TASK_NAME"
|
||||
private val podBuildTaskName = ":$POD_BUILD_TASK_NAME"
|
||||
private val podSetupBuildTaskName = ":$POD_SETUP_BUILD_TASK_NAME"
|
||||
private val podImportTaskName = ":$POD_IMPORT_TASK_NAME"
|
||||
private val podInstallTaskName = ":$POD_INSTALL_TASK_NAME"
|
||||
private val cinteropTaskName = ":cinterop"
|
||||
|
||||
private val defaultPodRepo = "https://github.com/AFNetworking/AFNetworking"
|
||||
private val defaultPodName = "AFNetworking"
|
||||
private val defaultTarget = "IOS"
|
||||
private val defaultFamily = "ios"
|
||||
private val defaultSDK = "iphonesimulator"
|
||||
private val defaultPodGenTaskName = podGenFullTaskName()
|
||||
private val defaultPodInstallSyntheticTaskName = ":podInstallSyntheticIos"
|
||||
private val defaultBuildTaskName = podBuildFullTaskName()
|
||||
private val defaultSetupBuildTaskName = podSetupBuildFullTaskName()
|
||||
private val defaultCinteropTaskName = cinteropTaskName + defaultPodName + defaultTarget
|
||||
|
||||
private fun podGenFullTaskName(familyName: String = defaultFamily) =
|
||||
podGenTaskName + familyName.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||
|
||||
private fun podSetupBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||
podSetupBuildTaskName + podName.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + sdkName.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(
|
||||
Locale.getDefault()
|
||||
) else it.toString()
|
||||
}
|
||||
|
||||
private fun podBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||
podBuildTaskName + podName.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + sdkName.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(
|
||||
Locale.getDefault()
|
||||
) else it.toString()
|
||||
}
|
||||
|
||||
private fun cinteropFullTaskName(podName: String = defaultPodName, targetName: String = defaultTarget) =
|
||||
cinteropTaskName + podName.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + targetName.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(
|
||||
Locale.getDefault()
|
||||
) else it.toString()
|
||||
}
|
||||
|
||||
private lateinit var hooks: CustomHooks
|
||||
private lateinit var project: BaseGradleIT.Project
|
||||
|
||||
@@ -154,7 +125,8 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
@Test
|
||||
fun testSyntheticProjectPodfileGeneration() {
|
||||
val gradleProject = transformProjectWithPluginsDsl(cocoapodsSingleKtPod, gradleVersion)
|
||||
gradleProject.gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleProject.gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
ios.deploymentTarget = "14.1"
|
||||
pod("SSZipArchive")
|
||||
pod("AFNetworking", "~> 4.0.1")
|
||||
@@ -163,7 +135,8 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
tag = "5.6.1"
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
gradleProject.build("podInstallSyntheticIos", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":podGenIos")
|
||||
@@ -184,14 +157,16 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
project.gradleBuildScript().apply {
|
||||
appendToCocoapodsBlock("""pod("ChatSDK", version = "5.2.1")""")
|
||||
|
||||
appendText("""
|
||||
appendText(
|
||||
"""
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.targets.native.tasks.PodGenTask>().configureEach {
|
||||
doLast {
|
||||
podfile.get().appendText("ENV['SWIFT_VERSION'] = '5'")
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
project.build("podInstallSyntheticIos", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
|
||||
@@ -200,65 +175,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitNoTagNorCommit() {
|
||||
doTestGit()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitTag() {
|
||||
doTestGit(tag = "4.0.0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitCommit() {
|
||||
doTestGit(commit = "9c07ac0a5645abb58850253eeb109ed0dca515c1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitBranch() {
|
||||
doTestGit(branch = "2974")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitSubspec() {
|
||||
doTestGit(
|
||||
repo = "https://github.com/SDWebImage/SDWebImage.git",
|
||||
pod = "SDWebImage/MapKit",
|
||||
tag = "5.9.2"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitBranchAndCommit() {
|
||||
val branch = "2974"
|
||||
val commit = "21637dd6164c0641e414bdaf3885af6f1ef15aee"
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo, branchName = branch, commitName = commit))
|
||||
}
|
||||
project.testImportWithAsserts(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
// tag priority is bigger than branch priority
|
||||
@Test
|
||||
fun testPodDownloadGitBranchAndTag() {
|
||||
val branch = "2974"
|
||||
val tag = "4.0.0"
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo, branchName = branch, tagName = tag))
|
||||
}
|
||||
project.testImportWithAsserts(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDownloadAndImport() {
|
||||
val tag = "4.0.0"
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo, tagName = tag))
|
||||
}
|
||||
project.testImportWithAsserts(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun warnIfDeprecatedPodspecPathIsUsed() {
|
||||
project = getProjectByName(cocoapodsSingleKtPod)
|
||||
@@ -306,13 +222,15 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
@Test
|
||||
fun testImportUTDAfterLinkingFramework() {
|
||||
val linkTaskName = ":linkPodDebugFrameworkIOS"
|
||||
project.gradleBuildScript().appendToCocoapodsBlock("""
|
||||
project.gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
framework {
|
||||
baseName = "kotlin-library"
|
||||
}
|
||||
name = "kotlin-library"
|
||||
podfile = project.file("ios-app/Podfile")
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
|
||||
hooks.addHook {
|
||||
@@ -335,13 +253,15 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@Test
|
||||
fun testChangeFrameworkTypeUTD() {
|
||||
project.gradleBuildScript().appendToCocoapodsBlock("""
|
||||
project.gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
framework {
|
||||
baseName = "kotlin-library"
|
||||
}
|
||||
name = "kotlin-library"
|
||||
podfile = project.file("ios-app/Podfile")
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(dummyTaskName)
|
||||
@@ -371,31 +291,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
fun basicUTDTest() {
|
||||
val tasks = listOf(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultPodInstallSyntheticTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName,
|
||||
)
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
}
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(tasks)
|
||||
}
|
||||
project.testImportWithAsserts(listOf(defaultPodRepo))
|
||||
|
||||
hooks.rewriteHooks {
|
||||
assertTasksUpToDate(tasks)
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSpecReposUTD() {
|
||||
with(project.gradleBuildScript()) {
|
||||
@@ -433,53 +328,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
project.testSynthetic(defaultPodInstallSyntheticTaskName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUTDPodAdded() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
|
||||
val anotherPodName = "Alamofire"
|
||||
val anotherPodRepo = "https://github.com/Alamofire/Alamofire"
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(anotherPodName, produceGitBlock(anotherPodRepo))
|
||||
}
|
||||
hooks.rewriteHooks {
|
||||
assertTasksExecuted(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
podSetupBuildFullTaskName(anotherPodName),
|
||||
podBuildFullTaskName(anotherPodName),
|
||||
cinteropFullTaskName(anotherPodName)
|
||||
)
|
||||
assertTasksUpToDate(
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo, anotherPodRepo))
|
||||
|
||||
with(project.gradleBuildScript()) {
|
||||
removePod(anotherPodName)
|
||||
}
|
||||
hooks.rewriteHooks {
|
||||
assertTasksNotRegisteredByPrefix(
|
||||
listOf(
|
||||
podBuildFullTaskName(anotherPodName),
|
||||
cinteropFullTaskName(anotherPodName)
|
||||
)
|
||||
)
|
||||
assertTasksUpToDate(
|
||||
defaultBuildTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testImportSubspecs() {
|
||||
with(project.gradleBuildScript()) {
|
||||
@@ -489,62 +337,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUTDTargetAdded() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
appendToCocoapodsBlock("osx.deploymentTarget = \"10.15\"")
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
|
||||
val anotherTarget = "MacosX64"
|
||||
val anotherSdk = "macosx"
|
||||
val anotherFamily = "macos"
|
||||
with(project.gradleBuildScript()) {
|
||||
appendToKotlinBlock(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()")
|
||||
}
|
||||
hooks.rewriteHooks {
|
||||
assertTasksExecuted(
|
||||
podGenFullTaskName(anotherFamily),
|
||||
podSetupBuildFullTaskName(sdkName = anotherSdk),
|
||||
podBuildFullTaskName(sdkName = anotherSdk),
|
||||
cinteropFullTaskName(targetName = anotherTarget)
|
||||
)
|
||||
assertTasksUpToDate(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
|
||||
with(project.gradleBuildScript()) {
|
||||
var text = readText()
|
||||
text = text.replace(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()", "")
|
||||
writeText(text)
|
||||
}
|
||||
hooks.rewriteHooks {
|
||||
assertTasksNotRegisteredByPrefix(
|
||||
listOf(
|
||||
podGenFullTaskName(anotherFamily),
|
||||
podSetupBuildFullTaskName(sdkName = anotherSdk),
|
||||
podBuildFullTaskName(sdkName = anotherSdk),
|
||||
cinteropFullTaskName(targetName = anotherTarget)
|
||||
)
|
||||
)
|
||||
assertTasksUpToDate(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
project.testImport(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUTDPodspec() {
|
||||
project.testWithWrapper(podspecTaskName)
|
||||
@@ -580,83 +372,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
project.testWithWrapper(podspecTaskName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUTDPodGen() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName)
|
||||
}
|
||||
val repos = listOf(
|
||||
"https://github.com/alozhkin/spec_repo_example",
|
||||
"https://github.com/alozhkin/spec_repo_example_2"
|
||||
)
|
||||
for (repo in repos) {
|
||||
assumeTrue(isRepoAvailable(repo))
|
||||
}
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
with(project.gradleBuildScript()) {
|
||||
addSpecRepo("https://github.com/alozhkin/spec_repo_example")
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
with(project.gradleBuildScript()) {
|
||||
addSpecRepo("https://github.com/alozhkin/spec_repo_example_2")
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
hooks.rewriteHooks {
|
||||
assertTasksUpToDate(defaultPodGenTaskName)
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUTDBuild() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock())
|
||||
}
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
project.testImport()
|
||||
|
||||
val anotherTarget = "MacosX64"
|
||||
val anotherSdk = "macosx"
|
||||
with(project.gradleBuildScript()) {
|
||||
appendToCocoapodsBlock("osx.deploymentTarget = \"10.15\"")
|
||||
appendToKotlinBlock(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()")
|
||||
}
|
||||
val anotherSdkDefaultPodTaskName = podBuildFullTaskName(sdkName = anotherSdk)
|
||||
hooks.rewriteHooks {
|
||||
assertTasksUpToDate(defaultBuildTaskName)
|
||||
assertTasksExecuted(anotherSdkDefaultPodTaskName)
|
||||
}
|
||||
project.testImport()
|
||||
|
||||
hooks.rewriteHooks {
|
||||
assertTasksUpToDate(defaultBuildTaskName, anotherSdkDefaultPodTaskName)
|
||||
}
|
||||
project.testImport()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodBuildUTDClean() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock())
|
||||
}
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
project.testImport()
|
||||
|
||||
hooks.rewriteHooks {}
|
||||
project.test(":clean")
|
||||
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(defaultBuildTaskName)
|
||||
}
|
||||
project.testImport()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodInstallWithoutPodFile() {
|
||||
@@ -664,19 +379,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
|
||||
// groovy tests
|
||||
|
||||
@Test
|
||||
fun testGroovyDownloadAndImport() {
|
||||
val project = getProjectByName(groovyTemplateProjectName)
|
||||
val tag = "4.0.0"
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo, tagName = tag))
|
||||
}
|
||||
project.testImportWithAsserts(listOf(defaultPodRepo))
|
||||
}
|
||||
|
||||
|
||||
// other tests
|
||||
|
||||
@Test
|
||||
@@ -742,47 +444,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUseDynamicFramework() {
|
||||
with(project) {
|
||||
gradleBuildScript().addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
gradleBuildScript().appendToFrameworkBlock("isStatic = false")
|
||||
hooks.addHook {
|
||||
// Check that an output framework is a dynamic framework
|
||||
val framework = fileInWorkingDir("build/bin/iOS/podDebugFramework/cocoapods.framework/cocoapods")
|
||||
with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = getEnvs())) {
|
||||
assertTrue(isSuccessful)
|
||||
assertTrue(output.contains("dynamically linked shared library"))
|
||||
}
|
||||
}
|
||||
|
||||
test(
|
||||
"linkPodDebugFrameworkIOS",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUseStaticFramework() {
|
||||
with(project) {
|
||||
gradleBuildScript().addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
gradleBuildScript().appendToFrameworkBlock("isStatic = true")
|
||||
hooks.addHook {
|
||||
// Check that an output framework is a static framework
|
||||
val framework = fileInWorkingDir("build/bin/iOS/podDebugFramework/cocoapods.framework/cocoapods")
|
||||
with(runProcess(listOf("file", framework.absolutePath), projectDir, environmentVariables = getEnvs())) {
|
||||
assertTrue(isSuccessful)
|
||||
kotlin.test.assertContains(output, "current ar archive")
|
||||
}
|
||||
}
|
||||
|
||||
test(
|
||||
"linkPodDebugFrameworkIOS",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCocoapodsWithRegularFrameworkDefinition() {
|
||||
@@ -970,23 +631,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
getProjectByName(cocoapodsTestsProjectName).testWithWrapper(":iosX64Test")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCinteropUpToDate() {
|
||||
project.gradleBuildScript().addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
project.testImport()
|
||||
hooks.addHook {
|
||||
assertTasksUpToDate(
|
||||
defaultCinteropTaskName
|
||||
)
|
||||
}
|
||||
project.test(
|
||||
"syncFramework",
|
||||
"-Pkotlin.native.cocoapods.platform=iphonesimulator",
|
||||
"-Pkotlin.native.cocoapods.archs=x86_64",
|
||||
"-Pkotlin.native.cocoapods.configuration=Debug",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCinteropCommonizationOff() {
|
||||
@@ -1116,11 +760,13 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@Test
|
||||
fun testLinkOnlyPods() = with(project) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
pod("AFNetworking") { linkOnly = true }
|
||||
pod("SSZipArchive", linkOnly = true)
|
||||
pod("SDWebImage/Core")
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
":linkPodDebugFrameworkIOS",
|
||||
@@ -1136,31 +782,37 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
assertTasksNotRegistered(":cinteropAFNetworkingIOS")
|
||||
assertTasksNotRegistered(":cinteropSSZipArchiveIOS")
|
||||
|
||||
assertContains("""
|
||||
assertContains(
|
||||
"""
|
||||
| -linker-option
|
||||
| -framework
|
||||
| -linker-option
|
||||
| AFNetworking
|
||||
""".trimMargin())
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
assertContains("""
|
||||
assertContains(
|
||||
"""
|
||||
| -linker-option
|
||||
| -framework
|
||||
| -linker-option
|
||||
| SSZipArchive
|
||||
""".trimMargin())
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUsageLinkOnlyWithStaticFrameworkProducesMessage() = with(project) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
framework {
|
||||
isStatic = true
|
||||
}
|
||||
|
||||
pod("AFNetworking") { linkOnly = true }
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
":linkPodDebugFrameworkIOS",
|
||||
@@ -1184,9 +836,11 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@Test
|
||||
fun `configuration fails when trying to depend on non-declared pod`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
pod("Foo") { useInteropBindingFrom("JBNonExistent") }
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
":help",
|
||||
@@ -1199,10 +853,12 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@Test
|
||||
fun `configuration fails when dependant pods are in the wrong order`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
pod("Foo") { useInteropBindingFrom("Bar") }
|
||||
pod("Bar")
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
":help",
|
||||
@@ -1215,9 +871,11 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@Test
|
||||
fun `configuration fails when pod depends on itself`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
gradleBuildScript().appendToCocoapodsBlock(
|
||||
"""
|
||||
pod("Foo") { useInteropBindingFrom("Foo") }
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
":help",
|
||||
@@ -1249,22 +907,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun doTestGit(
|
||||
repo: String = defaultPodRepo,
|
||||
pod: String = defaultPodName,
|
||||
branch: String? = null,
|
||||
commit: String? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(pod, produceGitBlock(repo, branch, commit, tag))
|
||||
}
|
||||
project.testImportWithAsserts(listOf(repo))
|
||||
}
|
||||
|
||||
private fun Project.testImportWithAsserts(
|
||||
repos: List<String> = listOf(),
|
||||
vararg args: String
|
||||
vararg args: String,
|
||||
) {
|
||||
hooks.addHook {
|
||||
podImportAsserts()
|
||||
@@ -1274,7 +920,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
private fun Project.testImport(
|
||||
repos: List<String> = listOf(),
|
||||
vararg args: String
|
||||
vararg args: String,
|
||||
) {
|
||||
for (repo in repos) {
|
||||
assumeTrue(isRepoAvailable(repo))
|
||||
@@ -1284,21 +930,21 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
private fun Project.testSynthetic(
|
||||
taskName: String,
|
||||
vararg args: String
|
||||
vararg args: String,
|
||||
) {
|
||||
testWithWrapper(taskName, *args)
|
||||
}
|
||||
|
||||
private fun Project.testWithWrapper(
|
||||
taskName: String,
|
||||
vararg args: String
|
||||
vararg args: String,
|
||||
) {
|
||||
test(taskName, "-Pkotlin.native.cocoapods.generate.wrapper=true", *args)
|
||||
}
|
||||
|
||||
private fun Project.test(
|
||||
taskName: String,
|
||||
vararg args: String
|
||||
vararg args: String,
|
||||
) {
|
||||
|
||||
// check that test executable
|
||||
@@ -1320,25 +966,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
appendToCocoapodsBlock(podBlock)
|
||||
}
|
||||
|
||||
private fun File.removePod(podName: String) {
|
||||
val text = readText()
|
||||
val begin = text.indexOf("""pod("$podName")""")
|
||||
require(begin != -1) { "Pod doesn't exist in file" }
|
||||
var index = begin + """pod("$podName")""".length - 1
|
||||
if (text.indexOf("""pod("$podName") {""", startIndex = begin) != -1) {
|
||||
index += 2
|
||||
var bracket = 1
|
||||
while (bracket != 0) {
|
||||
if (text[++index] == '{') {
|
||||
bracket++
|
||||
} else if (text[index] == '}') {
|
||||
bracket--
|
||||
}
|
||||
}
|
||||
}
|
||||
writeText(text.removeRange(begin..index))
|
||||
}
|
||||
|
||||
private fun File.addSpecRepo(specRepo: String) = appendToCocoapodsBlock("url(\"$specRepo\")".wrap("specRepos"))
|
||||
|
||||
private fun File.appendToKotlinBlock(str: String) = appendLine(str.wrap("kotlin"))
|
||||
@@ -1355,23 +982,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
private fun File.appendLine(s: String) = appendText("\n$s")
|
||||
|
||||
private fun produceGitBlock(
|
||||
repo: String = defaultPodRepo,
|
||||
branchName: String? = null,
|
||||
commitName: String? = null,
|
||||
tagName: String? = null
|
||||
): String {
|
||||
val branch = if (branchName != null) "branch = \"$branchName\"" else ""
|
||||
val commit = if (commitName != null) "commit = \"$commitName\"" else ""
|
||||
val tag = if (tagName != null) "tag = \"$tagName\"" else ""
|
||||
return """source = git("$repo") {
|
||||
| $branch
|
||||
| $commit
|
||||
| $tag
|
||||
|}
|
||||
""".trimMargin()
|
||||
}
|
||||
|
||||
|
||||
// proposition phase
|
||||
|
||||
@@ -1426,15 +1036,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
private enum class ImportMode(val directive: String) {
|
||||
FRAMEWORKS("use_frameworks!"),
|
||||
MODULAR_HEADERS("use_modular_headers!")
|
||||
}
|
||||
|
||||
private data class CommandResult(
|
||||
val exitCode: Int,
|
||||
val stdOut: String,
|
||||
val stdErr: String
|
||||
val stdErr: String,
|
||||
)
|
||||
|
||||
private fun runCommand(
|
||||
@@ -1443,11 +1048,11 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
vararg args: String,
|
||||
timeoutSec: Long = 120,
|
||||
inheritIO: Boolean = false,
|
||||
block: CommandResult.() -> Unit
|
||||
block: CommandResult.() -> Unit,
|
||||
) {
|
||||
val process = ProcessBuilder(command, *args).apply {
|
||||
directory(workingDir)
|
||||
environment().putAll(getEnvs())
|
||||
environment().putAll(cocoaPodsEnvironmentVariables())
|
||||
if (inheritIO) {
|
||||
inheritIO()
|
||||
}
|
||||
@@ -1523,79 +1128,12 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun ensureCocoapodsInstalled() {
|
||||
fun checkCocoapodsInstalled() {
|
||||
if (!HostManager.hostIsMac) {
|
||||
return
|
||||
}
|
||||
|
||||
if (shouldInstallLocalCocoapods) {
|
||||
val installDir = cocoapodsInstallationRoot.absolutePath
|
||||
println("Installing CocoaPods...")
|
||||
|
||||
//https://github.com/ffi/ffi/issues/864#issuecomment-875242776
|
||||
gem("install", "--install-dir", installDir, "ffi", "-v", "1.15.5", "--", "--enable-libffi-alloc")
|
||||
|
||||
gem("install", "--install-dir", installDir, "cocoapods", "-v", localCocoapodsVersion)
|
||||
} else if (!isCocoapodsInstalled()) {
|
||||
fail(
|
||||
"""
|
||||
Running CocoaPods integration tests requires cocoapods to be installed.
|
||||
Please install them manually:
|
||||
gem install cocoapods
|
||||
Or re-run the tests with the 'installCocoapods=true' Gradle property.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private const val localCocoapodsVersion = "1.11.0"
|
||||
|
||||
private val shouldInstallLocalCocoapods: Boolean = System.getProperty("installCocoapods").toBoolean()
|
||||
|
||||
private val cocoapodsInstallationRoot: File by lazy { createTempDir("cocoapods") }
|
||||
private val cocoapodsBinPath: File by lazy {
|
||||
cocoapodsInstallationRoot.resolve("bin")
|
||||
}
|
||||
|
||||
private fun getEnvs(): Map<String, String> {
|
||||
if (!shouldInstallLocalCocoapods) {
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
val path = cocoapodsBinPath.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,
|
||||
// CocoaPods 1.11 requires UTF-8 locale being set, more details: https://github.com/CocoaPods/CocoaPods/issues/10939
|
||||
"LC_ALL" to "en_US.UTF-8"
|
||||
)
|
||||
}
|
||||
|
||||
private fun isCocoapodsInstalled(): Boolean {
|
||||
// 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("."),
|
||||
)
|
||||
result.isSuccessful
|
||||
} catch (e: IOException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun gem(vararg args: String): String {
|
||||
val command = listOf("gem", *args)
|
||||
println("Run command: ${command.joinToString(separator = " ")}")
|
||||
val result = runProcess(command, File("."), options = BuildOptions(forceOutputToStdout = true))
|
||||
check(result.isSuccessful) {
|
||||
"Process 'gem ${args.joinToString(separator = " ")}' exited with error code ${result.exitCode}. See log for details."
|
||||
}
|
||||
return result.output
|
||||
ensureCocoapodsInstalled()
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-24
@@ -6,10 +6,11 @@
|
||||
package org.jetbrains.kotlin.gradle.native
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_INSTALL_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.assertProcessRunResult
|
||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.condition.OS
|
||||
import java.nio.file.Path
|
||||
@@ -24,18 +25,16 @@ import kotlin.test.assertEquals
|
||||
@OptIn(EnvironmentalVariablesOverride::class)
|
||||
class CocoaPodsXcodeIT : KGPBaseTest() {
|
||||
|
||||
private val podfileImportDirectivePlaceholder = "<import_mode_directive>"
|
||||
|
||||
private val cocoapodsSingleKtPod = "native-cocoapods-single"
|
||||
private val cocoapodsMultipleKtPods = "native-cocoapods-multiple"
|
||||
private val templateProjectName = "native-cocoapods-template"
|
||||
|
||||
private val environmentVariables = EnvironmentalVariables(
|
||||
mapOf(
|
||||
// CocoaPods 1.11 requires UTF-8 locale being set, more details: https://github.com/CocoaPods/CocoaPods/issues/10939
|
||||
"LC_ALL" to "en_US.UTF-8"
|
||||
)
|
||||
)
|
||||
private val environmentVariables = EnvironmentalVariables(cocoaPodsEnvironmentVariables())
|
||||
|
||||
@BeforeAll
|
||||
fun setUp() {
|
||||
ensureCocoapodsInstalled()
|
||||
}
|
||||
|
||||
@DisplayName("Checks xcodebuild for ios-app with a single framework")
|
||||
@GradleTest
|
||||
@@ -142,20 +141,6 @@ class CocoaPodsXcodeIT : KGPBaseTest() {
|
||||
mapOf("kotlin-library" to "FirstMultiplatformLibrary", "second-library" to "SecondMultiplatformLibrary")
|
||||
)
|
||||
|
||||
private enum class ImportMode(val directive: String) {
|
||||
FRAMEWORKS("use_frameworks!"),
|
||||
MODULAR_HEADERS("use_modular_headers!")
|
||||
}
|
||||
|
||||
private fun TestProject.preparePodfile(iosAppLocation: String, mode: ImportMode) {
|
||||
val iosAppDir = projectPath.resolve(iosAppLocation)
|
||||
|
||||
// Set import mode for Podfile.
|
||||
iosAppDir.resolve("Podfile")
|
||||
.takeIf { it.exists() }
|
||||
?.replaceText(podfileImportDirectivePlaceholder, mode.directive)
|
||||
}
|
||||
|
||||
private fun doTestXcode(
|
||||
projectName: String,
|
||||
gradleVersion: GradleVersion,
|
||||
@@ -208,7 +193,7 @@ class CocoaPodsXcodeIT : KGPBaseTest() {
|
||||
// Set import mode for Podfile.
|
||||
preparePodfile(it, mode)
|
||||
// Install pods.
|
||||
build("$taskPrefix:podInstall", buildOptions = buildOptions)
|
||||
build("$taskPrefix:$POD_INSTALL_TASK_NAME", buildOptions = buildOptions)
|
||||
|
||||
projectPath.resolve(it).apply {
|
||||
// Run Xcode build.
|
||||
|
||||
+12
@@ -68,6 +68,9 @@ data class BuildOptions(
|
||||
data class NativeOptions(
|
||||
val cacheKind: NativeCacheKind = NativeCacheKind.NONE,
|
||||
val cocoapodsGenerateWrapper: Boolean? = null,
|
||||
val cocoapodsPlatform: String? = null,
|
||||
val cocoapodsConfiguration: String? = null,
|
||||
val cocoapodsArchs: String? = null,
|
||||
val distributionType: String? = null,
|
||||
val distributionDownloadFromMaven: Boolean? = null,
|
||||
val platformLibrariesMode: String? = null,
|
||||
@@ -199,6 +202,15 @@ data class BuildOptions(
|
||||
nativeOptions.cocoapodsGenerateWrapper?.let {
|
||||
arguments.add("-Pkotlin.native.cocoapods.generate.wrapper=${it}")
|
||||
}
|
||||
nativeOptions.cocoapodsPlatform?.let {
|
||||
arguments.add("-Pkotlin.native.cocoapods.platform=${it}")
|
||||
}
|
||||
nativeOptions.cocoapodsArchs?.let {
|
||||
arguments.add("-Pkotlin.native.cocoapods.archs=${it}")
|
||||
}
|
||||
nativeOptions.cocoapodsConfiguration?.let {
|
||||
arguments.add("-Pkotlin.native.cocoapods.configuration=${it}")
|
||||
}
|
||||
|
||||
nativeOptions.distributionDownloadFromMaven?.let {
|
||||
arguments.add("-Pkotlin.native.distribution.downloadFromMaven=${it}")
|
||||
|
||||
+4
@@ -70,6 +70,10 @@ interface TestVersions {
|
||||
;
|
||||
}
|
||||
|
||||
object COCOAPODS {
|
||||
const val VERSION = "1.11.0"
|
||||
}
|
||||
|
||||
object AppleGradlePlugin {
|
||||
const val V222_0_21 = "222.4550-0.21"
|
||||
}
|
||||
|
||||
+195
-4
@@ -5,13 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.testbase
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_INSTALL_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.appendText
|
||||
import kotlin.io.path.*
|
||||
import kotlin.test.fail
|
||||
|
||||
val String.normalizeCocoapadsFrameworkName: String
|
||||
get() = replace('-', '_')
|
||||
|
||||
enum class ImportMode(val directive: String) {
|
||||
FRAMEWORKS("use_frameworks!"),
|
||||
MODULAR_HEADERS("use_modular_headers!")
|
||||
}
|
||||
|
||||
fun TestProject.useCustomCocoapodsFrameworkName(
|
||||
subprojectName: String,
|
||||
frameworkName: String,
|
||||
@@ -34,10 +46,189 @@ fun TestProject.useCustomCocoapodsFrameworkName(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the Podfile for an iOS app in the [TestProject]
|
||||
*
|
||||
* @param iosAppLocation The relative location of the iOS app directory within the [TestProject]
|
||||
* @param mode The [ImportMode] to be set for the Podfile.
|
||||
*
|
||||
*/
|
||||
fun TestProject.preparePodfile(iosAppLocation: String, mode: ImportMode) {
|
||||
val iosAppDir = projectPath.resolve(iosAppLocation)
|
||||
|
||||
// Set import mode for Podfile.
|
||||
iosAppDir.resolve("Podfile")
|
||||
.takeIf { it.exists() }
|
||||
?.replaceText(podfileImportDirectivePlaceholder, mode.directive)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given string into a specRepos block and adds this block to the end of the [this] path.
|
||||
*
|
||||
* @param specRepo The code to be wrapped with the Cocoapods block.
|
||||
*/
|
||||
|
||||
fun Path.addSpecRepo(specRepo: String) = addCocoapodsBlock("url(\"$specRepo\")".wrapIntoBlock("specRepos"))
|
||||
|
||||
/**
|
||||
* Wraps the given string into a Cocoapods block and adds this block to the end of the [this] path.
|
||||
*
|
||||
* @param str The code to be wrapped with the Cocoapods block.
|
||||
*/
|
||||
fun Path.addCocoapodsBlock(str: String) = addKotlinBlock(str.wrapIntoBlock("cocoapods"))
|
||||
|
||||
private fun Path.addKotlinBlock(str: String) = appendLine(str.wrapIntoBlock("kotlin"))
|
||||
/**
|
||||
* Wraps the given string into a Kotlin block and adds this block to the end of the [this] path.
|
||||
*
|
||||
* @param str The code to be wrapped with the Cocoapods block.
|
||||
*/
|
||||
fun Path.addKotlinBlock(str: String) = appendLine(str.wrapIntoBlock("kotlin"))
|
||||
|
||||
private fun Path.addFrameworkBlock(str: String) = addCocoapodsBlock(str.wrapIntoBlock("framework"))
|
||||
/**
|
||||
* Wraps the given string into a Framework block and adds this block to the end of the [this] path.
|
||||
*
|
||||
* @param str The code to be wrapped with the Cocoapods block.
|
||||
*/
|
||||
fun Path.addFrameworkBlock(str: String) = addCocoapodsBlock(str.wrapIntoBlock("framework"))
|
||||
|
||||
private fun Path.appendLine(s: String) = appendText("\n$s")
|
||||
|
||||
/**
|
||||
* Adds a Cocoapods dependency to [this] build script.
|
||||
*
|
||||
* @param podName The name of the Cocoapods dependency to be added.
|
||||
* @param configuration The optional configuration string for the Cocoapods dependency.
|
||||
*/
|
||||
fun Path.addPod(podName: String, configuration: String? = null) {
|
||||
val pod = "pod(\"$podName\")"
|
||||
val podBlock = configuration?.wrapIntoBlock(pod) ?: pod
|
||||
addCocoapodsBlock(podBlock)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a Cocoapods dependency from [this] build script.
|
||||
*
|
||||
* @param podName The name of the Cocoapods dependency to be removes.
|
||||
*/
|
||||
fun Path.removePod(podName: String) {
|
||||
val text = readText()
|
||||
val begin = text.indexOf("""pod("$podName")""")
|
||||
require(begin != -1) {
|
||||
"""
|
||||
Pod doesn't exist in file. File content is:
|
||||
${text}
|
||||
""".trimIndent()
|
||||
}
|
||||
var index = begin + """pod("$podName")""".length - 1
|
||||
if (text.indexOf("""pod("$podName") {""", startIndex = begin) != -1) {
|
||||
index += 2
|
||||
var bracket = 1
|
||||
while (bracket != 0) {
|
||||
if (text[++index] == '{') {
|
||||
bracket++
|
||||
} else if (text[index] == '}') {
|
||||
bracket--
|
||||
}
|
||||
}
|
||||
}
|
||||
writeText(text.removeRange(begin..index))
|
||||
}
|
||||
|
||||
/**
|
||||
* Method returns required environment variables for cocoapods tests with execution of [POD_INSTALL_TASK_NAME]
|
||||
*/
|
||||
fun cocoaPodsEnvironmentVariables(): Map<String, String> {
|
||||
if (!shouldInstallLocalCocoapods) {
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
val path = cocoapodsBinPath.absolutePathString() + File.pathSeparator + System.getenv("PATH")
|
||||
val gemPath = System.getenv("GEM_PATH")?.let {
|
||||
cocoapodsInstallationRoot.absolutePathString() + File.pathSeparator + it
|
||||
} ?: cocoapodsInstallationRoot.absolutePathString()
|
||||
return mapOf(
|
||||
"PATH" to path,
|
||||
"GEM_PATH" to gemPath,
|
||||
// CocoaPods 1.11 requires UTF-8 locale being set, more details: https://github.com/CocoaPods/CocoaPods/issues/10939
|
||||
"LC_ALL" to "en_US.UTF-8"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if Cocoapods should be installed and verifies its installation status.
|
||||
* If [shouldInstallLocalCocoapods] is true, it tries to install Cocoapods into the specified [cocoapodsInstallationRoot]
|
||||
* if it is not already installed.
|
||||
*
|
||||
* @throws AssertionError if [shouldInstallLocalCocoapods] is false and cocoapods has not been installed
|
||||
*/
|
||||
fun ensureCocoapodsInstalled() {
|
||||
if (shouldInstallLocalCocoapods) {
|
||||
val installDir = cocoapodsInstallationRoot.absolutePathString()
|
||||
println("Installing CocoaPods...")
|
||||
|
||||
//https://github.com/ffi/ffi/issues/864#issuecomment-875242776
|
||||
gem("install", "--install-dir", installDir, "ffi", "-v", "1.15.5", "--", "--enable-libffi-alloc")
|
||||
|
||||
gem("install", "--install-dir", installDir, "cocoapods", "-v", TestVersions.COCOAPODS.VERSION)
|
||||
} else if (!isCocoapodsInstalled()) {
|
||||
fail(
|
||||
"""
|
||||
Running CocoaPods integration tests requires cocoapods to be installed.
|
||||
Please install them manually:
|
||||
gem install cocoapods
|
||||
Or re-run the tests with the 'installCocoapods=true' Gradle property.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@EnvironmentalVariablesOverride
|
||||
fun KGPBaseTest.nativeProjectWithCocoapodsAndIosAppPodFile(
|
||||
projectName: String = templateProjectName,
|
||||
gradleVersion: GradleVersion,
|
||||
buildOptions: BuildOptions = this.defaultBuildOptions,
|
||||
projectBlock: TestProject.() -> Unit = {},
|
||||
) {
|
||||
nativeProject(
|
||||
projectName,
|
||||
gradleVersion,
|
||||
buildOptions = buildOptions,
|
||||
environmentVariables = EnvironmentalVariables(cocoaPodsEnvironmentVariables())
|
||||
) {
|
||||
preparePodfile("ios-app", ImportMode.FRAMEWORKS)
|
||||
projectBlock()
|
||||
}
|
||||
}
|
||||
|
||||
private val templateProjectName = "native-cocoapods-template"
|
||||
|
||||
private val shouldInstallLocalCocoapods: Boolean = System.getProperty("installCocoapods").toBoolean()
|
||||
private val cocoapodsInstallationRoot: Path by lazy { createTempDirectory("cocoapods") }
|
||||
private val cocoapodsBinPath: Path by lazy { cocoapodsInstallationRoot.resolve("bin") }
|
||||
|
||||
private fun isCocoapodsInstalled(): Boolean {
|
||||
// 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("."),
|
||||
)
|
||||
result.isSuccessful
|
||||
} catch (e: IOException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun gem(vararg args: String): String {
|
||||
val command = listOf("gem", *args)
|
||||
println("Run command: ${command.joinToString(separator = " ")}")
|
||||
val result = runProcess(command, File("."), options = BaseGradleIT.BuildOptions(forceOutputToStdout = true))
|
||||
check(result.isSuccessful) {
|
||||
"Process 'gem ${args.joinToString(separator = " ")}' exited with error code ${result.exitCode}. See log for details."
|
||||
}
|
||||
return result.output
|
||||
}
|
||||
|
||||
private fun Path.appendLine(s: String) = appendText("\n$s")
|
||||
|
||||
private const val podfileImportDirectivePlaceholder = "<import_mode_directive>"
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.gradle.apple.applePlugin") version "222.4550-0.21"
|
||||
id("org.jetbrains.gradle.apple.applePlugin") version <applePluginTestVersion>
|
||||
}
|
||||
|
||||
apple {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
|
||||
id("org.jetbrains.kotlin.native.cocoapods").version("<pluginMarkerVersion>")
|
||||
id("org.jetbrains.kotlin.multiplatform")
|
||||
id("org.jetbrains.kotlin.native.cocoapods")
|
||||
}
|
||||
|
||||
group = "com.example"
|
||||
|
||||
Reference in New Issue
Block a user