CocoaPods: Fix setting custom framework name

The main scheme of a synthetic project generated for
pod import has the same name as the podspec generated
for the kotlin module (== Gradle project name). But
when starting an Xcode build, we specify the -scheme
argument to a framework name instead of project.name.

By default they are the same, but if a custom framework
name is specified, xcodebuild fails.

Issue #KT-40801 fixed
This commit is contained in:
Ilya Matveev
2020-08-04 17:06:43 +07:00
committed by Ilya Matveev
parent a45f73867a
commit f6d7e7c52a
4 changed files with 57 additions and 36 deletions
@@ -82,7 +82,7 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsSingleKtPod,
"ios-app",
ImportMode.FRAMEWORKS,
listOf("kotlin-library")
mapOf("kotlin-library" to null)
)
@Test
@@ -91,7 +91,7 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsSingleKtPod,
"ios-app",
ImportMode.MODULAR_HEADERS,
listOf("kotlin-library")
mapOf("kotlin-library" to null)
)
@Test
@@ -148,7 +148,7 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsMultipleKtPods,
"ios-app",
ImportMode.FRAMEWORKS,
listOf("kotlin-library", "second-library")
mapOf("kotlin-library" to null, "second-library" to null)
)
@Test
@@ -157,9 +157,38 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsMultipleKtPods,
"ios-app",
ImportMode.MODULAR_HEADERS,
listOf("kotlin-library", "second-library")
mapOf("kotlin-library" to null, "second-library" to null)
)
@Test
fun testPodImportCustomFrameworkName() = doTestPodImport(
cocoapodsSingleKtPod,
"ios-app",
ImportMode.FRAMEWORKS,
mapOf("kotlin-library" to "foobaz")
)
private fun BaseGradleIT.Project.useCustomFrameworkName(subproject: String, frameworkName: String, iosAppLocation: String? = null) {
// Change the name at the Gradle side.
gradleBuildScript(subproject).appendText(
"""
|kotlin {
| cocoapods {
| frameworkName = "$frameworkName"
| }
|}
""".trimMargin()
)
// Change swift sources import if needed.
if (iosAppLocation != null) {
val iosAppDir = projectDir.resolve(iosAppLocation)
iosAppDir.resolve("ios-app/ViewController.swift").modify {
it.replace("import ${subproject.validFrameworkName}", "import $frameworkName")
}
}
}
private fun doTestPodspec(
projectName: String,
subprojectsToFrameworkNamesMap: Map<String, String?>,
@@ -175,16 +204,8 @@ class CocoaPodsIT : BaseGradleIT() {
}
for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) {
frameworkName?.also {
gradleProject.gradleBuildScript(subproject).appendText(
"""
|kotlin {
| cocoapods {
| frameworkName = "$frameworkName"
| }
|}
""".trimMargin()
)
frameworkName?.let {
gradleProject.useCustomFrameworkName(subproject, it)
}
// Check that we can generate the wrapper along with the podspec if the corresponding property specified
@@ -195,8 +216,6 @@ class CocoaPodsIT : BaseGradleIT() {
// Check that the podspec file is correctly generated.
val podspecFileName = "$subproject/${subproject.validFrameworkName}.podspec"
assertFileExists(podspecFileName)
val actualPodspecContentWithoutBlankLines = fileInWorkingDir(podspecFileName).readText()
.lineSequence()
@@ -212,12 +231,20 @@ class CocoaPodsIT : BaseGradleIT() {
projectName: String,
iosAppLocation: String,
mode: ImportMode,
subprojects: List<String>
subprojectsToFrameworkNamesMap: Map<String, String?>,
) {
assumeTrue(HostManager.hostIsMac)
assumeTrue(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic())
val subprojects = subprojectsToFrameworkNamesMap.keys
val gradleProject = transformProjectWithPluginsDsl(projectName, gradleVersion)
subprojectsToFrameworkNamesMap.forEach { subproject, frameworkName ->
frameworkName?.let {
gradleProject.useCustomFrameworkName(subproject, it, iosAppLocation)
}
}
with(gradleProject) {
preparePodfile(iosAppLocation, mode)
podImportAsserts()
@@ -313,25 +340,10 @@ class CocoaPodsIT : BaseGradleIT() {
for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) {
// Add property with custom framework name
frameworkName?.also { name ->
gradleBuildScript(subproject).appendText(
"""
kotlin {
cocoapods {
frameworkName = "$name"
}
}
""".trimIndent()
)
// Change swift sources import
val iosAppDir = projectDir.resolve(iosAppLocation)
iosAppDir.resolve("ios-app/ViewController.swift").modify {
it.replace("import ${subproject.validFrameworkName}", "import $name")
}
frameworkName?.let {
useCustomFrameworkName(subproject, it, iosAppLocation)
}
// Generate podspec.
gradleProject.build(":$subproject:podspec", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
assertSuccessful()
@@ -350,6 +350,10 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
it.description = "Collect environment variables from .xcworkspace file"
it.cocoapodsExtension = cocoapodsExtension
it.kotlinNativeTarget = target
val podspecTaskProvider = project.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java)
it.schemeName = podspecTaskProvider.map { it.specName }
val podGenTaskProvider = project.tasks.named(target.toPodGenTaskName, PodGenTask::class.java)
it.podsXcodeProjDirProvider = podGenTaskProvider.get().podsXcodeProjDirProvider
it.dependsOn(podGenTaskProvider)
@@ -10,6 +10,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.Optional
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.konan.target.Family
@@ -177,6 +178,9 @@ open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
@Internal
lateinit var kotlinNativeTarget: KotlinNativeTarget
@Input
lateinit var schemeName: Provider<String>
@get:OutputFile
internal val buildSettingsFileProvider: Provider<File> = project.provider {
project.cocoapodsBuildDirs
@@ -191,7 +195,7 @@ open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
val buildSettingsReceivingCommand = listOf(
"xcodebuild", "-showBuildSettings",
"-project", podsXcodeProjDir.name,
"-scheme", cocoapodsExtension.frameworkName,
"-scheme", schemeName.get(),
"-sdk", kotlinNativeTarget.toValidSDK
)
@@ -31,7 +31,8 @@ import java.io.File
*/
open class PodspecTask : DefaultTask() {
private val specName = project.name.asValidFrameworkName()
@get:Input
internal val specName = project.name.asValidFrameworkName()
@get:OutputFile
internal val outputFileProvider: Provider<File>