[Gradle] Forbid using embedAndSign together with Pod-dependencies

^KT-64096 Verification Pending
This commit is contained in:
Artem Daugel-Dauge
2024-02-17 17:52:23 +09:00
committed by Space Team
parent f5de0f9399
commit 7ab691fcef
4 changed files with 69 additions and 9 deletions
@@ -21,6 +21,8 @@ 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 org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import java.util.zip.ZipFile
import kotlin.io.path.*
import kotlin.test.assertContains
@@ -1049,6 +1051,31 @@ class CocoaPodsIT : KGPBaseTest() {
}
}
@DisplayName("Build fails when embedAndSign task is used with pod-dependencies")
@GradleTest
fun testEmbedAndSignNotUsedWithPodDepsDiagnostic(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
nativeProjectWithCocoapodsAndIosAppPodFile(
gradleVersion = gradleVersion,
environmentVariables = EnvironmentalVariables(
"CONFIGURATION" to "debug",
"SDK_NAME" to "iphoneos123",
"ARCHS" to "arm64",
"TARGET_BUILD_DIR" to tempDir.absolutePathString(),
"FRAMEWORKS_FOLDER_PATH" to "frameworks",
"BUILT_PRODUCTS_DIR" to tempDir.absolutePathString(),
)
) {
buildGradleKts.addKotlinBlock("iosArm64()")
buildGradleKts.addCocoapodsBlock("""pod("Base64", version="1.1.2")""")
buildAndFail(":embedAndSignPodAppleFrameworkForXcode") {
assertHasDiagnostic(CocoapodsPluginDiagnostics.EmbedAndSignUsedWithPodDependencies)
}
}
}
private fun TestProject.buildAndFailWithCocoapodsWrapper(
vararg buildArguments: String,
assertions: BuildResult.() -> Unit = {},
@@ -17,6 +17,7 @@ import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.UsesKotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
@@ -217,11 +218,7 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework
val envSign = XcodeEnvironment.sign
val userScriptSandboxingEnabled = XcodeEnvironment.userScriptSandboxingEnabled
val frameworkTaskName = lowerCamelCaseName(
AppleXcodeTasks.embedAndSignTaskPrefix,
framework.namePrefix,
AppleXcodeTasks.embedAndSignTaskPostfix
)
val frameworkTaskName = framework.embedAndSignTaskName()
if (envBuildType == null || envTargets.isEmpty() || envEmbeddedFrameworksDir == null) {
locateOrRegisterTask<DefaultTask>(frameworkTaskName) { task ->
@@ -250,7 +247,7 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework
}
}
val embedAndSignTask = locateOrRegisterTask<FrameworkCopy>(frameworkTaskName) { task ->
val embedAndSignTask = locateOrRegisterTask<EmbedAndSignTask>(frameworkTaskName) { task ->
task.group = BasePlugin.BUILD_GROUP
task.description = "Embed and sign ${framework.namePrefix} framework as requested by Xcode's environment variables"
task.isEnabled = !framework.isStatic
@@ -288,6 +285,12 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework
}
}
private fun Framework.embedAndSignTaskName(): String = lowerCamelCaseName(
AppleXcodeTasks.embedAndSignTaskPrefix,
namePrefix,
AppleXcodeTasks.embedAndSignTaskPostfix
)
private val Framework.namePrefix: String
get() = KotlinNativeBinaryContainer.extractPrefixFromBinaryName(
name,
@@ -316,7 +319,7 @@ private fun Project.appleFrameworkDir(frameworkTaskName: String): Provider<File>
* To preserve these symlinks we are using the `cp` command instead.
* See https://youtrack.jetbrains.com/issue/KT-48594.
*/
@DisableCachingByDefault
@DisableCachingByDefault(because = "Caching breaks symlinks inside frameworks")
internal abstract class FrameworkCopy : DefaultTask() {
@get:Inject
@@ -359,3 +362,6 @@ internal abstract class FrameworkCopy : DefaultTask() {
fun dsymFile(framework: Provider<File>): Provider<File> = framework.map { File(it.path + ".dSYM") }
}
}
@DisableCachingByDefault(because = "Caching breaks symlinks inside frameworks")
internal abstract class EmbedAndSignTask : FrameworkCopy(), UsesKotlinToolingDiagnostics
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.gradle.targets.native.cocoapods
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.ERROR
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.WARNING
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.*
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnosticFactory
@InternalKotlinGradlePluginApi // used in integration tests
@@ -52,4 +51,13 @@ object CocoapodsPluginDiagnostics {
operator fun invoke(podName: String, dependencyName: String) = build("Couldn't find declaration of pod '$dependencyName' (interop-binding dependency of pod '${podName}')")
}
object EmbedAndSignUsedWithPodDependencies : ToolingDiagnosticFactory(FATAL) {
operator fun invoke() = build(
"""
'embedAndSign' task can not be used in a project with dependencies to pods.
Please use CocoaPods for integration into Xcode.
""".trimIndent()
)
}
}
@@ -815,6 +815,24 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
}
}
private fun checkEmbedAndSignNotUsedTogetherWithPodDependencies(project: Project, kotlinExtension: KotlinMultiplatformExtension, cocoapodsExtension: CocoapodsExtension) {
cocoapodsExtension.pods.all {
SingleActionPerProject.run(project, "assertEmbedAndSignNotUsedTogetherWithPodDependencies") {
kotlinExtension.targets.withType<KotlinNativeTarget>().all { target ->
target.binaries.withType<Framework>().all {
project.tasks.withType<EmbedAndSignTask>().all { embedAndSignTask ->
embedAndSignTask.doFirst {
embedAndSignTask.reportDiagnostic(CocoapodsPluginDiagnostics.EmbedAndSignUsedWithPodDependencies())
}
}
}
}
}
}
}
private fun Project.gradleWrapperPath(): Provider<String?> {
return provider { rootProject.tasks.locateTask<Wrapper>("wrapper")?.get()?.scriptFile?.absolutePath }
}
@@ -873,6 +891,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
createInterops(project, kotlinExtension, cocoapodsExtension)
configureLinkingOptions(project, cocoapodsExtension)
checkLinkOnlyNotUsedWithStaticFramework(project, cocoapodsExtension)
checkEmbedAndSignNotUsedTogetherWithPodDependencies(project, kotlinExtension, cocoapodsExtension)
}
}