Separate podgen & podinstall tasks
^KT-54161 Verification Pending
This commit is contained in:
committed by
Space Team
parent
f144f8b6d3
commit
8a34d1f430
+37
-12
@@ -70,9 +70,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
private val defaultPodRepo = "https://github.com/AFNetworking/AFNetworking"
|
||||
private val defaultPodName = "AFNetworking"
|
||||
private val defaultTarget = "IOS"
|
||||
private val defaultFamily = "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
|
||||
@@ -245,7 +246,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSyntheticProjectPodspecGeneration() {
|
||||
fun testSyntheticProjectPodfileGeneration() {
|
||||
val gradleProject = transformProjectWithPluginsDsl(cocoapodsSingleKtPod, gradleVersion)
|
||||
gradleProject.gradleBuildScript().appendToCocoapodsBlock("""
|
||||
ios.deploymentTarget = "14.1"
|
||||
@@ -257,9 +258,11 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
gradleProject.build("podGenIOS", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
|
||||
gradleProject.build("podInstallSyntheticIos", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
|
||||
assertSuccessful()
|
||||
val podfileText = gradleProject.projectDir.resolve("build/cocoapods/synthetic/IOS/Podfile").readText().trim()
|
||||
assertTasksExecuted(":podGenIos")
|
||||
|
||||
val podfileText = gradleProject.projectDir.resolve("build/cocoapods/synthetic/ios/Podfile").readText().trim()
|
||||
assertTrue(podfileText.contains("platform :ios, '14.1'"))
|
||||
assertTrue(podfileText.contains("pod 'SSZipArchive'"))
|
||||
assertTrue(podfileText.contains("pod 'AFNetworking', '~> 4.0.1'"))
|
||||
@@ -270,6 +273,27 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSyntheticProjectPodfilePostprocessing() {
|
||||
project.gradleBuildScript().apply {
|
||||
appendToCocoapodsBlock("""pod("AWSMobileClient", version = "2.29.1")""")
|
||||
|
||||
appendText("""
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.targets.native.tasks.PodGenTask>().configureEach {
|
||||
doLast {
|
||||
podfile.get().appendText("ENV['SWIFT_VERSION'] = '5'")
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
project.build("podInstallSyntheticIos", "-Pkotlin.native.cocoapods.generate.wrapper=true") {
|
||||
assertSuccessful()
|
||||
assertFileContains(path = "build/cocoapods/synthetic/ios/Podfile", "ENV['SWIFT_VERSION'] = '5'")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodDownloadGitNoTagNorCommit() {
|
||||
doTestGit()
|
||||
@@ -378,9 +402,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
val tasks = listOf(
|
||||
podspecTaskName,
|
||||
defaultPodGenTaskName,
|
||||
defaultPodInstallSyntheticTaskName,
|
||||
defaultSetupBuildTaskName,
|
||||
defaultBuildTaskName,
|
||||
defaultCinteropTaskName
|
||||
defaultCinteropTaskName,
|
||||
)
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||
@@ -416,21 +441,21 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPodGenInvalidatesUTD() {
|
||||
fun testPodInstallInvalidatesUTD() {
|
||||
with(project.gradleBuildScript()) {
|
||||
addPod("AFNetworking")
|
||||
}
|
||||
|
||||
hooks.addHook {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
assertTrue { fileInWorkingDir("build/cocoapods/synthetic/IOS/Pods/AFNetworking").deleteRecursively() }
|
||||
assertTasksExecuted(defaultPodInstallSyntheticTaskName)
|
||||
assertTrue { fileInWorkingDir("build/cocoapods/synthetic/ios/Pods/AFNetworking").deleteRecursively() }
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
project.testSynthetic(defaultPodInstallSyntheticTaskName)
|
||||
|
||||
hooks.rewriteHooks {
|
||||
assertTasksExecuted(defaultPodGenTaskName)
|
||||
assertTasksExecuted(defaultPodInstallSyntheticTaskName)
|
||||
}
|
||||
project.testSynthetic(defaultPodGenTaskName)
|
||||
project.testSynthetic(defaultPodInstallSyntheticTaskName)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -499,7 +524,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
|
||||
val anotherTarget = "MacosX64"
|
||||
val anotherSdk = "macosx"
|
||||
val anotherFamily = "OSX"
|
||||
val anotherFamily = "macos"
|
||||
with(project.gradleBuildScript()) {
|
||||
appendToKotlinBlock(anotherTarget.replaceFirstChar { it.lowercase(Locale.getDefault()) } + "()")
|
||||
}
|
||||
|
||||
+1
-6
@@ -10,22 +10,17 @@ import org.gradle.api.Action
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.NamedDomainObjectSet
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency.PodLocation.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_FRAMEWORK_PREFIX
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBinary
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
|
||||
import org.jetbrains.kotlin.gradle.tasks.addArg
|
||||
import org.jetbrains.kotlin.gradle.tasks.addArgs
|
||||
import org.jetbrains.kotlin.gradle.utils.relativeToRoot
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("unused") // Public API
|
||||
abstract class CocoapodsExtension @Inject constructor(private val project: Project) {
|
||||
/**
|
||||
* Configure version of the pod
|
||||
|
||||
+53
-34
@@ -62,7 +62,7 @@ internal class CocoapodsBuildDirs(val project: Project) {
|
||||
val synthetic: File
|
||||
get() = root.resolve("synthetic")
|
||||
|
||||
fun synthetic(family: Family) = synthetic.resolve(family.name)
|
||||
fun synthetic(family: Family) = synthetic.resolve(family.platformLiteral)
|
||||
|
||||
val publish: File = root.resolve("publish")
|
||||
|
||||
@@ -72,11 +72,20 @@ internal class CocoapodsBuildDirs(val project: Project) {
|
||||
|
||||
internal fun String.asValidFrameworkName() = replace('-', '_')
|
||||
|
||||
internal val Family.platformLiteral: String
|
||||
get() = when (this) {
|
||||
Family.OSX -> "macos"
|
||||
Family.IOS -> "ios"
|
||||
Family.TVOS -> "tvos"
|
||||
Family.WATCHOS -> "watchos"
|
||||
else -> throw IllegalArgumentException("Bad family ${this.name}")
|
||||
}
|
||||
|
||||
private val Family.toPodGenTaskName: String
|
||||
get() = lowerCamelCaseName(
|
||||
KotlinCocoapodsPlugin.POD_GEN_TASK_NAME,
|
||||
name
|
||||
)
|
||||
get() = lowerCamelCaseName(KotlinCocoapodsPlugin.POD_GEN_TASK_NAME, platformLiteral)
|
||||
|
||||
private val Family.toPodInstallSyntheticTaskName: String
|
||||
get() = lowerCamelCaseName(KotlinCocoapodsPlugin.POD_INSTALL_TASK_NAME, "synthetic", platformLiteral)
|
||||
|
||||
private fun String.toSetupBuildTaskName(pod: CocoapodsDependency): String = lowerCamelCaseName(
|
||||
KotlinCocoapodsPlugin.POD_SETUP_BUILD_TASK_NAME,
|
||||
@@ -451,23 +460,25 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
project: Project,
|
||||
cocoapodsExtension: CocoapodsExtension
|
||||
) {
|
||||
val podspecTaskProvider = project.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java)
|
||||
project.tasks.register(POD_INSTALL_TASK_NAME, PodInstallTask::class.java) {
|
||||
it.group = TASK_GROUP
|
||||
it.description = "Invokes `pod install` call within Podfile location directory"
|
||||
it.podfile.set(cocoapodsExtension.podfile)
|
||||
it.podspec.set(podspecTaskProvider.map { podspecTask -> podspecTask.outputFile })
|
||||
it.frameworkName = cocoapodsExtension.podFrameworkName
|
||||
it.dependsOn(podspecTaskProvider)
|
||||
val podspecTaskProvider = project.tasks.named<PodspecTask>(POD_SPEC_TASK_NAME)
|
||||
project.registerTask<PodInstallTask>(POD_INSTALL_TASK_NAME) { task ->
|
||||
task.group = TASK_GROUP
|
||||
task.description = "Invokes `pod install` call within Podfile location directory"
|
||||
task.podfile.set(project.provider { cocoapodsExtension.podfile })
|
||||
task.podspec.set(podspecTaskProvider.map { it.outputFile })
|
||||
task.frameworkName.set(cocoapodsExtension.podFrameworkName)
|
||||
task.specRepos.set(project.provider { cocoapodsExtension.specRepos })
|
||||
task.pods.set(cocoapodsExtension.pods)
|
||||
task.dependsOn(podspecTaskProvider)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerPodGenTask(
|
||||
private fun registerSyntheticPodTasks(
|
||||
project: Project, kotlinExtension: KotlinMultiplatformExtension, cocoapodsExtension: CocoapodsExtension
|
||||
) {
|
||||
val families = mutableSetOf<Family>()
|
||||
|
||||
val podspecTaskProvider = project.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java)
|
||||
val podspecTaskProvider = project.tasks.named<PodspecTask>(POD_SPEC_TASK_NAME)
|
||||
kotlinExtension.supportedTargets().all { target ->
|
||||
val family = target.konanTarget.family
|
||||
if (family in families) {
|
||||
@@ -483,15 +494,23 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
else -> error("Unknown cocoapods platform: $family")
|
||||
}
|
||||
|
||||
project.tasks.register(family.toPodGenTaskName, PodGenTask::class.java) {
|
||||
it.description = "Сreates a synthetic Xcode project to retrieve CocoaPods dependencies"
|
||||
it.podspec = podspecTaskProvider.map { task -> task.outputFile }
|
||||
it.podName = project.provider { cocoapodsExtension.name }
|
||||
it.useLibraries = project.provider { cocoapodsExtension.useLibraries }
|
||||
it.specRepos = project.provider { cocoapodsExtension.specRepos }
|
||||
it.family = family
|
||||
it.platformSettings = platformSettings
|
||||
it.pods.set(cocoapodsExtension.pods)
|
||||
val podGenTask = project.registerTask<PodGenTask>(family.toPodGenTaskName) { task ->
|
||||
task.description = "Сreates a synthetic Xcode project to retrieve CocoaPods dependencies"
|
||||
task.podspec = podspecTaskProvider.map { it.outputFile }
|
||||
task.podName = project.provider { cocoapodsExtension.name }
|
||||
task.useLibraries = project.provider { cocoapodsExtension.useLibraries }
|
||||
task.specRepos = project.provider { cocoapodsExtension.specRepos }
|
||||
task.family = family
|
||||
task.platformSettings = platformSettings
|
||||
task.pods.set(cocoapodsExtension.pods)
|
||||
}
|
||||
|
||||
project.registerTask<PodInstallSyntheticTask>(family.toPodInstallSyntheticTaskName) { task ->
|
||||
task.description = "Invokes `pod install` for synthetic project"
|
||||
task.podfile.set(podGenTask.map { it.podfile.get() })
|
||||
task.family.set(family)
|
||||
task.podName.set(cocoapodsExtension.name)
|
||||
task.dependsOn(podGenTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,15 +539,15 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
}
|
||||
sdks += sdk
|
||||
|
||||
val podGenTaskProvider = project.tasks.named(target.konanTarget.family.toPodGenTaskName, PodGenTask::class.java)
|
||||
project.tasks.register(sdk.toSetupBuildTaskName(pod), PodSetupBuildTask::class.java) {
|
||||
it.group = TASK_GROUP
|
||||
it.description = "Collect environment variables from .xcworkspace file"
|
||||
it.pod = project.provider { pod }
|
||||
it.sdk = project.provider { sdk }
|
||||
it.podsXcodeProjDir = podGenTaskProvider.map { podGen -> podGen.podsXcodeProjDir.get() }
|
||||
it.frameworkName = cocoapodsExtension.podFrameworkName
|
||||
it.dependsOn(podGenTaskProvider)
|
||||
val podInstallTask = project.tasks.named<PodInstallSyntheticTask>(target.konanTarget.family.toPodInstallSyntheticTaskName)
|
||||
project.registerTask<PodSetupBuildTask>(sdk.toSetupBuildTaskName(pod)) { task ->
|
||||
task.group = TASK_GROUP
|
||||
task.description = "Collect environment variables from .xcworkspace file"
|
||||
task.pod = project.provider { pod }
|
||||
task.sdk = project.provider { sdk }
|
||||
task.podsXcodeProjDir = podInstallTask.map { it.podsXcodeProjDirProvider.get() }
|
||||
task.frameworkName = cocoapodsExtension.podFrameworkName
|
||||
task.dependsOn(podInstallTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -772,7 +791,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
injectPodspecExtensionToArtifacts(project, kotlinArtifactsExtension, cocoapodsExtension)
|
||||
registerPodspecTask(project, cocoapodsExtension)
|
||||
|
||||
registerPodGenTask(project, kotlinExtension, cocoapodsExtension)
|
||||
registerSyntheticPodTasks(project, kotlinExtension, cocoapodsExtension)
|
||||
registerPodInstallTask(project, cocoapodsExtension)
|
||||
registerPodSetupBuildTasks(project, kotlinExtension, cocoapodsExtension)
|
||||
registerPodBuildTasks(project, kotlinExtension, cocoapodsExtension)
|
||||
|
||||
+1
-3
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.native.cocoapods
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.SpecRepos
|
||||
|
||||
@@ -20,8 +19,7 @@ class MissingSpecReposMessage(override val missingInfo: SpecRepos) : MissingInfo
|
||||
}
|
||||
|
||||
class MissingCocoapodsMessage(
|
||||
override val missingInfo: CocoapodsDependency,
|
||||
private val project: Project
|
||||
override val missingInfo: CocoapodsDependency
|
||||
) : MissingInfoMessage<CocoapodsDependency> {
|
||||
override val missingMessage: String
|
||||
get() = "pod '${missingInfo.name}'${missingInfo.source?.let { ", ${it.getPodSourcePath()}" }.orEmpty()}"
|
||||
|
||||
+161
-189
@@ -8,46 +8,30 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.native.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.FileTree
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
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.CocoapodsExtension.CocoapodsDependency.PodLocation.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.platformLiteral
|
||||
import org.jetbrains.kotlin.gradle.targets.native.cocoapods.MissingCocoapodsMessage
|
||||
import org.jetbrains.kotlin.gradle.targets.native.cocoapods.MissingSpecReposMessage
|
||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrievePods
|
||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrieveSpecRepos
|
||||
import org.jetbrains.kotlin.gradle.utils.runCommand
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.Reader
|
||||
import java.util.*
|
||||
|
||||
private val Family.platformLiteral: String
|
||||
get() = when (this) {
|
||||
Family.OSX -> "macos"
|
||||
Family.IOS -> "ios"
|
||||
Family.TVOS -> "tvos"
|
||||
Family.WATCHOS -> "watchos"
|
||||
else -> throw IllegalArgumentException("Bad family ${this.name}")
|
||||
}
|
||||
|
||||
val CocoapodsDependency.schemeName: String
|
||||
get() = name.split("/")[0]
|
||||
|
||||
/**
|
||||
* The task takes the path to the Podfile and calls `pod install`
|
||||
* to obtain sources or artifacts for the declared dependencies.
|
||||
* This task is a part of CocoaPods integration infrastructure.
|
||||
*/
|
||||
|
||||
open class CocoapodsTask : DefaultTask() {
|
||||
init {
|
||||
@@ -58,61 +42,164 @@ open class CocoapodsTask : DefaultTask() {
|
||||
}
|
||||
|
||||
|
||||
open class PodInstallTask : CocoapodsTask() {
|
||||
/**
|
||||
* The task takes the path to the Podfile and calls `pod install`
|
||||
* to obtain sources or artifacts for the declared dependencies.
|
||||
* This task is a part of CocoaPods integration infrastructure.
|
||||
*/
|
||||
abstract class AbstractPodInstallTask : CocoapodsTask() {
|
||||
init {
|
||||
onlyIf { podfile.isPresent }
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var frameworkName: Provider<String>
|
||||
|
||||
@get:Optional
|
||||
@get:PathSensitive(PathSensitivity.ABSOLUTE)
|
||||
@get:InputFile
|
||||
internal val podfile = project.objects.property(File::class.java)
|
||||
abstract val podfile: Property<File?>
|
||||
|
||||
@get:Optional
|
||||
@get:PathSensitive(PathSensitivity.ABSOLUTE)
|
||||
@get:InputFile
|
||||
internal val podspec = project.objects.property(File::class.java)
|
||||
protected val workingDir: Provider<File> = podfile.map { file: File? ->
|
||||
requireNotNull(file) { "Task outputs shouldn't be queried if it's skipped" }.parentFile
|
||||
}
|
||||
|
||||
@get:Optional
|
||||
@get:OutputDirectory
|
||||
internal val podsXcodeProjDirProvider: Provider<File>?
|
||||
get() = podfile.orNull?.let {
|
||||
project.provider { it.parentFile.resolve("Pods").resolve("Pods.xcodeproj") }
|
||||
}
|
||||
internal val podsDir: Provider<File> = workingDir.map { it.resolve("Pods") }
|
||||
|
||||
@get:Internal
|
||||
internal val podsXcodeProjDirProvider: Provider<File> = podsDir.map { it.resolve("Pods.xcodeproj") }
|
||||
|
||||
@TaskAction
|
||||
fun doPodInstall() {
|
||||
podfile.orNull?.parentFile?.also { podfileDir ->
|
||||
val podInstallCommand = listOf("pod", "install")
|
||||
open fun doPodInstall() {
|
||||
val podInstallCommand = listOf("pod", "install")
|
||||
|
||||
runCommand(podInstallCommand,
|
||||
logger,
|
||||
errorHandler = { returnCode, output, _ ->
|
||||
CocoapodsErrorHandlingUtil.handlePodInstallError(
|
||||
podInstallCommand.joinToString(" "),
|
||||
returnCode,
|
||||
output,
|
||||
project,
|
||||
frameworkName.get()
|
||||
)
|
||||
},
|
||||
exceptionHandler = { e: IOException ->
|
||||
CocoapodsErrorHandlingUtil.handle(e, podInstallCommand)
|
||||
},
|
||||
processConfiguration = {
|
||||
directory(podfileDir)
|
||||
})
|
||||
runCommand(podInstallCommand,
|
||||
logger,
|
||||
errorHandler = ::handleError,
|
||||
exceptionHandler = { e: IOException ->
|
||||
CocoapodsErrorHandlingUtil.handle(e, podInstallCommand)
|
||||
},
|
||||
processConfiguration = {
|
||||
directory(workingDir.get())
|
||||
})
|
||||
|
||||
with(podsXcodeProjDirProvider) {
|
||||
check(this != null && get().exists() && get().isDirectory) {
|
||||
"The directory 'Pods/Pods.xcodeproj' was not created as a result of the `pod install` call."
|
||||
}
|
||||
with(podsXcodeProjDirProvider.get()) {
|
||||
check(exists() && isDirectory) {
|
||||
"The directory 'Pods/Pods.xcodeproj' was not created as a result of the `pod install` call."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun handleError(retCode: Int, error: String, process: Process): String?
|
||||
}
|
||||
|
||||
abstract class PodInstallTask : AbstractPodInstallTask() {
|
||||
|
||||
|
||||
@get:Optional
|
||||
@get:InputFile
|
||||
abstract val podspec: Property<File?>
|
||||
|
||||
@get:Input
|
||||
abstract val frameworkName: Property<String>
|
||||
|
||||
@get:Nested
|
||||
abstract val specRepos: Property<SpecRepos>
|
||||
|
||||
@get:Nested
|
||||
abstract val pods: ListProperty<CocoapodsDependency>
|
||||
|
||||
override fun handleError(retCode: Int, error: String, process: Process): String? {
|
||||
val specReposMessages = MissingSpecReposMessage(specRepos.get()).missingMessage
|
||||
val cocoapodsMessages = pods.get().map { MissingCocoapodsMessage(it).missingMessage }
|
||||
|
||||
return listOfNotNull(
|
||||
"'pod install' command failed with code $retCode.",
|
||||
"Error message:",
|
||||
error.lines().filter { it.isNotBlank() }.joinToString("\n"),
|
||||
"""
|
||||
| Please, check that podfile contains following lines in header:
|
||||
| $specReposMessages
|
||||
|
|
||||
""".trimMargin(),
|
||||
"""
|
||||
| Please, check that each target depended on ${frameworkName.get()} contains following dependencies:
|
||||
| ${cocoapodsMessages.joinToString("\n")}
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
).joinToString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PodInstallSyntheticTask : AbstractPodInstallTask() {
|
||||
|
||||
@get:Input
|
||||
abstract val family: Property<Family>
|
||||
|
||||
@get:Input
|
||||
abstract val podName: Property<String>
|
||||
|
||||
@get:OutputDirectory
|
||||
internal val syntheticXcodeProject: Provider<File> = workingDir.map { it.resolve("synthetic.xcodeproj") }
|
||||
|
||||
override fun doPodInstall() {
|
||||
val projResource = "/cocoapods/project.pbxproj"
|
||||
val projDestination = syntheticXcodeProject.get().resolve("project.pbxproj")
|
||||
|
||||
syntheticXcodeProject.get().mkdirs()
|
||||
projDestination.outputStream().use { file ->
|
||||
javaClass.getResourceAsStream(projResource)!!.use { resource ->
|
||||
resource.copyTo(file)
|
||||
}
|
||||
}
|
||||
|
||||
super.doPodInstall()
|
||||
}
|
||||
|
||||
override fun handleError(retCode: Int, error: String, process: Process): String? {
|
||||
var message = """
|
||||
|'pod install' command on the synthetic project failed with return code: $retCode
|
||||
|
|
||||
| Error: ${error.lines().filter { it.contains("[!]") }.joinToString("\n")}
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
if (
|
||||
error.contains("deployment target") ||
|
||||
error.contains("no platform was specified") ||
|
||||
error.contains(Regex("The platform of the target .+ is not compatible with `${podName.get()}"))
|
||||
) {
|
||||
message += """
|
||||
|
|
||||
| Possible reason: ${family.get().platformLiteral} deployment target is not configured
|
||||
| Configure deployment_target for ALL targets as follows:
|
||||
| cocoapods {
|
||||
| ...
|
||||
| ${family.get().platformLiteral}.deploymentTarget = "..."
|
||||
| ...
|
||||
| }
|
||||
|
|
||||
""".trimMargin()
|
||||
return message
|
||||
} else if (
|
||||
error.contains("Unable to add a source with url") ||
|
||||
error.contains("Couldn't determine repo name for URL") ||
|
||||
error.contains("Unable to find a specification")
|
||||
) {
|
||||
message += """
|
||||
|
|
||||
| Possible reason: spec repos are not configured correctly.
|
||||
| Ensure that spec repos are correctly configured for all private pod dependencies:
|
||||
| cocoapods {
|
||||
| specRepos {
|
||||
| url("<private spec repo url>")
|
||||
| }
|
||||
| }
|
||||
|
|
||||
""".trimMargin()
|
||||
return message
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,82 +213,39 @@ abstract class PodGenTask : CocoapodsTask() {
|
||||
}
|
||||
}
|
||||
|
||||
@get:PathSensitive(PathSensitivity.ABSOLUTE)
|
||||
@get:InputFile
|
||||
internal lateinit var podspec: Provider<File>
|
||||
internal abstract val podspec: Property<File>
|
||||
|
||||
@get:Input
|
||||
internal lateinit var podName: Provider<String>
|
||||
internal abstract val podName: Property<String>
|
||||
|
||||
@get:Input
|
||||
internal lateinit var useLibraries: Provider<Boolean>
|
||||
internal abstract val useLibraries: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
lateinit var family: Family
|
||||
@get:Input
|
||||
internal abstract val family: Property<Family>
|
||||
|
||||
@get:Nested
|
||||
internal lateinit var platformSettings: PodspecPlatformSettings
|
||||
internal abstract val platformSettings: Property<PodspecPlatformSettings>
|
||||
|
||||
@get:Nested
|
||||
internal lateinit var specRepos: Provider<SpecRepos>
|
||||
internal abstract val specRepos: Property<SpecRepos>
|
||||
|
||||
@get:Nested
|
||||
abstract val pods: ListProperty<CocoapodsDependency>
|
||||
internal abstract val pods: ListProperty<CocoapodsDependency>
|
||||
|
||||
@get:OutputDirectory
|
||||
internal val outputDir: Provider<File> = project.provider { project.cocoapodsBuildDirs.synthetic(family) }
|
||||
|
||||
@get:Internal
|
||||
internal val podsXcodeProjDir: Provider<File> = outputDir.map { it.resolve("Pods").resolve("Pods.xcodeproj") }
|
||||
|
||||
@get:Internal
|
||||
val podfile: Provider<File> = outputDir.map { it.resolve("Podfile") }
|
||||
@get:OutputFile
|
||||
val podfile: Provider<File> = family.map { project.cocoapodsBuildDirs.synthetic(it).resolve("Podfile") }
|
||||
|
||||
@TaskAction
|
||||
fun generate() {
|
||||
val syntheticDir = outputDir.get().apply { mkdirs() }
|
||||
val specRepos = specRepos.get().getAll()
|
||||
|
||||
val projResource = "/cocoapods/project.pbxproj"
|
||||
val projDestination = syntheticDir.resolve("synthetic.xcodeproj").resolve("project.pbxproj")
|
||||
|
||||
projDestination.parentFile.mkdirs()
|
||||
projDestination.outputStream().use { file ->
|
||||
javaClass.getResourceAsStream(projResource)!!.use { resource ->
|
||||
resource.copyTo(file)
|
||||
}
|
||||
}
|
||||
|
||||
val podfile = this.podfile.get()
|
||||
podfile.createNewFile()
|
||||
|
||||
val podfileContent = getPodfileContent(specRepos, family.platformLiteral)
|
||||
val podfileContent = getPodfileContent(specRepos, family.get().platformLiteral)
|
||||
podfile.writeText(podfileContent)
|
||||
val podInstallCommand = listOf("pod", "install")
|
||||
|
||||
runCommand(
|
||||
podInstallCommand,
|
||||
project.logger,
|
||||
exceptionHandler = { e: IOException ->
|
||||
CocoapodsErrorHandlingUtil.handle(e, podInstallCommand)
|
||||
},
|
||||
errorHandler = { retCode, output, _ ->
|
||||
CocoapodsErrorHandlingUtil.handlePodInstallSyntheticError(
|
||||
podInstallCommand.joinToString(" "),
|
||||
retCode,
|
||||
output,
|
||||
family,
|
||||
podName.get()
|
||||
)
|
||||
},
|
||||
processConfiguration = {
|
||||
directory(syntheticDir)
|
||||
})
|
||||
|
||||
val podsXcprojFile = podsXcodeProjDir.get()
|
||||
check(podsXcprojFile.exists() && podsXcprojFile.isDirectory) {
|
||||
"Synthetic project '${podsXcprojFile.path}' was not created."
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPodfileContent(specRepos: Collection<String>, xcodeTarget: String) =
|
||||
@@ -215,11 +259,12 @@ abstract class PodGenTask : CocoapodsTask() {
|
||||
if (useLibraries.get().not()) {
|
||||
appendLine("\tuse_frameworks!")
|
||||
}
|
||||
val deploymentTarget = platformSettings.deploymentTarget
|
||||
val settings = platformSettings.get()
|
||||
val deploymentTarget = settings.deploymentTarget
|
||||
if (deploymentTarget != null) {
|
||||
appendLine("\tplatform :${platformSettings.name}, '$deploymentTarget'")
|
||||
appendLine("\tplatform :${settings.name}, '$deploymentTarget'")
|
||||
} else {
|
||||
appendLine("\tplatform :${platformSettings.name}")
|
||||
appendLine("\tplatform :${settings.name}")
|
||||
}
|
||||
pods.get().mapNotNull {
|
||||
buildString {
|
||||
@@ -251,6 +296,7 @@ abstract class PodGenTask : CocoapodsTask() {
|
||||
end
|
||||
""".trimIndent()
|
||||
)
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +449,7 @@ data class PodBuildSettingsProperties(
|
||||
|
||||
fun readSettingsFromReader(reader: Reader): PodBuildSettingsProperties {
|
||||
with(Properties()) {
|
||||
@Suppress("BlockingMethodInNonBlockingContext") // It's ok to do blocking call here
|
||||
load(reader)
|
||||
return PodBuildSettingsProperties(
|
||||
readProperty(BUILD_DIR),
|
||||
@@ -448,79 +495,4 @@ private object CocoapodsErrorHandlingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
fun handlePodInstallError(command: String, retCode: Int, error: String, project: Project, frameworkName: String): String {
|
||||
val specReposMessages = retrieveSpecRepos(project)?.let { MissingSpecReposMessage(it).missingMessage }
|
||||
val cocoapodsMessages = retrievePods(project)?.map { MissingCocoapodsMessage(it, project).missingMessage }
|
||||
|
||||
return listOfNotNull(
|
||||
"'pod install' command failed with code $retCode.",
|
||||
"Full command: $command",
|
||||
"Error message:",
|
||||
error.lines().filter { it.isNotBlank() }.joinToString("\n"),
|
||||
specReposMessages?.let {
|
||||
"""
|
||||
| Please, check that podfile contains following lines in header:
|
||||
| $it
|
||||
|
|
||||
""".trimMargin()
|
||||
},
|
||||
cocoapodsMessages?.let {
|
||||
"""
|
||||
| Please, check that each target depended on $frameworkName contains following dependencies:
|
||||
| ${it.joinToString("\n")}
|
||||
|
|
||||
""".trimMargin()
|
||||
}
|
||||
|
||||
).joinToString("\n")
|
||||
}
|
||||
|
||||
fun handlePodInstallSyntheticError(command: String, retCode: Int, error: String, family: Family, podName: String): String? {
|
||||
var message = """
|
||||
|'pod install' command on the synthetic project failed with return code: $retCode
|
||||
|
|
||||
| Full command: $command
|
||||
|
|
||||
| Error: ${error.lines().filter { it.contains("[!]") }.joinToString("\n")}
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
if (
|
||||
error.contains("deployment target") ||
|
||||
error.contains("no platform was specified") ||
|
||||
error.contains(Regex("The platform of the target .+ is not compatible with `$podName"))
|
||||
) {
|
||||
message += """
|
||||
|
|
||||
| Possible reason: ${family.name.toLowerCaseAsciiOnly()} deployment target is not configured
|
||||
| Configure deployment_target for ALL targets as follows:
|
||||
| cocoapods {
|
||||
| ...
|
||||
| ${family.name.toLowerCaseAsciiOnly()}.deploymentTarget = "..."
|
||||
| ...
|
||||
| }
|
||||
|
|
||||
""".trimMargin()
|
||||
return message
|
||||
} else if (
|
||||
error.contains("Unable to add a source with url") ||
|
||||
error.contains("Couldn't determine repo name for URL") ||
|
||||
error.contains("Unable to find a specification")
|
||||
) {
|
||||
message += """
|
||||
|
|
||||
| Possible reason: spec repos are not configured correctly.
|
||||
| Ensure that spec repos are correctly configured for all private pod dependencies:
|
||||
| cocoapods {
|
||||
| specRepos {
|
||||
| url("<private spec repo url>")
|
||||
| }
|
||||
| }
|
||||
|
|
||||
""".trimMargin()
|
||||
return message
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-2
@@ -221,8 +221,6 @@ open class PodspecTask : DefaultTask() {
|
||||
else project.multiplatformExtensionOrNull?.cocoapodsExtensionOrNull?.podfile != null
|
||||
|| (project.parent?.let { hasPodfileOwnOrParent(it) } ?: false)
|
||||
|
||||
internal fun retrieveSpecRepos(project: Project): SpecRepos? = project.multiplatformExtensionOrNull?.cocoapodsExtensionOrNull?.specRepos
|
||||
internal fun retrievePods(project: Project): List<CocoapodsDependency>? = project.multiplatformExtensionOrNull?.cocoapodsExtensionOrNull?.podsAsTaskInput
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user