From ce029822265bdd9bfaf1cc6716eddee7a142a48e Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Wed, 19 Aug 2020 15:27:48 +0700 Subject: [PATCH] CocoaPods: Skip synthetic task on non-mac hosts This patch performs the following changes: 1. Create synthetic tasks even if synthetic projects are not supported on the current host. This change simplifies configuring dependencies between these tasks and custom user tasks at the user side. 2. Disable synthetic tasks if synthetic projects are not supported on the current host Issue #KT-40834 Fixed --- .../jetbrains/kotlin/gradle/CocoaPodsIT.kt | 25 ++++++++++++- .../native/cocoapods/KotlinCocoapodsPlugin.kt | 37 ++++++++++++------- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CocoaPodsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CocoaPodsIT.kt index 75d88af3873..2a99efc4aca 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CocoaPodsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CocoaPodsIT.kt @@ -11,6 +11,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.util.modify import org.jetbrains.kotlin.konan.target.HostManager +import org.junit.Assume.assumeFalse import org.junit.Assume.assumeTrue import org.junit.Test import java.io.File @@ -168,6 +169,28 @@ class CocoaPodsIT : BaseGradleIT() { mapOf("kotlin-library" to "foobaz") ) + @Test + fun testSkippingTasksOnOtherHosts() { + assumeFalse(HostManager.hostIsMac) + + with(transformProjectWithPluginsDsl(cocoapodsSingleKtPod, gradleVersion)) { + val syntheticTasks = arrayOf( + ":podInstall", + ":kotlin-library:generateDummyFramework", + ":kotlin-library:podGenIOS", + ":kotlin-library:podSetupBuildIOS", + ":kotlin-library:podBuildDependenciesIOS", + ":kotlin-library:podImport" + ) + + build(*syntheticTasks, "-Pkotlin.native.cocoapods.generate.wrapper=true") { + // Check that tasks working with synthetic projects are skipped on non-mac hosts. + assertSuccessful() + assertTasksSkipped(*syntheticTasks) + } + } + } + private fun BaseGradleIT.Project.useCustomFrameworkName(subproject: String, frameworkName: String, iosAppLocation: String? = null) { // Change the name at the Gradle side. gradleBuildScript(subproject).appendText( @@ -234,7 +257,7 @@ class CocoaPodsIT : BaseGradleIT() { subprojectsToFrameworkNamesMap: Map, ) { assumeTrue(HostManager.hostIsMac) - assumeTrue(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic()) + assumeTrue(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic) val subprojects = subprojectsToFrameworkNamesMap.keys val gradleProject = transformProjectWithPluginsDsl(projectName, gradleVersion) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt index ce693dd7417..1a70917956e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt @@ -213,8 +213,8 @@ open class KotlinCocoapodsPlugin : Plugin { interop.packageName = "cocoapods.${pod.moduleName}" - if (//TODO ychernyshev improve first check - isAvailableToProduceSynthetic() + if ( + isAvailableToProduceSynthetic && project.findProperty(TARGET_PROPERTY) == null && project.findProperty(CONFIGURATION_PROPERTY) == null ) { @@ -239,8 +239,8 @@ open class KotlinCocoapodsPlugin : Plugin { // Since we cannot expand the configuration phase of interop tasks // receiving the required environment variables happens on execution phase. // TODO This needs to be fixed to improve UP-TO-DATE checks. - if (// TODO ychernyshev improve first check - isAvailableToProduceSynthetic() + if ( + isAvailableToProduceSynthetic && project.findProperty(TARGET_PROPERTY) == null && project.findProperty(CONFIGURATION_PROPERTY) == null ) { @@ -305,6 +305,8 @@ open class KotlinCocoapodsPlugin : Plugin { it.group = TASK_GROUP it.description = "Invokes `pod install` call within Podfile location directory" it.cocoapodsExtension = cocoapodsExtension + it.onlyIf { isAvailableToProduceSynthetic } + //TODO avoid subproject task management here project.allprojects.map { it.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java) } .forEach { podspecTaskProvider -> @@ -328,6 +330,7 @@ open class KotlinCocoapodsPlugin : Plugin { it.kotlinNativeTarget = target it.cocoapodsExtension = cocoapodsExtension it.dependsOn(podspecTaskProvider) + it.onlyIf { isAvailableToProduceSynthetic } } } } @@ -352,6 +355,7 @@ open class KotlinCocoapodsPlugin : Plugin { val podGenTaskProvider = project.tasks.named(target.toPodGenTaskName, PodGenTask::class.java) it.podsXcodeProjDirProvider = podGenTaskProvider.get().podsXcodeProjDirProvider it.dependsOn(podGenTaskProvider) + it.onlyIf { isAvailableToProduceSynthetic } } } } @@ -374,6 +378,7 @@ open class KotlinCocoapodsPlugin : Plugin { it.podsXcodeProjDirProvider = podSetupBuildTaskProvider.get().podsXcodeProjDirProvider it.buildSettingsFileProvider = podSetupBuildTaskProvider.get().buildSettingsFileProvider it.dependsOn(podSetupBuildTaskProvider) + it.onlyIf { isAvailableToProduceSynthetic } } } } @@ -388,6 +393,7 @@ open class KotlinCocoapodsPlugin : Plugin { it.group = TASK_GROUP it.description = "Called on Gradle sync, depends on Cinterop tasks for every used pod" it.dependsOn(podInstallTaskProvider) + it.onlyIf { isAvailableToProduceSynthetic } kotlinExtension.supportedTargets().all { target -> target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).cinterops.all { interop -> @@ -408,13 +414,14 @@ open class KotlinCocoapodsPlugin : Plugin { registerDummyFrameworkTask(project, cocoapodsExtension) createSyncTask(project, kotlinExtension) registerPodspecTask(project, cocoapodsExtension) - if (isAvailableToProduceSynthetic()) { - registerPodGenTask(project, kotlinExtension, cocoapodsExtension) - registerPodInstallTask(project, cocoapodsExtension) - registerPodSetupBuildTasks(project, kotlinExtension, cocoapodsExtension) - registerPodBuildTasks(project, kotlinExtension, cocoapodsExtension) - registerPodImportTask(project, kotlinExtension) - } else { + + registerPodGenTask(project, kotlinExtension, cocoapodsExtension) + registerPodInstallTask(project, cocoapodsExtension) + registerPodSetupBuildTasks(project, kotlinExtension, cocoapodsExtension) + registerPodBuildTasks(project, kotlinExtension, cocoapodsExtension) + registerPodImportTask(project, kotlinExtension) + + if (HostManager.hostIsMac && !isAvailableToProduceSynthetic) { logger.quiet( """ To take advantage of the new functionality for Cocoapods Integration like synchronizing with the Xcode project @@ -457,13 +464,17 @@ open class KotlinCocoapodsPlugin : Plugin { const val KOTLIN_TARGET_FOR_IOS_DEVICE = "ios_arm" const val KOTLIN_TARGET_FOR_WATCHOS_DEVICE = "watchos_arm" - fun isAvailableToProduceSynthetic(): Boolean { + val isAvailableToProduceSynthetic: Boolean by lazy { + if (!HostManager.hostIsMac) { + return@lazy false + } + val gemListProcess = ProcessBuilder("gem", "list").start() val gemListRetCode = gemListProcess.waitFor() val gemListOutput = gemListProcess.inputStream.use { it.reader().readText() } - return gemListRetCode == 0 && gemListOutput.contains("cocoapods-generate") + gemListRetCode == 0 && gemListOutput.contains("cocoapods-generate") } } } \ No newline at end of file