[Gradle] Support dependencies between pods in CocoaPods plugin
^KT-38749 Verification Pending
This commit is contained in:
committed by
Space Team
parent
b36e1f1a5b
commit
4b66160afb
+41
@@ -1299,6 +1299,47 @@ class CocoaPodsIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hierarchy of dependant pods compiles successfully`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
build(
|
||||
":compileKotlinIosX64",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true",
|
||||
) {
|
||||
assertSuccessful()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `configuration fails when trying to depend on non-declared pod`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
pod("Foo") { useInteropBindingFrom("JBNonExistent") }
|
||||
""".trimIndent())
|
||||
|
||||
build(
|
||||
":help",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true",
|
||||
) {
|
||||
assertFailed()
|
||||
assertContains("Couldn't find declaration of pod 'JBNonExistent' (interop-binding dependency of pod 'Foo')")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `configuration fails when dependant pods are in the wrong order`() = with(getProjectByName("native-cocoapods-dependant-pods")) {
|
||||
gradleBuildScript().appendToCocoapodsBlock("""
|
||||
pod("Foo") { useInteropBindingFrom("Bar") }
|
||||
pod("Bar")
|
||||
""".trimIndent())
|
||||
|
||||
build(
|
||||
":help",
|
||||
"-Pkotlin.native.cocoapods.generate.wrapper=true",
|
||||
) {
|
||||
assertFailed()
|
||||
assertContains("Couldn't find declaration of pod 'Bar' (interop-binding dependency of pod 'Foo')")
|
||||
}
|
||||
}
|
||||
|
||||
// test configuration phase
|
||||
|
||||
private class CustomHooks {
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
kotlin("multiplatform") version "<pluginMarkerVersion>"
|
||||
kotlin("native.cocoapods") version "<pluginMarkerVersion>"
|
||||
}
|
||||
|
||||
group = "org.jetbrains.kotlin.sample.native"
|
||||
version = "1.0"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
iosX64()
|
||||
|
||||
cocoapods {
|
||||
summary = "Some description for the Shared Module"
|
||||
homepage = "Link to the Shared Module homepage"
|
||||
version = "1.0"
|
||||
ios.deploymentTarget = "14.1"
|
||||
framework {
|
||||
baseName = "shared"
|
||||
}
|
||||
|
||||
pod("pod1", path = project.file("pod1"))
|
||||
|
||||
pod("pod2") {
|
||||
source = path(project.file("pod2"))
|
||||
|
||||
useInteropBindingFrom("pod1")
|
||||
|
||||
extraOpts = listOf("-compiler-option", "-fmodules")
|
||||
}
|
||||
|
||||
pod("pod3") {
|
||||
source = path(project.file("pod3"))
|
||||
|
||||
interopBindingDependencies.add("pod1")
|
||||
}
|
||||
|
||||
pod("pod4") {
|
||||
source = path(project.file("pod4"))
|
||||
|
||||
useInteropBindingFrom("pod2")
|
||||
useInteropBindingFrom("pod3")
|
||||
|
||||
extraOpts = listOf("-compiler-option", "-fmodules")
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
@interface Pod1 : NSObject
|
||||
-(int)pod1;
|
||||
-(void)name: (NSString *) firstName secondName: (NSString *) secondName;
|
||||
@end
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#include <pod1.h>
|
||||
|
||||
@implementation Pod1
|
||||
|
||||
-(int)pod1 {
|
||||
return 42;
|
||||
}
|
||||
|
||||
-(void)name: (NSString *) firstName secondName: (NSString *) secondName {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'pod1'
|
||||
spec.version = '1.0'
|
||||
spec.homepage = 'repro'
|
||||
spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
||||
spec.authors = ''
|
||||
spec.license = ''
|
||||
spec.summary = 'repro'
|
||||
|
||||
spec.source_files = '*.{h,m}'
|
||||
spec.public_header_files = '*.h'
|
||||
end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'pod2'
|
||||
spec.version = '1.0'
|
||||
spec.homepage = 'repro'
|
||||
spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
||||
spec.authors = ''
|
||||
spec.license = ''
|
||||
spec.summary = 'repro'
|
||||
|
||||
spec.dependency 'pod1'
|
||||
|
||||
spec.swift_version = '5.0'
|
||||
spec.source_files = '*.swift'
|
||||
end
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import pod1
|
||||
|
||||
@objc
|
||||
open class Pod2: Pod1 {
|
||||
@objc
|
||||
public func pod2() -> Int32 {
|
||||
return 33
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#import "pod1/pod1.h"
|
||||
|
||||
@interface Pod3 : Pod1
|
||||
-(int)pod3;
|
||||
@end
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#include <pod3.h>
|
||||
|
||||
@implementation Pod3
|
||||
|
||||
-(int)pod3 {
|
||||
return 42;
|
||||
}
|
||||
|
||||
@end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'pod3'
|
||||
spec.version = '1.0'
|
||||
spec.homepage = 'repro'
|
||||
spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
||||
spec.authors = ''
|
||||
spec.license = ''
|
||||
spec.summary = 'repro'
|
||||
|
||||
spec.source_files = '*.{h,m}'
|
||||
spec.public_header_files = '*.h'
|
||||
|
||||
spec.dependency 'pod1'
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'pod4'
|
||||
spec.version = '1.0'
|
||||
spec.homepage = 'repro'
|
||||
spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
||||
spec.authors = ''
|
||||
spec.license = ''
|
||||
spec.summary = 'repro'
|
||||
|
||||
spec.dependency 'pod2'
|
||||
spec.dependency 'pod3'
|
||||
|
||||
spec.swift_version = '5.0'
|
||||
spec.source_files = '*.swift'
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import pod2
|
||||
import pod3
|
||||
|
||||
@objc
|
||||
public class Pod42: Pod2 {
|
||||
@objc
|
||||
public func pod4() -> String {
|
||||
return "Hello"
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public class Pod43: Pod3 {
|
||||
@objc
|
||||
public func pod4() -> String {
|
||||
return "Hello"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
rootProject.name = "cocoapods"
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import cocoapods.pod1.Pod1
|
||||
import cocoapods.pod2.Pod2
|
||||
import cocoapods.pod3.Pod3
|
||||
import cocoapods.pod4.Pod42
|
||||
import cocoapods.pod4.Pod43
|
||||
|
||||
fun printPod1(p: Pod1) {
|
||||
println(p.pod1())
|
||||
}
|
||||
|
||||
fun printPod2(p: Pod2) {
|
||||
println("Hi from Kt!")
|
||||
println(p.pod2())
|
||||
printPod1(p)
|
||||
}
|
||||
|
||||
fun printPod3(p: Pod3) {
|
||||
printPod1(p)
|
||||
}
|
||||
|
||||
fun printPods4(p42: Pod42, p43: Pod43) {
|
||||
printPod2(p42)
|
||||
printPod3(p43)
|
||||
printPod1(p42)
|
||||
printPod1(p43)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
printPods4(Pod42(), Pod43())
|
||||
}
|
||||
+22
-1
@@ -20,7 +20,7 @@ import java.io.File
|
||||
import java.net.URI
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("unused") // Public API
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate") // Public API
|
||||
abstract class CocoapodsExtension @Inject constructor(private val project: Project) {
|
||||
/**
|
||||
* Configure version of the pod
|
||||
@@ -292,6 +292,27 @@ abstract class CocoapodsExtension @Inject constructor(private val project: Proje
|
||||
@get:Input
|
||||
var linkOnly: Boolean = false
|
||||
|
||||
/**
|
||||
* Contains a list of dependencies to other pods. This list will be used while building an interop Kotlin-binding for the pod.
|
||||
*
|
||||
* @see useInteropBindingFrom
|
||||
*/
|
||||
@get:Input
|
||||
val interopBindingDependencies: MutableList<String> = mutableListOf()
|
||||
|
||||
/**
|
||||
* Specify that the pod depends on another pod **podName** and a Kotlin-binding for **podName** should be used while building
|
||||
* a binding for the pod. This is necessary if you need to operate entities from **podName** and from the pod together, for
|
||||
* instance pass an object from **podName** to the pod in Kotlin.
|
||||
*
|
||||
* A pod with the exact name must be declared before calling this function.
|
||||
*
|
||||
* @see interopBindingDependencies
|
||||
*/
|
||||
fun useInteropBindingFrom(podName: String) {
|
||||
interopBindingDependencies.add(podName)
|
||||
}
|
||||
|
||||
@Input
|
||||
override fun getName(): String = name
|
||||
|
||||
|
||||
+29
-2
@@ -7,6 +7,7 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.cocoapods
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
@@ -326,12 +327,17 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
kotlinExtension.supportedTargets().all { target ->
|
||||
target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).cinterops.create(pod.moduleName) { interop ->
|
||||
val cinterops = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).cinterops
|
||||
cinterops.create(pod.moduleName) { interop ->
|
||||
|
||||
val interopTask = project.tasks.getByPath(interop.interopProcessingTaskName)
|
||||
val interopTask = project.tasks.named<CInteropProcess>(interop.interopProcessingTaskName).get()
|
||||
|
||||
interopTask.dependsOn(defTask)
|
||||
|
||||
pod.interopBindingDependencies.forEach { dependencyName ->
|
||||
addPodDependencyToInterop(project, cocoapodsExtension, pod, cinterops, interop, dependencyName)
|
||||
}
|
||||
|
||||
with(interop) {
|
||||
defFileProperty.set(defTask.map { it.outputFile })
|
||||
_packageNameProp.set(project.provider { pod.packageName })
|
||||
@@ -364,6 +370,27 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPodDependencyToInterop(
|
||||
project: Project,
|
||||
cocoapodsExtension: CocoapodsExtension,
|
||||
pod: CocoapodsDependency,
|
||||
cinterops: NamedDomainObjectContainer<DefaultCInteropSettings>,
|
||||
interop: DefaultCInteropSettings,
|
||||
dependencyName: String,
|
||||
) {
|
||||
val dependencyPod = cocoapodsExtension.pods.findByName(dependencyName)
|
||||
?: error("Couldn't find declaration of pod '$dependencyName' (interop-binding dependency of pod '${pod.name}')")
|
||||
|
||||
val dependencyTaskName = cinterops.getByName(dependencyPod.moduleName).interopProcessingTaskName
|
||||
val dependencyTask = project.tasks.named<CInteropProcess>(dependencyTaskName)
|
||||
|
||||
interop.dependencyFiles += project.files(dependencyTask.map { it.outputFile }).builtBy(dependencyTask)
|
||||
|
||||
dependencyPod.interopBindingDependencies.forEach { transitiveDependency ->
|
||||
addPodDependencyToInterop(project, cocoapodsExtension, pod, cinterops, interop, transitiveDependency)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerDummyFrameworkTask(
|
||||
project: Project,
|
||||
cocoapodsExtension: CocoapodsExtension
|
||||
|
||||
Reference in New Issue
Block a user