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, cocoapodsSingleKtPod,
"ios-app", "ios-app",
ImportMode.FRAMEWORKS, ImportMode.FRAMEWORKS,
listOf("kotlin-library") mapOf("kotlin-library" to null)
) )
@Test @Test
@@ -91,7 +91,7 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsSingleKtPod, cocoapodsSingleKtPod,
"ios-app", "ios-app",
ImportMode.MODULAR_HEADERS, ImportMode.MODULAR_HEADERS,
listOf("kotlin-library") mapOf("kotlin-library" to null)
) )
@Test @Test
@@ -148,7 +148,7 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsMultipleKtPods, cocoapodsMultipleKtPods,
"ios-app", "ios-app",
ImportMode.FRAMEWORKS, ImportMode.FRAMEWORKS,
listOf("kotlin-library", "second-library") mapOf("kotlin-library" to null, "second-library" to null)
) )
@Test @Test
@@ -157,9 +157,38 @@ class CocoaPodsIT : BaseGradleIT() {
cocoapodsMultipleKtPods, cocoapodsMultipleKtPods,
"ios-app", "ios-app",
ImportMode.MODULAR_HEADERS, 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( private fun doTestPodspec(
projectName: String, projectName: String,
subprojectsToFrameworkNamesMap: Map<String, String?>, subprojectsToFrameworkNamesMap: Map<String, String?>,
@@ -175,16 +204,8 @@ class CocoaPodsIT : BaseGradleIT() {
} }
for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) { for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) {
frameworkName?.also { frameworkName?.let {
gradleProject.gradleBuildScript(subproject).appendText( gradleProject.useCustomFrameworkName(subproject, it)
"""
|kotlin {
| cocoapods {
| frameworkName = "$frameworkName"
| }
|}
""".trimMargin()
)
} }
// Check that we can generate the wrapper along with the podspec if the corresponding property specified // 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. // Check that the podspec file is correctly generated.
val podspecFileName = "$subproject/${subproject.validFrameworkName}.podspec" val podspecFileName = "$subproject/${subproject.validFrameworkName}.podspec"
assertFileExists(podspecFileName) assertFileExists(podspecFileName)
val actualPodspecContentWithoutBlankLines = fileInWorkingDir(podspecFileName).readText() val actualPodspecContentWithoutBlankLines = fileInWorkingDir(podspecFileName).readText()
.lineSequence() .lineSequence()
@@ -212,12 +231,20 @@ class CocoaPodsIT : BaseGradleIT() {
projectName: String, projectName: String,
iosAppLocation: String, iosAppLocation: String,
mode: ImportMode, mode: ImportMode,
subprojects: List<String> subprojectsToFrameworkNamesMap: Map<String, String?>,
) { ) {
assumeTrue(HostManager.hostIsMac) assumeTrue(HostManager.hostIsMac)
assumeTrue(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic()) assumeTrue(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic())
val subprojects = subprojectsToFrameworkNamesMap.keys
val gradleProject = transformProjectWithPluginsDsl(projectName, gradleVersion) val gradleProject = transformProjectWithPluginsDsl(projectName, gradleVersion)
subprojectsToFrameworkNamesMap.forEach { subproject, frameworkName ->
frameworkName?.let {
gradleProject.useCustomFrameworkName(subproject, it, iosAppLocation)
}
}
with(gradleProject) { with(gradleProject) {
preparePodfile(iosAppLocation, mode) preparePodfile(iosAppLocation, mode)
podImportAsserts() podImportAsserts()
@@ -313,25 +340,10 @@ class CocoaPodsIT : BaseGradleIT() {
for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) { for ((subproject, frameworkName) in subprojectsToFrameworkNamesMap) {
// Add property with custom framework name // Add property with custom framework name
frameworkName?.also { name -> frameworkName?.let {
gradleBuildScript(subproject).appendText( useCustomFrameworkName(subproject, it, iosAppLocation)
"""
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")
}
} }
// Generate podspec. // Generate podspec.
gradleProject.build(":$subproject:podspec", "-Pkotlin.native.cocoapods.generate.wrapper=true") { gradleProject.build(":$subproject:podspec", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
assertSuccessful() assertSuccessful()
@@ -350,6 +350,10 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
it.description = "Collect environment variables from .xcworkspace file" it.description = "Collect environment variables from .xcworkspace file"
it.cocoapodsExtension = cocoapodsExtension it.cocoapodsExtension = cocoapodsExtension
it.kotlinNativeTarget = target 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) val podGenTaskProvider = project.tasks.named(target.toPodGenTaskName, PodGenTask::class.java)
it.podsXcodeProjDirProvider = podGenTaskProvider.get().podsXcodeProjDirProvider it.podsXcodeProjDirProvider = podGenTaskProvider.get().podsXcodeProjDirProvider
it.dependsOn(podGenTaskProvider) it.dependsOn(podGenTaskProvider)
@@ -10,6 +10,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.Optional import org.gradle.api.tasks.Optional
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension 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.cocoapods.cocoapodsBuildDirs
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family
@@ -177,6 +178,9 @@ open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
@Internal @Internal
lateinit var kotlinNativeTarget: KotlinNativeTarget lateinit var kotlinNativeTarget: KotlinNativeTarget
@Input
lateinit var schemeName: Provider<String>
@get:OutputFile @get:OutputFile
internal val buildSettingsFileProvider: Provider<File> = project.provider { internal val buildSettingsFileProvider: Provider<File> = project.provider {
project.cocoapodsBuildDirs project.cocoapodsBuildDirs
@@ -191,7 +195,7 @@ open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
val buildSettingsReceivingCommand = listOf( val buildSettingsReceivingCommand = listOf(
"xcodebuild", "-showBuildSettings", "xcodebuild", "-showBuildSettings",
"-project", podsXcodeProjDir.name, "-project", podsXcodeProjDir.name,
"-scheme", cocoapodsExtension.frameworkName, "-scheme", schemeName.get(),
"-sdk", kotlinNativeTarget.toValidSDK "-sdk", kotlinNativeTarget.toValidSDK
) )
@@ -31,7 +31,8 @@ import java.io.File
*/ */
open class PodspecTask : DefaultTask() { open class PodspecTask : DefaultTask() {
private val specName = project.name.asValidFrameworkName() @get:Input
internal val specName = project.name.asValidFrameworkName()
@get:OutputFile @get:OutputFile
internal val outputFileProvider: Provider<File> internal val outputFileProvider: Provider<File>