[Gradle, Cocoapods] refactor I/O, improve Up-To-Date
all synthetic tasks are per pod tasks receive parts of extension as inputs
This commit is contained in:
+345
-43
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.DUMMY_FRAMEWORK_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.DUMMY_FRAMEWORK_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_BUILD_DEPENDENCIES_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_BUILD_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_DOWNLOAD_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_DOWNLOAD_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_GEN_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_GEN_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_IMPORT_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_IMPORT_TASK_NAME
|
||||||
@@ -16,10 +16,8 @@ import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Compan
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SPEC_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.POD_SPEC_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.util.modify
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.junit.Assume.assumeFalse
|
|
||||||
import org.junit.Assume.assumeTrue
|
import org.junit.Assume.assumeTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Ignore
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@@ -46,7 +44,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
private val podspecTaskName = ":$POD_SPEC_TASK_NAME"
|
private val podspecTaskName = ":$POD_SPEC_TASK_NAME"
|
||||||
private val podDownloadTaskName = ":$POD_DOWNLOAD_TASK_NAME"
|
private val podDownloadTaskName = ":$POD_DOWNLOAD_TASK_NAME"
|
||||||
private val podGenTaskName = ":$POD_GEN_TASK_NAME"
|
private val podGenTaskName = ":$POD_GEN_TASK_NAME"
|
||||||
private val podBuildTaskName = ":$POD_BUILD_DEPENDENCIES_TASK_NAME"
|
private val podBuildTaskName = ":$POD_BUILD_TASK_NAME"
|
||||||
private val podSetupBuildTaskName = ":$POD_SETUP_BUILD_TASK_NAME"
|
private val podSetupBuildTaskName = ":$POD_SETUP_BUILD_TASK_NAME"
|
||||||
private val podImportTaskName = ":$POD_IMPORT_TASK_NAME"
|
private val podImportTaskName = ":$POD_IMPORT_TASK_NAME"
|
||||||
private val podInstallTaskName = ":$POD_INSTALL_TASK_NAME"
|
private val podInstallTaskName = ":$POD_INSTALL_TASK_NAME"
|
||||||
@@ -54,14 +52,30 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
|
|
||||||
private val defaultPodRepo = "https://github.com/AFNetworking/AFNetworking"
|
private val defaultPodRepo = "https://github.com/AFNetworking/AFNetworking"
|
||||||
private val defaultPodName = "AFNetworking"
|
private val defaultPodName = "AFNetworking"
|
||||||
|
private val downloadUrlPodName = "podspecWithFilesExample"
|
||||||
|
private val downloadUrlRepoName = "https://github.com/alozhkin/podspecWithFilesExample/raw/master"
|
||||||
private val defaultTarget = "IOS"
|
private val defaultTarget = "IOS"
|
||||||
private val defaultFamily = "IOS"
|
private val defaultFamily = "IOS"
|
||||||
private val defaultSDK = "iphonesimulator"
|
private val defaultSDK = "iphonesimulator"
|
||||||
private val defaultPodDownloadTaskName = podDownloadTaskName + defaultPodName
|
private val defaultPodDownloadTaskName = podDownloadFullTaskName()
|
||||||
private val defaultPodGenTaskName = podGenTaskName + defaultFamily
|
private val defaultPodGenTaskName = podGenFullTaskName()
|
||||||
private val defaultBuildTaskName = podBuildTaskName + defaultSDK.capitalize()
|
private val defaultBuildTaskName = podBuildFullTaskName()
|
||||||
private val defaultSetupBuildTaskName = podSetupBuildTaskName + defaultSDK.capitalize()
|
private val defaultSetupBuildTaskName = podSetupBuildFullTaskName()
|
||||||
private val defaultCinteropTaskName = cinteropTaskName + defaultPodName + defaultTarget
|
private val defaultCinteropTaskName = cinteropTaskName + defaultPodName + defaultTarget
|
||||||
|
private val downloadUrlTaskName = podDownloadTaskName + downloadUrlPodName.capitalize()
|
||||||
|
|
||||||
|
private fun podDownloadFullTaskName(podName: String = defaultPodName) = podDownloadTaskName + podName.capitalize()
|
||||||
|
|
||||||
|
private fun podGenFullTaskName(familyName: String = defaultFamily) = podGenTaskName + familyName.capitalize()
|
||||||
|
|
||||||
|
private fun podSetupBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||||
|
podSetupBuildTaskName + podName.capitalize() + sdkName.capitalize()
|
||||||
|
|
||||||
|
private fun podBuildFullTaskName(podName: String = defaultPodName, sdkName: String = defaultSDK) =
|
||||||
|
podBuildTaskName + podName.capitalize() + sdkName.capitalize()
|
||||||
|
|
||||||
|
private fun cinteropFullTaskName(podName: String = defaultPodName, targetName: String = defaultTarget) =
|
||||||
|
cinteropTaskName + podName.capitalize() + targetName.capitalize()
|
||||||
|
|
||||||
private lateinit var hooks: CustomHooks
|
private lateinit var hooks: CustomHooks
|
||||||
private lateinit var project: BaseGradleIT.Project
|
private lateinit var project: BaseGradleIT.Project
|
||||||
@@ -118,10 +132,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPodImportUseFrameworksSingle() = doTestImportSingle(ImportMode.FRAMEWORKS)
|
fun testPodImportSingle() = doTestImportSingle()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPodImportUseModularHeadersSingle() = doTestImportSingle(ImportMode.MODULAR_HEADERS)
|
fun testPodImportMultiple() = doTestImportMultiple()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPodspecMultiple() = doTestPodspec(
|
fun testPodspecMultiple() = doTestPodspec(
|
||||||
@@ -173,20 +187,14 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPodImportUseFrameworksMultiple() = doTestImportMultiple(ImportMode.FRAMEWORKS)
|
fun testSpecReposImport() {
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testPodImportUseModularHeadersMultiple() = doTestImportMultiple(ImportMode.MODULAR_HEADERS)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSpecReposDownloads() {
|
|
||||||
val podName = "example"
|
val podName = "example"
|
||||||
val podRepo = "https://github.com/alozhkin/spec_repo_example"
|
val podRepo = "https://github.com/alozhkin/spec_repo"
|
||||||
with(project.gradleBuildScript()) {
|
with(project.gradleBuildScript()) {
|
||||||
addPod(podName)
|
addPod(podName)
|
||||||
addSpecRepo(podRepo)
|
addSpecRepo(podRepo)
|
||||||
}
|
}
|
||||||
project.testDownload(listOf(podRepo))
|
project.testImportWithAsserts(listOf(podRepo))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -275,19 +283,6 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
project.test(":kotlin-library:podDownload")
|
project.test(":kotlin-library:podDownload")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
|
||||||
fun testSubspecWithModuleName() {
|
|
||||||
with(project.gradleBuildScript()) {
|
|
||||||
addPod("AFNetworking/Reachability", "moduleName = \"CustomName\"")
|
|
||||||
addPod("AFNetworking/Security")
|
|
||||||
}
|
|
||||||
hooks.addHook {
|
|
||||||
assertTasksExecuted(defaultCinteropTaskName, cinteropTaskName + "AFNetworking/Security" + defaultTarget)
|
|
||||||
}
|
|
||||||
project.testImportWithAsserts()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// up-to-date tests
|
// up-to-date tests
|
||||||
|
|
||||||
@@ -355,6 +350,282 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
project.testSynthetic(defaultPodGenTaskName)
|
project.testSynthetic(defaultPodGenTaskName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDPodAdded() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
|
||||||
|
val anotherPodName = "Alamofire"
|
||||||
|
val anotherPodRepo = "https://github.com/Alamofire/Alamofire"
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(anotherPodName, produceGitBlock(anotherPodRepo))
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksExecuted(
|
||||||
|
podspecTaskName,
|
||||||
|
podDownloadFullTaskName(anotherPodName),
|
||||||
|
defaultPodGenTaskName,
|
||||||
|
podSetupBuildFullTaskName(anotherPodName),
|
||||||
|
podBuildFullTaskName(anotherPodName),
|
||||||
|
cinteropFullTaskName(anotherPodName)
|
||||||
|
)
|
||||||
|
assertTasksUpToDate(
|
||||||
|
defaultPodDownloadTaskName,
|
||||||
|
defaultSetupBuildTaskName,
|
||||||
|
defaultBuildTaskName,
|
||||||
|
defaultCinteropTaskName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo, anotherPodRepo))
|
||||||
|
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
removePod(anotherPodName)
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksNotRegisteredByPrefix(
|
||||||
|
listOf(
|
||||||
|
podDownloadFullTaskName(anotherPodName),
|
||||||
|
podBuildFullTaskName(anotherPodName),
|
||||||
|
cinteropFullTaskName(anotherPodName)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertTasksUpToDate(
|
||||||
|
defaultBuildTaskName,
|
||||||
|
defaultPodDownloadTaskName,
|
||||||
|
defaultSetupBuildTaskName,
|
||||||
|
defaultCinteropTaskName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testImportSubspecs() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod("SDWebImage/Core")
|
||||||
|
addPod("SDWebImage/MapKit")
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDTargetAdded() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(defaultPodName, produceGitBlock(defaultPodRepo))
|
||||||
|
appendToCocoapodsBlock("osx.deploymentTarget = \"13.5\"")
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
|
||||||
|
val anotherTarget = "MacosX64"
|
||||||
|
val anotherSdk = "macosx"
|
||||||
|
val anotherFamily = "OSX"
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
appendToKotlinBlock(anotherTarget.decapitalize() + "()")
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksExecuted(
|
||||||
|
podGenFullTaskName(anotherFamily),
|
||||||
|
podSetupBuildFullTaskName(sdkName = anotherSdk),
|
||||||
|
podBuildFullTaskName(sdkName = anotherSdk),
|
||||||
|
cinteropFullTaskName(targetName = anotherTarget)
|
||||||
|
)
|
||||||
|
assertTasksUpToDate(
|
||||||
|
podspecTaskName,
|
||||||
|
defaultPodDownloadTaskName,
|
||||||
|
defaultPodGenTaskName,
|
||||||
|
defaultSetupBuildTaskName,
|
||||||
|
defaultBuildTaskName,
|
||||||
|
defaultCinteropTaskName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
var text = readText()
|
||||||
|
text = text.replace(anotherTarget.decapitalize() + "()", "")
|
||||||
|
writeText(text)
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksNotRegisteredByPrefix(
|
||||||
|
listOf(
|
||||||
|
podGenFullTaskName(anotherFamily),
|
||||||
|
podSetupBuildFullTaskName(sdkName = anotherSdk),
|
||||||
|
podBuildFullTaskName(sdkName = anotherSdk),
|
||||||
|
cinteropFullTaskName(targetName = anotherTarget)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertTasksUpToDate(
|
||||||
|
podspecTaskName,
|
||||||
|
defaultPodDownloadTaskName,
|
||||||
|
defaultPodGenTaskName,
|
||||||
|
defaultSetupBuildTaskName,
|
||||||
|
defaultBuildTaskName,
|
||||||
|
defaultCinteropTaskName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
project.testImport(listOf(defaultPodRepo))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDPodspec() {
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(podspecTaskName)
|
||||||
|
}
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
appendToCocoapodsBlock("license = \"new license name\"")
|
||||||
|
}
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
appendToCocoapodsBlock("license = \"new license name\"")
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(podspecTaskName)
|
||||||
|
}
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDPodspecDeploymentTarget() {
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(podspecTaskName)
|
||||||
|
}
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
appendToCocoapodsBlock("ios.deploymentTarget = \"12.5\"")
|
||||||
|
}
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(podspecTaskName)
|
||||||
|
}
|
||||||
|
project.testWithWrapper(podspecTaskName)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDDownload() {
|
||||||
|
val gitRepo = downloadUrlRepoName.substringBeforeLast("/").substringBeforeLast("/")
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(downloadUrlPodName, produceGitBlock(repo = gitRepo))
|
||||||
|
}
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(downloadUrlTaskName)
|
||||||
|
}
|
||||||
|
project.testDownload(listOf(gitRepo))
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
changePod(downloadUrlPodName, produceGitBlock(repo = gitRepo, commitName = "f52f035018b4f3fe253d50ce85a7e0652a62ee9b"))
|
||||||
|
}
|
||||||
|
project.testDownload(listOf(gitRepo))
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(downloadUrlTaskName)
|
||||||
|
}
|
||||||
|
project.testDownload(listOf(gitRepo))
|
||||||
|
val podArchivePath = "$downloadUrlRepoName/$downloadUrlPodName.tar.gz"
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
changePod(downloadUrlPodName, "source = url(\"$podArchivePath\")")
|
||||||
|
}
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksExecuted(downloadUrlTaskName)
|
||||||
|
}
|
||||||
|
project.testDownload(listOf(podArchivePath))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDPodGen() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(defaultPodName)
|
||||||
|
}
|
||||||
|
val repos = listOf(
|
||||||
|
"https://github.com/alozhkin/spec_repo_example",
|
||||||
|
"https://github.com/alozhkin/spec_repo_example_2"
|
||||||
|
)
|
||||||
|
for (repo in repos) {
|
||||||
|
assumeTrue(isRepoAvailable(repo))
|
||||||
|
}
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(defaultPodGenTaskName)
|
||||||
|
}
|
||||||
|
project.testSynthetic(defaultPodGenTaskName)
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addSpecRepo("https://github.com/alozhkin/spec_repo_example")
|
||||||
|
}
|
||||||
|
project.testSynthetic(defaultPodGenTaskName)
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addSpecRepo("https://github.com/alozhkin/spec_repo_example_2")
|
||||||
|
}
|
||||||
|
project.testSynthetic(defaultPodGenTaskName)
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(defaultPodGenTaskName)
|
||||||
|
}
|
||||||
|
project.testSynthetic(defaultPodGenTaskName)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUTDBuild() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(defaultPodName, produceGitBlock())
|
||||||
|
}
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(defaultBuildTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
|
||||||
|
val repo = "$downloadUrlRepoName/$downloadUrlPodName.tar.gz"
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(downloadUrlPodName, "source = url(\"$repo\")")
|
||||||
|
}
|
||||||
|
val urlTaskName = podBuildFullTaskName(downloadUrlPodName)
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(defaultBuildTaskName)
|
||||||
|
assertTasksExecuted(urlTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
|
||||||
|
val anotherTarget = "MacosX64"
|
||||||
|
val anotherSdk = "macosx"
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
appendToCocoapodsBlock("osx.deploymentTarget = \"13.5\"")
|
||||||
|
appendToKotlinBlock(anotherTarget.decapitalize() + "()")
|
||||||
|
}
|
||||||
|
val anotherSdkDefaultPodTaskName = podBuildFullTaskName(sdkName = anotherSdk)
|
||||||
|
val anotherTargetUrlTaskName = podBuildFullTaskName(downloadUrlPodName, anotherSdk)
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(defaultBuildTaskName, urlTaskName)
|
||||||
|
assertTasksExecuted(anotherSdkDefaultPodTaskName, anotherTargetUrlTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
|
||||||
|
hooks.rewriteHooks {
|
||||||
|
assertTasksUpToDate(defaultBuildTaskName, urlTaskName, anotherSdkDefaultPodTaskName, anotherTargetUrlTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPodBuildUTDClean() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod(defaultPodName, produceGitBlock())
|
||||||
|
}
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(defaultBuildTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
|
||||||
|
hooks.rewriteHooks {}
|
||||||
|
project.test(":clean")
|
||||||
|
|
||||||
|
hooks.addHook {
|
||||||
|
assertTasksExecuted(defaultBuildTaskName)
|
||||||
|
}
|
||||||
|
project.testImport()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPodInstallWithoutPodFile() {
|
||||||
|
project.testSynthetic(podInstallTaskName)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// groovy tests
|
// groovy tests
|
||||||
|
|
||||||
@@ -395,6 +666,13 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
project.testImportWithAsserts(listOf(repo))
|
project.testImportWithAsserts(listOf(repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun supportPodsWithDependencies() {
|
||||||
|
with(project.gradleBuildScript()) {
|
||||||
|
addPod("AlamofireImage")
|
||||||
|
}
|
||||||
|
project.testImportWithAsserts()
|
||||||
|
}
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
|
|
||||||
@@ -408,7 +686,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
|
|
||||||
// test configuration phase
|
// test configuration phase
|
||||||
|
|
||||||
private class CustomHooks() {
|
private class CustomHooks {
|
||||||
private val hooks = mutableSetOf<CompiledProject.() -> Unit>()
|
private val hooks = mutableSetOf<CompiledProject.() -> Unit>()
|
||||||
|
|
||||||
fun addHook(hook: CompiledProject.() -> Unit) {
|
fun addHook(hook: CompiledProject.() -> Unit) {
|
||||||
@@ -427,21 +705,21 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doTestImportSingle(importMode: ImportMode) {
|
private fun doTestImportSingle() {
|
||||||
val project = getProjectByName(cocoapodsSingleKtPod)
|
val project = getProjectByName(cocoapodsSingleKtPod)
|
||||||
val subprojects = listOf("kotlin-library")
|
val subprojects = listOf("kotlin-library")
|
||||||
doTestPodImport(project, subprojects, importMode)
|
doTestPodImport(project, subprojects)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doTestImportMultiple(importMode: ImportMode) {
|
private fun doTestImportMultiple() {
|
||||||
val project = getProjectByName(cocoapodsMultipleKtPods)
|
val project = getProjectByName(cocoapodsMultipleKtPods)
|
||||||
val subprojects = listOf("kotlin-library", "second-library")
|
val subprojects = listOf("kotlin-library", "second-library")
|
||||||
doTestPodImport(project, subprojects, importMode)
|
doTestPodImport(project, subprojects)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doTestPodImport(project: BaseGradleIT.Project, subprojects: List<String>, importMode: ImportMode) {
|
private fun doTestPodImport(project: BaseGradleIT.Project, subprojects: List<String>) {
|
||||||
with(project) {
|
with(project) {
|
||||||
preparePodfile("ios-app", importMode)
|
preparePodfile("ios-app", ImportMode.FRAMEWORKS)
|
||||||
}
|
}
|
||||||
project.testImportWithAsserts()
|
project.testImportWithAsserts()
|
||||||
subprojects.forEach {
|
subprojects.forEach {
|
||||||
@@ -468,10 +746,10 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
project.testDownload(listOf(repo))
|
project.testDownload(listOf(repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doTestPodDownloadUrl(
|
private fun doTestPodDownloadUrl(
|
||||||
fileExtension: String,
|
fileExtension: String,
|
||||||
podName: String = "podspecWithFilesExample",
|
podName: String = downloadUrlPodName,
|
||||||
repoPath: String = "https://github.com/alozhkin/podspecWithFilesExample/raw/master",
|
repoPath: String = downloadUrlRepoName,
|
||||||
archiveName: String = podName,
|
archiveName: String = podName,
|
||||||
flatten: Boolean = false
|
flatten: Boolean = false
|
||||||
) {
|
) {
|
||||||
@@ -554,6 +832,30 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
appendToCocoapodsBlock(podBlock)
|
appendToCocoapodsBlock(podBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun File.removePod(podName: String) {
|
||||||
|
val text = readText()
|
||||||
|
val begin = text.indexOf("""pod("$podName")""")
|
||||||
|
require(begin != -1) { "Pod doesn't exist in file" }
|
||||||
|
var index = begin + """pod("$podName")""".length - 1
|
||||||
|
if (text.indexOf("""pod("$podName") {""", startIndex = begin) != -1) {
|
||||||
|
index += 2
|
||||||
|
var bracket = 1
|
||||||
|
while (bracket != 0) {
|
||||||
|
if (text[++index] == '{') {
|
||||||
|
bracket++
|
||||||
|
} else if (text[index] == '}') {
|
||||||
|
bracket--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeText(text.removeRange(begin..index))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun File.changePod(podName: String, newConfiguration: String? = null) {
|
||||||
|
removePod(podName)
|
||||||
|
addPod(podName, newConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
private fun File.addSpecRepo(specRepo: String) = appendToCocoapodsBlock("url(\"$specRepo\")".wrap("specRepos"))
|
private fun File.addSpecRepo(specRepo: String) = appendToCocoapodsBlock("url(\"$specRepo\")".wrap("specRepos"))
|
||||||
|
|
||||||
private fun File.appendToKotlinBlock(str: String) = appendLine(str.wrap("kotlin"))
|
private fun File.appendToKotlinBlock(str: String) = appendLine(str.wrap("kotlin"))
|
||||||
@@ -691,7 +993,7 @@ class CocoaPodsIT : BaseGradleIT() {
|
|||||||
assertTasksExecutedByPrefix(listOf("$taskPrefix:$POD_GEN_TASK_NAME"))
|
assertTasksExecutedByPrefix(listOf("$taskPrefix:$POD_GEN_TASK_NAME"))
|
||||||
}
|
}
|
||||||
|
|
||||||
with(listOf(POD_SETUP_BUILD_TASK_NAME, POD_BUILD_DEPENDENCIES_TASK_NAME).map { "$taskPrefix:$it" }) {
|
with(listOf(POD_SETUP_BUILD_TASK_NAME, POD_BUILD_TASK_NAME).map { "$taskPrefix:$it" }) {
|
||||||
if (buildScriptText.matches("pod\\(.*\\)".toRegex())) {
|
if (buildScriptText.matches("pod\\(.*\\)".toRegex())) {
|
||||||
assertTasksRegisteredByPrefix(this)
|
assertTasksRegisteredByPrefix(this)
|
||||||
assertTasksExecutedByPrefix(this)
|
assertTasksExecutedByPrefix(this)
|
||||||
|
|||||||
+92
-60
@@ -11,6 +11,7 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.provider.Provider
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.tasks.Sync
|
import org.gradle.api.tasks.Sync
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.jetbrains.kotlin.daemon.common.trimQuotes
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.konan.target.HostManager
|
|||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
internal val Project.cocoapodsBuildDirs: CocoapodsBuildDirs
|
internal val Project.cocoapodsBuildDirs: CocoapodsBuildDirs
|
||||||
get() = CocoapodsBuildDirs(this)
|
get() = CocoapodsBuildDirs(this)
|
||||||
@@ -68,17 +70,17 @@ private val Family.toPodGenTaskName: String
|
|||||||
name
|
name
|
||||||
)
|
)
|
||||||
|
|
||||||
private val String.toSetupBuildTaskName: String
|
private fun String.toSetupBuildTaskName(pod: CocoapodsDependency): String = lowerCamelCaseName(
|
||||||
get() = lowerCamelCaseName(
|
KotlinCocoapodsPlugin.POD_SETUP_BUILD_TASK_NAME,
|
||||||
KotlinCocoapodsPlugin.POD_SETUP_BUILD_TASK_NAME,
|
pod.schemeName,
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
|
|
||||||
private val String.toBuildDependenciesTaskName: String
|
private fun String.toBuildDependenciesTaskName(pod: CocoapodsDependency): String = lowerCamelCaseName(
|
||||||
get() = lowerCamelCaseName(
|
KotlinCocoapodsPlugin.POD_BUILD_TASK_NAME,
|
||||||
KotlinCocoapodsPlugin.POD_BUILD_DEPENDENCIES_TASK_NAME,
|
pod.schemeName,
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CocoapodsDependency.toPodDownloadTaskName: String
|
private val CocoapodsDependency.toPodDownloadTaskName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
@@ -225,7 +227,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
val defTask = project.registerTask<DefFileTask>(
|
val defTask = project.registerTask<DefFileTask>(
|
||||||
lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName()
|
lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName()
|
||||||
) {
|
) {
|
||||||
it.pod = pod
|
it.pod = project.provider { pod }
|
||||||
it.description = "Generates a def file for CocoaPods dependencies with module ${pod.moduleName}"
|
it.description = "Generates a def file for CocoaPods dependencies with module ${pod.moduleName}"
|
||||||
// This task is an implementation detail so we don't add it in any group
|
// This task is an implementation detail so we don't add it in any group
|
||||||
// to avoid showing it in the `tasks` output.
|
// to avoid showing it in the `tasks` output.
|
||||||
@@ -248,8 +250,8 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
&& project.findProperty(CONFIGURATION_PROPERTY) == null
|
&& project.findProperty(CONFIGURATION_PROPERTY) == null
|
||||||
) {
|
) {
|
||||||
val podBuildTaskProvider =
|
val podBuildTaskProvider =
|
||||||
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName, PodBuildTask::class.java)
|
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java)
|
||||||
interopTask.inputs.file(podBuildTaskProvider.get().buildSettingsFileProvider)
|
interopTask.inputs.file(podBuildTaskProvider.get().buildSettingsFile)
|
||||||
interopTask.dependsOn(podBuildTaskProvider)
|
interopTask.dependsOn(podBuildTaskProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,9 +277,9 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
&& project.findProperty(CONFIGURATION_PROPERTY) == null
|
&& project.findProperty(CONFIGURATION_PROPERTY) == null
|
||||||
) {
|
) {
|
||||||
val podBuildTaskProvider =
|
val podBuildTaskProvider =
|
||||||
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName, PodBuildTask::class.java)
|
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java)
|
||||||
val buildSettings =
|
val buildSettings =
|
||||||
podBuildTaskProvider.get().buildSettingsFileProvider.get()
|
podBuildTaskProvider.get().buildSettingsFile.get()
|
||||||
.inputStream()
|
.inputStream()
|
||||||
.use {
|
.use {
|
||||||
PodBuildSettingsProperties.readSettingsFromStream(it)
|
PodBuildSettingsProperties.readSettingsFromStream(it)
|
||||||
@@ -291,9 +293,14 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
buildSettings.headerPaths?.let { args ->
|
buildSettings.headerPaths?.let { args ->
|
||||||
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
|
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
|
||||||
}
|
}
|
||||||
buildSettings.frameworkPaths?.let { args ->
|
|
||||||
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-F$it" })
|
val frameworkPaths = buildSettings.frameworkPaths
|
||||||
}
|
val configurationBuildDir = buildSettings.configurationBuildDir
|
||||||
|
val frameworkPathsSelfIncluding = mutableListOf<String>()
|
||||||
|
frameworkPathsSelfIncluding += configurationBuildDir.trimQuotes()
|
||||||
|
frameworkPaths?.let { frameworkPathsSelfIncluding.addAll(it.splitQuotedArgs()) }
|
||||||
|
|
||||||
|
interop.compilerOpts.addAll(frameworkPathsSelfIncluding.map { "-F$it" })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +313,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
cocoapodsExtension: CocoapodsExtension
|
cocoapodsExtension: CocoapodsExtension
|
||||||
) {
|
) {
|
||||||
project.tasks.register(DUMMY_FRAMEWORK_TASK_NAME, DummyFrameworkTask::class.java) {
|
project.tasks.register(DUMMY_FRAMEWORK_TASK_NAME, DummyFrameworkTask::class.java) {
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
it.frameworkName = project.provider { cocoapodsExtension.frameworkName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +326,18 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
project.tasks.register(POD_SPEC_TASK_NAME, PodspecTask::class.java) {
|
project.tasks.register(POD_SPEC_TASK_NAME, PodspecTask::class.java) {
|
||||||
it.group = TASK_GROUP
|
it.group = TASK_GROUP
|
||||||
it.description = "Generates a podspec file for CocoaPods import"
|
it.description = "Generates a podspec file for CocoaPods import"
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
it.needPodspec = project.provider { cocoapodsExtension.needPodspec }
|
||||||
|
it.pods.set(cocoapodsExtension.pods)
|
||||||
|
it.version = project.provider { cocoapodsExtension.version }
|
||||||
|
it.homepage.set(cocoapodsExtension.homepage)
|
||||||
|
it.license.set(cocoapodsExtension.license)
|
||||||
|
it.authors.set(cocoapodsExtension.authors)
|
||||||
|
it.summary.set(cocoapodsExtension.summary)
|
||||||
|
it.frameworkName = project.provider { cocoapodsExtension.frameworkName }
|
||||||
|
it.ios = project.provider { cocoapodsExtension.ios }
|
||||||
|
it.osx = project.provider { cocoapodsExtension.osx }
|
||||||
|
it.tvos = project.provider { cocoapodsExtension.tvos }
|
||||||
|
it.watchos = project.provider { cocoapodsExtension.watchos }
|
||||||
it.dependsOn(dummyFrameworkTaskProvider)
|
it.dependsOn(dummyFrameworkTaskProvider)
|
||||||
val generateWrapper = project.findProperty(GENERATE_WRAPPER_PROPERTY)?.toString()?.toBoolean() ?: false
|
val generateWrapper = project.findProperty(GENERATE_WRAPPER_PROPERTY)?.toString()?.toBoolean() ?: false
|
||||||
if (generateWrapper) {
|
if (generateWrapper) {
|
||||||
@@ -335,13 +353,13 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
project.tasks.register(POD_INSTALL_TASK_NAME, PodInstallTask::class.java) {
|
project.tasks.register(POD_INSTALL_TASK_NAME, PodInstallTask::class.java) {
|
||||||
it.group = TASK_GROUP
|
it.group = TASK_GROUP
|
||||||
it.description = "Invokes `pod install` call within Podfile location directory"
|
it.description = "Invokes `pod install` call within Podfile location directory"
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
it.podfile.set(cocoapodsExtension.podfile)
|
||||||
it.onlyIf { isAvailableToProduceSynthetic }
|
it.onlyIf { isAvailableToProduceSynthetic }
|
||||||
|
|
||||||
//TODO avoid subproject task management here
|
//TODO avoid subproject task management here
|
||||||
project.allprojects.map { it.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java) }
|
project.allprojects.map { it.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java) }
|
||||||
.forEach { podspecTaskProvider ->
|
.forEach { podspecTaskProvider ->
|
||||||
podspecTaskProvider.get().takeIf { task -> task.cocoapodsExtension.needPodspec }
|
podspecTaskProvider.get().takeIf { task -> task.needPodspec.get() }
|
||||||
?.also { task -> it.inputs.file(task.outputFileProvider) }
|
?.also { task -> it.inputs.file(task.outputFileProvider) }
|
||||||
it.dependsOn(podspecTaskProvider)
|
it.dependsOn(podspecTaskProvider)
|
||||||
}
|
}
|
||||||
@@ -361,12 +379,10 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
val podSource = pod.source
|
val podSource = pod.source
|
||||||
val downloadPodTask = when (podSource) {
|
val downloadPodTask = when (podSource) {
|
||||||
is Git -> project.tasks.register(pod.toPodDownloadTaskName, PodDownloadGitTask::class.java) {
|
is Git -> project.tasks.register(pod.toPodDownloadTaskName, PodDownloadGitTask::class.java) {
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
|
||||||
it.podName = project.provider { pod.name }
|
it.podName = project.provider { pod.name }
|
||||||
it.podSource = project.provider { podSource as Git }
|
it.podSource = project.provider { podSource as Git }
|
||||||
}
|
}
|
||||||
is Url -> project.tasks.register(pod.toPodDownloadTaskName, PodDownloadUrlTask::class.java) {
|
is Url -> project.tasks.register(pod.toPodDownloadTaskName, PodDownloadUrlTask::class.java) {
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
|
||||||
it.podName = project.provider { pod.name }
|
it.podName = project.provider { pod.name }
|
||||||
it.podSource = project.provider { podSource as Url }
|
it.podSource = project.provider { podSource as Url }
|
||||||
}
|
}
|
||||||
@@ -394,10 +410,10 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
|
|
||||||
project.tasks.register(family.toPodGenTaskName, PodGenTask::class.java) {
|
project.tasks.register(family.toPodGenTaskName, PodGenTask::class.java) {
|
||||||
it.description = "Сreates a synthetic Xcode project to retrieve CocoaPods dependencies"
|
it.description = "Сreates a synthetic Xcode project to retrieve CocoaPods dependencies"
|
||||||
it.podspecProvider = podspecTaskProvider.get().outputFileProvider
|
it.podspec = podspecTaskProvider.map { task -> task.outputFileProvider.get() }
|
||||||
|
it.specRepos = project.provider { cocoapodsExtension.specRepos }
|
||||||
it.family = family
|
it.family = family
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
it.pods.set(cocoapodsExtension.pods)
|
||||||
it.dependsOn(podspecTaskProvider)
|
|
||||||
it.dependsOn(downloadPods)
|
it.dependsOn(downloadPods)
|
||||||
it.onlyIf { isAvailableToProduceSynthetic }
|
it.onlyIf { isAvailableToProduceSynthetic }
|
||||||
}
|
}
|
||||||
@@ -409,30 +425,36 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
kotlinExtension: KotlinMultiplatformExtension,
|
kotlinExtension: KotlinMultiplatformExtension,
|
||||||
cocoapodsExtension: CocoapodsExtension
|
cocoapodsExtension: CocoapodsExtension
|
||||||
) {
|
) {
|
||||||
val sdks = mutableSetOf<String>()
|
val schemeNames = mutableSetOf<String>()
|
||||||
|
|
||||||
kotlinExtension.supportedTargets().all { target ->
|
cocoapodsExtension.pods.all { pod ->
|
||||||
|
|
||||||
val sdk = target.toValidSDK
|
if (schemeNames.contains(pod.schemeName)) {
|
||||||
if (sdk in sdks) {
|
|
||||||
return@all
|
return@all
|
||||||
}
|
}
|
||||||
sdks += sdk
|
schemeNames.add(pod.schemeName)
|
||||||
|
|
||||||
val podGenTaskProvider = project.tasks.named(target.konanTarget.family.toPodGenTaskName, PodGenTask::class.java)
|
val sdks = mutableSetOf<String>()
|
||||||
|
|
||||||
project.tasks.register(sdk.toSetupBuildTaskName, PodSetupBuildTask::class.java) {
|
kotlinExtension.supportedTargets().all loop@{ target ->
|
||||||
it.group = TASK_GROUP
|
|
||||||
it.description = "Collect environment variables from .xcworkspace file"
|
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
|
||||||
it.sdk = project.provider { sdk }
|
|
||||||
|
|
||||||
val podspecTaskProvider = project.tasks.named(POD_SPEC_TASK_NAME, PodspecTask::class.java)
|
val sdk = target.toValidSDK
|
||||||
it.schemeName = podspecTaskProvider.map { it.specName }
|
if (sdk in sdks) {
|
||||||
|
return@loop
|
||||||
|
}
|
||||||
|
sdks += sdk
|
||||||
|
|
||||||
it.podsXcodeProjDirProvider = podGenTaskProvider.get().podsXcodeProjDirProvider
|
val podGenTaskProvider = project.tasks.named(target.konanTarget.family.toPodGenTaskName, PodGenTask::class.java)
|
||||||
it.dependsOn(podGenTaskProvider)
|
project.tasks.register(sdk.toSetupBuildTaskName(pod), PodSetupBuildTask::class.java) {
|
||||||
it.onlyIf { isAvailableToProduceSynthetic }
|
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 = project.provider { cocoapodsExtension.frameworkName }
|
||||||
|
it.dependsOn(podGenTaskProvider)
|
||||||
|
it.onlyIf { isAvailableToProduceSynthetic }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,27 +464,38 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
kotlinExtension: KotlinMultiplatformExtension,
|
kotlinExtension: KotlinMultiplatformExtension,
|
||||||
cocoapodsExtension: CocoapodsExtension
|
cocoapodsExtension: CocoapodsExtension
|
||||||
) {
|
) {
|
||||||
val sdks = mutableSetOf<String>()
|
val schemeNames = mutableSetOf<String>()
|
||||||
|
|
||||||
kotlinExtension.supportedTargets().all { target ->
|
cocoapodsExtension.pods.all { pod ->
|
||||||
|
|
||||||
val sdk = target.toValidSDK
|
if (schemeNames.contains(pod.schemeName)) {
|
||||||
if (sdk in sdks) {
|
|
||||||
return@all
|
return@all
|
||||||
}
|
}
|
||||||
sdks += sdk
|
schemeNames.add(pod.schemeName)
|
||||||
|
|
||||||
val podSetupBuildTaskProvider = project.tasks.named(sdk.toSetupBuildTaskName, PodSetupBuildTask::class.java)
|
val sdks = mutableSetOf<String>()
|
||||||
|
|
||||||
project.tasks.register(sdk.toBuildDependenciesTaskName, PodBuildTask::class.java) {
|
kotlinExtension.supportedTargets().all loop@{ target ->
|
||||||
it.group = TASK_GROUP
|
|
||||||
it.description = "Calls `xcodebuild` on xcworkspace for the pod scheme"
|
val sdk = target.toValidSDK
|
||||||
it.sdk = project.provider { sdk }
|
|
||||||
it.cocoapodsExtension = cocoapodsExtension
|
if (sdk in sdks) {
|
||||||
it.podsXcodeProjDirProvider = podSetupBuildTaskProvider.get().podsXcodeProjDirProvider
|
return@loop
|
||||||
it.buildSettingsFileProvider = podSetupBuildTaskProvider.get().buildSettingsFileProvider
|
}
|
||||||
it.dependsOn(podSetupBuildTaskProvider)
|
sdks += sdk
|
||||||
it.onlyIf { isAvailableToProduceSynthetic }
|
|
||||||
|
val podSetupBuildTaskProvider =
|
||||||
|
project.tasks.named(sdk.toSetupBuildTaskName(pod), PodSetupBuildTask::class.java)
|
||||||
|
|
||||||
|
project.tasks.register(sdk.toBuildDependenciesTaskName(pod), PodBuildTask::class.java) {
|
||||||
|
it.group = TASK_GROUP
|
||||||
|
it.description = "Calls `xcodebuild` on xcworkspace for the pod scheme"
|
||||||
|
it.sdk = project.provider { sdk }
|
||||||
|
it.pod = project.provider { pod }
|
||||||
|
it.podsXcodeProjDir = podSetupBuildTaskProvider.map { task -> task.podsXcodeProjDir.get() }
|
||||||
|
it.buildSettingsFile = podSetupBuildTaskProvider.map { task -> task.buildSettingsFile.get() }
|
||||||
|
it.onlyIf { isAvailableToProduceSynthetic }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,7 +504,6 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
project: Project,
|
project: Project,
|
||||||
kotlinExtension: KotlinMultiplatformExtension
|
kotlinExtension: KotlinMultiplatformExtension
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val podInstallTaskProvider = project.tasks.named(POD_INSTALL_TASK_NAME, PodInstallTask::class.java)
|
val podInstallTaskProvider = project.tasks.named(POD_INSTALL_TASK_NAME, PodInstallTask::class.java)
|
||||||
project.tasks.register(POD_IMPORT_TASK_NAME) {
|
project.tasks.register(POD_IMPORT_TASK_NAME) {
|
||||||
it.group = TASK_GROUP
|
it.group = TASK_GROUP
|
||||||
@@ -531,7 +563,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
|
|||||||
const val POD_DOWNLOAD_TASK_NAME = "podDownload"
|
const val POD_DOWNLOAD_TASK_NAME = "podDownload"
|
||||||
const val POD_GEN_TASK_NAME = "podGen"
|
const val POD_GEN_TASK_NAME = "podGen"
|
||||||
const val POD_SETUP_BUILD_TASK_NAME = "podSetupBuild"
|
const val POD_SETUP_BUILD_TASK_NAME = "podSetupBuild"
|
||||||
const val POD_BUILD_DEPENDENCIES_TASK_NAME = "podBuildDependencies"
|
const val POD_BUILD_TASK_NAME = "podBuild"
|
||||||
const val POD_IMPORT_TASK_NAME = "podImport"
|
const val POD_IMPORT_TASK_NAME = "podImport"
|
||||||
|
|
||||||
// We don't move these properties in PropertiesProvider because
|
// We don't move these properties in PropertiesProvider because
|
||||||
|
|||||||
+140
-102
@@ -7,15 +7,14 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks
|
|||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.artifacts.repositories.ArtifactRepository
|
import org.gradle.api.artifacts.repositories.ArtifactRepository
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.file.FileTree
|
import org.gradle.api.file.FileTree
|
||||||
import org.gradle.api.file.RelativePath
|
import org.gradle.api.file.RelativePath
|
||||||
import org.gradle.api.provider.Provider
|
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.*
|
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.CocoapodsExtension.CocoapodsDependency.PodLocation.*
|
||||||
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.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -34,6 +33,9 @@ private val Family.platformLiteral: String
|
|||||||
else -> throw IllegalArgumentException("Bad family ${this.name}")
|
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`
|
* The task takes the path to the Podfile and calls `pod install`
|
||||||
* to obtain sources or artifacts for the declared dependencies.
|
* to obtain sources or artifacts for the declared dependencies.
|
||||||
@@ -41,24 +43,24 @@ private val Family.platformLiteral: String
|
|||||||
*/
|
*/
|
||||||
open class PodInstallTask : DefaultTask() {
|
open class PodInstallTask : DefaultTask() {
|
||||||
init {
|
init {
|
||||||
onlyIf { cocoapodsExtension?.podfile != null }
|
onlyIf { podfile.isPresent }
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Optional
|
@get:Optional
|
||||||
@get:Nested
|
@get:Input
|
||||||
internal var cocoapodsExtension: CocoapodsExtension? = null
|
internal val podfile = project.objects.property(File::class.java)
|
||||||
|
|
||||||
@get:Optional
|
@get:Optional
|
||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
internal val podsXcodeProjDirProvider: Provider<File>?
|
internal val podsXcodeProjDirProvider: Provider<File>?
|
||||||
get() = cocoapodsExtension?.podfile?.let {
|
get() = podfile.orNull?.let {
|
||||||
project.provider { it.parentFile.resolve("Pods").resolve("Pods.xcodeproj") }
|
project.provider { it.parentFile.resolve("Pods").resolve("Pods.xcodeproj") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun doPodInstall() {
|
fun doPodInstall() {
|
||||||
cocoapodsExtension?.podfile?.parentFile?.also { podfileDir ->
|
podfile.orNull?.parentFile?.also { podfileDir ->
|
||||||
val podInstallProcess = ProcessBuilder("pod", "install").apply {
|
val podInstallProcess = ProcessBuilder("pod", "install").apply {
|
||||||
directory(podfileDir)
|
directory(podfileDir)
|
||||||
}.start()
|
}.start()
|
||||||
@@ -81,25 +83,12 @@ open class PodInstallTask : DefaultTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class DownloadCocoapodsTask : DefaultTask() {
|
||||||
abstract class CocoapodsWithSyntheticTask : DefaultTask() {
|
|
||||||
init {
|
|
||||||
onlyIf {
|
|
||||||
cocoapodsExtension.pods.isNotEmpty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@get:Nested
|
|
||||||
internal lateinit var cocoapodsExtension: CocoapodsExtension
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class PodDownloadTask : CocoapodsWithSyntheticTask() {
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal lateinit var podName: Provider<String>
|
internal lateinit var podName: Provider<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class PodDownloadUrlTask : DownloadCocoapodsTask() {
|
||||||
open class PodDownloadUrlTask : PodDownloadTask() {
|
|
||||||
|
|
||||||
@get:Nested
|
@get:Nested
|
||||||
internal lateinit var podSource: Provider<Url>
|
internal lateinit var podSource: Provider<Url>
|
||||||
@@ -181,8 +170,7 @@ open class PodDownloadUrlTask : PodDownloadTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class PodDownloadGitTask : DownloadCocoapodsTask() {
|
||||||
open class PodDownloadGitTask : PodDownloadTask() {
|
|
||||||
|
|
||||||
@get:Nested
|
@get:Nested
|
||||||
internal lateinit var podSource: Provider<Git>
|
internal lateinit var podSource: Provider<Git>
|
||||||
@@ -328,19 +316,31 @@ private fun runCommand(
|
|||||||
* The task takes the path to the .podspec file and calls `pod gen`
|
* The task takes the path to the .podspec file and calls `pod gen`
|
||||||
* to create synthetic xcode project and workspace.
|
* to create synthetic xcode project and workspace.
|
||||||
*/
|
*/
|
||||||
open class PodGenTask : CocoapodsWithSyntheticTask() {
|
open class PodGenTask : DefaultTask() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
onlyIf {
|
||||||
|
pods.get().isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@get:InputFile
|
@get:InputFile
|
||||||
internal lateinit var podspecProvider: Provider<File>
|
internal lateinit var podspec: Provider<File>
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
lateinit var family: Family
|
lateinit var family: Family
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var specRepos: Provider<SpecRepos>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
val pods = project.objects.listProperty(CocoapodsDependency::class.java)
|
||||||
|
|
||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
internal val podsXcodeProjDirProvider: Provider<File>
|
internal val podsXcodeProjDir: Provider<File>
|
||||||
get() = project.provider {
|
get() = project.provider {
|
||||||
project.cocoapodsBuildDirs.synthetic(family)
|
project.cocoapodsBuildDirs.synthetic(family)
|
||||||
.resolve(podspecProvider.get().nameWithoutExtension)
|
.resolve(podspec.get().nameWithoutExtension)
|
||||||
.resolve("Pods")
|
.resolve("Pods")
|
||||||
.resolve("Pods.xcodeproj")
|
.resolve("Pods.xcodeproj")
|
||||||
}
|
}
|
||||||
@@ -348,18 +348,18 @@ open class PodGenTask : CocoapodsWithSyntheticTask() {
|
|||||||
@TaskAction
|
@TaskAction
|
||||||
fun generate() {
|
fun generate() {
|
||||||
val syntheticDir = project.cocoapodsBuildDirs.synthetic(family).apply { mkdirs() }
|
val syntheticDir = project.cocoapodsBuildDirs.synthetic(family).apply { mkdirs() }
|
||||||
val localPodspecPaths = cocoapodsExtension.pods.mapNotNull { it.source?.getLocalPath(project, it.name) }
|
val localPodspecPaths = pods.get().mapNotNull { it.source?.getLocalPath(project, it.name) }
|
||||||
|
|
||||||
val sources = cocoapodsExtension.specRepos.getAll().toMutableList()
|
val specRepos = specRepos.get().getAll().toMutableList()
|
||||||
sources += URI("https://cdn.cocoapods.org")
|
specRepos += URI("https://cdn.cocoapods.org")
|
||||||
|
|
||||||
val podGenProcessArgs = listOfNotNull(
|
val podGenProcessArgs = listOfNotNull(
|
||||||
"pod", "gen",
|
"pod", "gen",
|
||||||
"--platforms=${family.platformLiteral}",
|
"--platforms=${family.platformLiteral}",
|
||||||
"--gen-directory=${syntheticDir.absolutePath}",
|
"--gen-directory=${syntheticDir.absolutePath}",
|
||||||
localPodspecPaths.takeIf { it.isNotEmpty() }?.joinToString(separator = ",")?.let { "--local-sources=$it" },
|
localPodspecPaths.takeIf { it.isNotEmpty() }?.joinToString(separator = ",")?.let { "--local-sources=$it" },
|
||||||
sources.takeIf { it.isNotEmpty() }?.joinToString(separator = ",")?.let { "--sources=$it" },
|
specRepos.takeIf { it.isNotEmpty() }?.joinToString(separator = ",")?.let { "--sources=$it" },
|
||||||
podspecProvider.get().absolutePath
|
podspec.get().absolutePath
|
||||||
)
|
)
|
||||||
|
|
||||||
val podGenProcess = ProcessBuilder(podGenProcessArgs).apply {
|
val podGenProcess = ProcessBuilder(podGenProcessArgs).apply {
|
||||||
@@ -388,7 +388,7 @@ open class PodGenTask : CocoapodsWithSyntheticTask() {
|
|||||||
).joinToString("\n")
|
).joinToString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
val podsXcprojFile = podsXcodeProjDirProvider.get()
|
val podsXcprojFile = podsXcodeProjDir.get()
|
||||||
check(podsXcprojFile.exists() && podsXcprojFile.isDirectory) {
|
check(podsXcprojFile.exists() && podsXcprojFile.isDirectory) {
|
||||||
"The directory '${podsXcprojFile.path}' was not created as a result of the `pod gen` call."
|
"The directory '${podsXcprojFile.path}' was not created as a result of the `pod gen` call."
|
||||||
}
|
}
|
||||||
@@ -396,35 +396,35 @@ open class PodGenTask : CocoapodsWithSyntheticTask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
|
open class PodSetupBuildTask : DefaultTask() {
|
||||||
|
|
||||||
@get:InputDirectory
|
@get:Input
|
||||||
internal lateinit var podsXcodeProjDirProvider: Provider<File>
|
lateinit var frameworkName: Provider<String>
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal lateinit var sdk: Provider<String>
|
internal lateinit var sdk: Provider<String>
|
||||||
|
|
||||||
@Input
|
@get:Nested
|
||||||
lateinit var schemeName: Provider<String>
|
lateinit var pod: Provider<CocoapodsDependency>
|
||||||
|
|
||||||
@get:OutputFile
|
@get:OutputFile
|
||||||
internal val buildSettingsFileProvider: Provider<File> = project.provider {
|
internal val buildSettingsFile: Provider<File> = project.provider {
|
||||||
project.cocoapodsBuildDirs
|
project.cocoapodsBuildDirs
|
||||||
.buildSettings
|
.buildSettings
|
||||||
.resolve(sdk.get().toBuildSettingsFileName)
|
.resolve(getBuildSettingFileName(pod.get(), sdk.get()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val String.toBuildSettingsFileName: String
|
@get:Internal
|
||||||
get() = "build-settings-$this.properties"
|
internal lateinit var podsXcodeProjDir: Provider<File>
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun setupBuild() {
|
fun setupBuild() {
|
||||||
val podsXcodeProjDir = podsXcodeProjDirProvider.get()
|
val podsXcodeProjDir = podsXcodeProjDir.get()
|
||||||
|
|
||||||
val buildSettingsReceivingCommand = listOf(
|
val buildSettingsReceivingCommand = listOf(
|
||||||
"xcodebuild", "-showBuildSettings",
|
"xcodebuild", "-showBuildSettings",
|
||||||
"-project", podsXcodeProjDir.name,
|
"-project", podsXcodeProjDir.name,
|
||||||
"-scheme", schemeName.get(),
|
"-scheme", pod.get().schemeName,
|
||||||
"-sdk", sdk.get()
|
"-sdk", sdk.get()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -442,113 +442,151 @@ open class PodSetupBuildTask : CocoapodsWithSyntheticTask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val stdOut = buildSettingsProcess.inputStream
|
val stdOut = buildSettingsProcess.inputStream
|
||||||
|
|
||||||
val buildSettingsProperties = PodBuildSettingsProperties.readSettingsFromStream(stdOut)
|
val buildSettingsProperties = PodBuildSettingsProperties.readSettingsFromStream(stdOut)
|
||||||
buildSettingsFileProvider.get().let { buildSettingsProperties.writeSettings(it) }
|
buildSettingsFile.get().let {
|
||||||
|
buildSettingsProperties.writeSettings(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getBuildSettingFileName(pod: CocoapodsDependency, sdk: String): String =
|
||||||
|
"build-settings-$sdk-${pod.schemeName}.properties"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The task compiles external cocoa pods sources.
|
* The task compiles external cocoa pods sources.
|
||||||
*/
|
*/
|
||||||
open class PodBuildTask : CocoapodsWithSyntheticTask() {
|
open class PodBuildTask : DefaultTask() {
|
||||||
|
|
||||||
@get:InputDirectory
|
|
||||||
internal lateinit var podsXcodeProjDirProvider: Provider<File>
|
|
||||||
|
|
||||||
@get:InputFile
|
@get:InputFile
|
||||||
internal lateinit var buildSettingsFileProvider: Provider<File>
|
internal lateinit var buildSettingsFile: Provider<File>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var pod: Provider<CocoapodsDependency>
|
||||||
|
|
||||||
|
@get:InputFiles
|
||||||
|
internal val srcDir: FileTree
|
||||||
|
get() = project.fileTree(
|
||||||
|
buildSettingsFile.map {
|
||||||
|
PodBuildSettingsProperties.readSettingsFromStream(
|
||||||
|
FileInputStream(it)
|
||||||
|
).podsTargetSrcRoot
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@get:Internal
|
||||||
|
internal var buildDir: Provider<File> = project.provider {
|
||||||
|
project.file(
|
||||||
|
PodBuildSettingsProperties.readSettingsFromStream(
|
||||||
|
FileInputStream(buildSettingsFile.get())
|
||||||
|
).buildDir
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal lateinit var sdk: Provider<String>
|
internal lateinit var sdk: Provider<String>
|
||||||
|
|
||||||
@get:Optional
|
@get:OutputFiles
|
||||||
@get:OutputDirectory
|
internal val buildResult: Provider<FileCollection>? = project.provider {
|
||||||
internal var buildDirProvider: Provider<File>? = null
|
project.fileTree(buildDir.get()) {
|
||||||
|
it.include("**/${pod.get().schemeName}.*/")
|
||||||
|
it.include("**/${pod.get().schemeName}/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val CocoapodsExtension.CocoapodsDependency.schemeName: String
|
@get:Internal
|
||||||
get() = name.split("/")[0]
|
internal lateinit var podsXcodeProjDir: Provider<File>
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun buildDependencies() {
|
fun buildDependencies() {
|
||||||
val podBuildSettings = PodBuildSettingsProperties.readSettingsFromStream(
|
val podBuildSettings = PodBuildSettingsProperties.readSettingsFromStream(
|
||||||
FileInputStream(buildSettingsFileProvider.get())
|
FileInputStream(buildSettingsFile.get())
|
||||||
)
|
)
|
||||||
|
|
||||||
val podsXcodeProjDir = podsXcodeProjDirProvider.get()
|
val podsXcodeProjDir = podsXcodeProjDir.get()
|
||||||
|
|
||||||
cocoapodsExtension.pods.all {
|
val podXcodeBuildCommand = listOf(
|
||||||
|
"xcodebuild",
|
||||||
|
"-project", podsXcodeProjDir.name,
|
||||||
|
"-scheme", pod.get().schemeName,
|
||||||
|
"-sdk", sdk.get(),
|
||||||
|
"-configuration", podBuildSettings.configuration
|
||||||
|
)
|
||||||
|
|
||||||
val podXcodeBuildCommand = listOf(
|
val podBuildProcess = ProcessBuilder(podXcodeBuildCommand)
|
||||||
"xcodebuild",
|
.apply {
|
||||||
"-project", podsXcodeProjDir.name,
|
directory(podsXcodeProjDir.parentFile)
|
||||||
"-scheme", it.schemeName,
|
inheritIO()
|
||||||
"-sdk", sdk.get(),
|
}.start()
|
||||||
"-configuration", podBuildSettings.configuration
|
|
||||||
)
|
|
||||||
|
|
||||||
val podBuildProcess = ProcessBuilder(podXcodeBuildCommand)
|
val podBuildRetCode = podBuildProcess.waitFor()
|
||||||
.apply {
|
check(podBuildRetCode == 0) {
|
||||||
directory(podsXcodeProjDir.parentFile)
|
listOf(
|
||||||
inheritIO()
|
"Executing of '${podXcodeBuildCommand.joinToString(" ")}' failed with code $podBuildRetCode and message:",
|
||||||
}.start()
|
podBuildProcess.errorStream.use { it.reader().readText() }
|
||||||
|
).joinToString("\n")
|
||||||
val podBuildRetCode = podBuildProcess.waitFor()
|
|
||||||
check(podBuildRetCode == 0) {
|
|
||||||
listOf(
|
|
||||||
"Executing of '${podXcodeBuildCommand.joinToString(" ")}' failed with code $podBuildRetCode and message:",
|
|
||||||
podBuildProcess.errorStream.use { it.reader().readText() }
|
|
||||||
).joinToString("\n")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buildDirProvider = project.provider { project.file(podBuildSettings.buildDir) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal data class PodBuildSettingsProperties(
|
internal data class PodBuildSettingsProperties(
|
||||||
internal val buildDir: String,
|
internal val buildDir: String,
|
||||||
internal val configuration: String,
|
internal val configuration: String,
|
||||||
|
internal val configurationBuildDir: String,
|
||||||
|
internal val podsTargetSrcRoot: String,
|
||||||
internal val cflags: String? = null,
|
internal val cflags: String? = null,
|
||||||
internal val headerPaths: String? = null,
|
internal val headerPaths: String? = null,
|
||||||
internal val frameworkPaths: String? = null
|
internal val frameworkPaths: String? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun writeSettings(buildSettingsFile: File) {
|
fun writeSettings(
|
||||||
|
buildSettingsFile: File
|
||||||
|
) {
|
||||||
buildSettingsFile.parentFile.mkdirs()
|
buildSettingsFile.parentFile.mkdirs()
|
||||||
|
buildSettingsFile.delete()
|
||||||
buildSettingsFile.createNewFile()
|
buildSettingsFile.createNewFile()
|
||||||
|
|
||||||
check(buildSettingsFile.exists()) { "Unable to create file ${buildSettingsFile.path}!" }
|
check(buildSettingsFile.exists()) { "Unable to create file ${buildSettingsFile.path}!" }
|
||||||
|
|
||||||
with(Properties()) {
|
with(buildSettingsFile) {
|
||||||
setProperty(BUILD_DIR, buildDir)
|
appendText("$BUILD_DIR=$buildDir\n")
|
||||||
setProperty(CONFIGURATION, configuration)
|
appendText("$CONFIGURATION=$configuration\n")
|
||||||
cflags?.let { setProperty(OTHER_CFLAGS, it) }
|
appendText("$CONFIGURATION_BUILD_DIR=$configurationBuildDir\n")
|
||||||
headerPaths?.let { setProperty(HEADER_SEARCH_PATHS, it) }
|
appendText("$PODS_TARGET_SRCROOT=$podsTargetSrcRoot\n")
|
||||||
frameworkPaths?.let { setProperty(FRAMEWORK_SEARCH_PATHS, it) }
|
cflags?.let { appendText("$OTHER_CFLAGS=$it\n") }
|
||||||
buildSettingsFile.outputStream().use {
|
headerPaths?.let { appendText("$HEADER_SEARCH_PATHS=$it\n") }
|
||||||
store(it, null)
|
frameworkPaths?.let { appendText("$FRAMEWORK_SEARCH_PATHS=$it") }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val BUILD_DIR: String = "BUILD_DIR"
|
const val BUILD_DIR = "BUILD_DIR"
|
||||||
const val CONFIGURATION: String = "CONFIGURATION"
|
const val CONFIGURATION = "CONFIGURATION"
|
||||||
const val OTHER_CFLAGS: String = "OTHER_CFLAGS"
|
const val CONFIGURATION_BUILD_DIR = "CONFIGURATION_BUILD_DIR"
|
||||||
const val HEADER_SEARCH_PATHS: String = "HEADER_SEARCH_PATHS"
|
const val PODS_TARGET_SRCROOT = "PODS_TARGET_SRCROOT"
|
||||||
const val FRAMEWORK_SEARCH_PATHS: String = "FRAMEWORK_SEARCH_PATHS"
|
const val OTHER_CFLAGS = "OTHER_CFLAGS"
|
||||||
|
const val HEADER_SEARCH_PATHS = "HEADER_SEARCH_PATHS"
|
||||||
|
const val FRAMEWORK_SEARCH_PATHS = "FRAMEWORK_SEARCH_PATHS"
|
||||||
|
|
||||||
fun readSettingsFromStream(inputStream: InputStream): PodBuildSettingsProperties {
|
fun readSettingsFromStream(inputStream: InputStream): PodBuildSettingsProperties {
|
||||||
with(Properties()) {
|
with(Properties()) {
|
||||||
load(inputStream)
|
load(inputStream)
|
||||||
return PodBuildSettingsProperties(
|
return PodBuildSettingsProperties(
|
||||||
getProperty(BUILD_DIR),
|
readProperty(BUILD_DIR),
|
||||||
getProperty(CONFIGURATION),
|
readProperty(CONFIGURATION),
|
||||||
getProperty(OTHER_CFLAGS),
|
readProperty(CONFIGURATION_BUILD_DIR),
|
||||||
getProperty(HEADER_SEARCH_PATHS),
|
readProperty(PODS_TARGET_SRCROOT),
|
||||||
getProperty(FRAMEWORK_SEARCH_PATHS)
|
readNullableProperty(OTHER_CFLAGS),
|
||||||
|
readNullableProperty(HEADER_SEARCH_PATHS),
|
||||||
|
readNullableProperty(FRAMEWORK_SEARCH_PATHS)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Properties.readProperty(propertyName: String) =
|
||||||
|
readNullableProperty(propertyName) ?: error("$propertyName property is absent")
|
||||||
|
|
||||||
|
private fun Properties.readNullableProperty(propertyName: String) =
|
||||||
|
getProperty(propertyName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-24
@@ -15,6 +15,7 @@ import org.gradle.api.tasks.wrapper.Wrapper
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.COCOAPODS_EXTENSION_NAME
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.COCOAPODS_EXTENSION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.GENERATE_WRAPPER_PROPERTY
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.GENERATE_WRAPPER_PROPERTY
|
||||||
@@ -38,18 +39,55 @@ open class PodspecTask : DefaultTask() {
|
|||||||
internal val outputFileProvider: Provider<File>
|
internal val outputFileProvider: Provider<File>
|
||||||
get() = project.provider { project.file("$specName.podspec") }
|
get() = project.provider { project.file("$specName.podspec") }
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
internal lateinit var needPodspec: Provider<Boolean>
|
||||||
|
|
||||||
@get:Nested
|
@get:Nested
|
||||||
internal lateinit var cocoapodsExtension: CocoapodsExtension
|
val pods = project.objects.listProperty(CocoapodsDependency::class.java)
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
internal lateinit var version: Provider<String>
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Optional
|
||||||
|
internal val homepage = project.objects.property(String::class.java)
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Optional
|
||||||
|
internal val license = project.objects.property(String::class.java)
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Optional
|
||||||
|
internal val authors = project.objects.property(String::class.java)
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Optional
|
||||||
|
internal val summary = project.objects.property(String::class.java)
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
internal lateinit var frameworkName: Provider<String>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var ios: Provider<PodspecPlatformSettings>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var osx: Provider<PodspecPlatformSettings>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var tvos: Provider<PodspecPlatformSettings>
|
||||||
|
|
||||||
|
@get:Nested
|
||||||
|
internal lateinit var watchos: Provider<PodspecPlatformSettings>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
onlyIf { cocoapodsExtension.needPodspec }
|
onlyIf { needPodspec.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun generate() {
|
fun generate() {
|
||||||
|
|
||||||
val frameworkDir = project.cocoapodsBuildDirs.framework.relativeTo(outputFileProvider.get().parentFile).path
|
val frameworkDir = project.cocoapodsBuildDirs.framework.relativeTo(outputFileProvider.get().parentFile).path
|
||||||
val dependencies = cocoapodsExtension.pods.map { pod ->
|
val dependencies = pods.get().map { pod ->
|
||||||
val versionSuffix = if (pod.version != null) ", '${pod.version}'" else ""
|
val versionSuffix = if (pod.version != null) ", '${pod.version}'" else ""
|
||||||
"| spec.dependency '${pod.name}'$versionSuffix"
|
"| spec.dependency '${pod.name}'$versionSuffix"
|
||||||
}.joinToString(separator = "\n")
|
}.joinToString(separator = "\n")
|
||||||
@@ -69,10 +107,8 @@ open class PodspecTask : DefaultTask() {
|
|||||||
val syncTask = "${project.path}:$SYNC_TASK_NAME"
|
val syncTask = "${project.path}:$SYNC_TASK_NAME"
|
||||||
|
|
||||||
val deploymentTargets = run {
|
val deploymentTargets = run {
|
||||||
with(cocoapodsExtension) {
|
listOf(ios, osx, tvos, watchos).map { it.get() }.filter { it.deploymentTarget != null }.joinToString("\n") {
|
||||||
listOf(ios, osx, tvos, watchos).filter { it.deploymentTarget != null }.joinToString("\n") {
|
"| spec.${it.name}.deployment_target = '${it.deploymentTarget}'"
|
||||||
"| spec.${it.name}.deployment_target = '${it.deploymentTarget}'"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,15 +117,15 @@ open class PodspecTask : DefaultTask() {
|
|||||||
"""
|
"""
|
||||||
|Pod::Spec.new do |spec|
|
|Pod::Spec.new do |spec|
|
||||||
| spec.name = '$specName'
|
| spec.name = '$specName'
|
||||||
| spec.version = '${cocoapodsExtension.version}'
|
| spec.version = '${version.get()}'
|
||||||
| spec.homepage = '${cocoapodsExtension.homepage.orEmpty()}'
|
| spec.homepage = '${homepage.getOrEmpty()}'
|
||||||
| spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
| spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
|
||||||
| spec.authors = '${cocoapodsExtension.authors.orEmpty()}'
|
| spec.authors = '${authors.getOrEmpty()}'
|
||||||
| spec.license = '${cocoapodsExtension.license.orEmpty()}'
|
| spec.license = '${license.getOrEmpty()}'
|
||||||
| spec.summary = '${cocoapodsExtension.summary.orEmpty()}'
|
| spec.summary = '${summary.getOrEmpty()}'
|
||||||
|
|
|
|
||||||
| spec.static_framework = true
|
| spec.static_framework = true
|
||||||
| spec.vendored_frameworks = "$frameworkDir/${cocoapodsExtension.frameworkName}.framework"
|
| spec.vendored_frameworks = "$frameworkDir/${frameworkName.get()}.framework"
|
||||||
| spec.libraries = "c++"
|
| spec.libraries = "c++"
|
||||||
| spec.module_name = "#{spec.name}_umbrella"
|
| spec.module_name = "#{spec.name}_umbrella"
|
||||||
|
|
|
|
||||||
@@ -143,6 +179,8 @@ open class PodspecTask : DefaultTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Provider<String>.getOrEmpty() = getOrElse("")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val KotlinMultiplatformExtension?.cocoapodsExtensionOrNull: CocoapodsExtension?
|
private val KotlinMultiplatformExtension?.cocoapodsExtensionOrNull: CocoapodsExtension?
|
||||||
get() = (this as? ExtensionAware)?.extensions?.findByName(COCOAPODS_EXTENSION_NAME) as? CocoapodsExtension
|
get() = (this as? ExtensionAware)?.extensions?.findByName(COCOAPODS_EXTENSION_NAME) as? CocoapodsExtension
|
||||||
@@ -167,17 +205,15 @@ open class PodspecTask : DefaultTask() {
|
|||||||
* and then replace it with the real one during a real build process.
|
* and then replace it with the real one during a real build process.
|
||||||
*/
|
*/
|
||||||
open class DummyFrameworkTask : DefaultTask() {
|
open class DummyFrameworkTask : DefaultTask() {
|
||||||
|
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
val destinationDir = project.cocoapodsBuildDirs.framework
|
val destinationDir = project.cocoapodsBuildDirs.framework
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
val frameworkNameProvider: Provider<String> = project.provider { cocoapodsExtension.frameworkName }
|
lateinit var frameworkName: Provider<String>
|
||||||
|
|
||||||
@get:Nested
|
|
||||||
internal lateinit var cocoapodsExtension: CocoapodsExtension
|
|
||||||
|
|
||||||
private val frameworkDir: File
|
private val frameworkDir: File
|
||||||
get() = destinationDir.resolve("${frameworkNameProvider.get()}.framework")
|
get() = destinationDir.resolve("${frameworkName.get()}.framework")
|
||||||
|
|
||||||
private fun copyResource(from: String, to: File) {
|
private fun copyResource(from: String, to: File) {
|
||||||
to.parentFile.mkdirs()
|
to.parentFile.mkdirs()
|
||||||
@@ -225,11 +261,11 @@ open class DummyFrameworkTask : DefaultTask() {
|
|||||||
|
|
||||||
// Copy files for the dummy framework.
|
// Copy files for the dummy framework.
|
||||||
copyFrameworkFile("Info.plist")
|
copyFrameworkFile("Info.plist")
|
||||||
copyFrameworkFile("dummy", frameworkNameProvider.get())
|
copyFrameworkFile("dummy", frameworkName.get())
|
||||||
copyFrameworkFile("Headers/placeholder.h")
|
copyFrameworkFile("Headers/placeholder.h")
|
||||||
copyFrameworkTextFile("Modules/module.modulemap") {
|
copyFrameworkTextFile("Modules/module.modulemap") {
|
||||||
if (it == "framework module dummy {") {
|
if (it == "framework module dummy {") {
|
||||||
it.replace("dummy", frameworkNameProvider.get())
|
it.replace("dummy", frameworkName.get())
|
||||||
} else {
|
} else {
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
@@ -242,12 +278,12 @@ open class DummyFrameworkTask : DefaultTask() {
|
|||||||
*/
|
*/
|
||||||
open class DefFileTask : DefaultTask() {
|
open class DefFileTask : DefaultTask() {
|
||||||
|
|
||||||
@Nested
|
@get:Nested
|
||||||
lateinit var pod: CocoapodsExtension.CocoapodsDependency
|
lateinit var pod: Provider<CocoapodsDependency>
|
||||||
|
|
||||||
@get:OutputFile
|
@get:OutputFile
|
||||||
val outputFile: File
|
val outputFile: File
|
||||||
get() = project.cocoapodsBuildDirs.defs.resolve("${pod.moduleName}.def")
|
get() = project.cocoapodsBuildDirs.defs.resolve("${pod.get().moduleName}.def")
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun generate() {
|
fun generate() {
|
||||||
@@ -255,7 +291,7 @@ open class DefFileTask : DefaultTask() {
|
|||||||
outputFile.writeText(
|
outputFile.writeText(
|
||||||
"""
|
"""
|
||||||
language = Objective-C
|
language = Objective-C
|
||||||
modules = ${pod.moduleName}
|
modules = ${pod.get().moduleName}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user