[Gradle, Cocoapods] Refactor, log process outputs with info level

Also fixed broken `stdErr` processing for `xcodebuild` commands.

#KT-42938 Fixed
This commit is contained in:
Yaroslav Chernyshev
2020-10-26 21:56:25 +03:00
parent 67b262aa34
commit a3b951e505
2 changed files with 59 additions and 86 deletions
@@ -282,9 +282,9 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java) project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java)
val buildSettings = val buildSettings =
podBuildTaskProvider.get().buildSettingsFile.get() podBuildTaskProvider.get().buildSettingsFile.get()
.inputStream() .reader()
.use { .use {
PodBuildSettingsProperties.readSettingsFromStream(it) PodBuildSettingsProperties.readSettingsFromReader(it)
} }
buildSettings.cflags?.let { args -> buildSettings.cflags?.let { args ->
@@ -10,6 +10,7 @@ import org.gradle.api.artifacts.repositories.ArtifactRepository
import org.gradle.api.file.FileCollection 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.logging.Logger
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
@@ -22,8 +23,7 @@ import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrievePods
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrieveSpecRepos import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrieveSpecRepos
import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.Reader
import java.io.InputStream
import java.net.URI import java.net.URI
import java.util.* import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
@@ -108,6 +108,11 @@ open class PodInstallTask : DefaultTask() {
} }
} }
private interface ExtendedErrorDiagnostic {
fun isAppropriateOutput(output: String): Boolean
val message: String
}
abstract class DownloadCocoapodsTask : DefaultTask() { abstract class DownloadCocoapodsTask : DefaultTask() {
@get:Input @get:Input
internal lateinit var podName: Provider<String> internal lateinit var podName: Provider<String>
@@ -233,14 +238,14 @@ open class PodDownloadGitTask : DownloadCocoapodsTask() {
} }
private fun retrieveCommit(url: URI, commit: String) { private fun retrieveCommit(url: URI, commit: String) {
val logger = project.logger
val initCommand = listOf( val initCommand = listOf(
"git", "git",
"init" "init"
) )
val repo = repo.get() val repo = repo.get()
repo.mkdir() repo.mkdir()
val configProcess: ProcessBuilder.() -> Unit = { directory(repo) } runCommand(initCommand, logger) { directory(repo) }
runCommand(initCommand, configProcess)
val fetchCommand = listOf( val fetchCommand = listOf(
"git", "git",
@@ -249,14 +254,14 @@ open class PodDownloadGitTask : DownloadCocoapodsTask() {
"$url", "$url",
commit commit
) )
runCommand(fetchCommand, configProcess) runCommand(fetchCommand, logger) { directory(repo) }
val checkoutCommand = listOf( val checkoutCommand = listOf(
"git", "git",
"checkout", "checkout",
"FETCH_HEAD" "FETCH_HEAD"
) )
runCommand(checkoutCommand, configProcess) runCommand(checkoutCommand, logger) { directory(repo) }
} }
private fun cloneShallow(url: URI, branch: String) { private fun cloneShallow(url: URI, branch: String) {
@@ -268,8 +273,7 @@ open class PodDownloadGitTask : DownloadCocoapodsTask() {
"--branch", branch, "--branch", branch,
"--depth", "1" "--depth", "1"
) )
val configProcess: ProcessBuilder.() -> Unit = { directory(gitDir) } runCommand(shallowCloneCommand, project.logger) { directory(gitDir) }
runCommand(shallowCloneCommand, configProcess)
} }
private fun cloneHead(podspecLocation: Git) { private fun cloneHead(podspecLocation: Git) {
@@ -280,8 +284,7 @@ open class PodDownloadGitTask : DownloadCocoapodsTask() {
podName.get(), podName.get(),
"--depth", "1" "--depth", "1"
) )
val configProcess: ProcessBuilder.() -> Unit = { directory(gitDir) } runCommand(cloneHeadCommand, project.logger) { directory(gitDir) }
runCommand(cloneHeadCommand, configProcess)
} }
private fun fallback(podspecLocation: Git) { private fun fallback(podspecLocation: Git) {
@@ -293,21 +296,20 @@ open class PodDownloadGitTask : DownloadCocoapodsTask() {
"${podspecLocation.url}", "${podspecLocation.url}",
podName.get() podName.get()
) )
val configProcess: ProcessBuilder.() -> Unit = { directory(gitDir) } runCommand(cloneAllCommand, project.logger) { directory(gitDir) }
runCommand(cloneAllCommand, configProcess)
} }
} }
private fun runCommand( private fun runCommand(
command: List<String>, command: List<String>,
processConfiguration: ((ProcessBuilder.() -> Unit))? = null, logger: Logger,
errorHandler: ((retCode: Int, process: Process) -> Unit)? = null extendedErrorDiagnostic: ExtendedErrorDiagnostic? = null,
errorHandler: ((retCode: Int, process: Process) -> Unit)? = null,
processConfiguration: ProcessBuilder.() -> Unit = { }
): String { ): String {
val process = ProcessBuilder(command) val process = ProcessBuilder(command)
.apply { .apply {
if (processConfiguration != null) { this.processConfiguration()
this.processConfiguration()
}
}.start() }.start()
var inputText = "" var inputText = ""
@@ -329,9 +331,22 @@ private fun runCommand(
errorThread.join() errorThread.join()
val retCode = process.waitFor() val retCode = process.waitFor()
logger.info(
"""
|Information about "${command.joinToString(" ")}" call:
|
|${inputText}
""".trimMargin()
)
check(retCode == 0) { check(retCode == 0) {
errorHandler?.invoke(retCode, process) errorHandler?.invoke(retCode, process)
?: "Executing of '${command.joinToString(" ")}' failed with code $retCode and message: $errorText" ?: """
|Executing of '${command.joinToString(" ")}' failed with code $retCode and message:
|
|$errorText
|${extendedErrorDiagnostic?.takeIf { it.isAppropriateOutput(inputText) }?.message ?: ""}
""".trimMargin()
} }
return inputText return inputText
@@ -390,32 +405,24 @@ open class PodGenTask : DefaultTask() {
podspec.get().absolutePath podspec.get().absolutePath
) )
val podGenProcess = ProcessBuilder(podGenProcessArgs).apply { val podGenDiagnostic = object : ExtendedErrorDiagnostic {
directory(syntheticDir) override fun isAppropriateOutput(output: String): Boolean =
}.start() output.contains("deployment target") || output.contains("requested platforms: [\"${family.platformLiteral}\"]")
val podGenRetCode = podGenProcess.waitFor()
val outputText = podGenProcess.inputStream.use { it.reader().readText() }
check(podGenRetCode == 0) { override val message: String
listOfNotNull( get() =
"Executing of '${podGenProcessArgs.joinToString(" ")}' failed with code $podGenRetCode and message:",
outputText,
outputText.takeIf {
it.contains("deployment target")
|| it.contains("requested platforms: [\"${family.platformLiteral}\"]")
}?.let {
""" """
Tip: try to configure deployment_target for ALL targets as follows: |Tip: try to configure deployment_target for ALL targets as follows:
cocoapods { |cocoapods {
... | ...
${family.name.toLowerCase()}.deploymentTarget = "..." | ${family.name.toLowerCase()}.deploymentTarget = "..."
... | ...
} |}
""".trimIndent() """.trimMargin()
}
).joinToString("\n")
} }
runCommand(podGenProcessArgs, project.logger, podGenDiagnostic) { directory(syntheticDir) }
val podsXcprojFile = podsXcodeProjDir.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."
@@ -456,23 +463,11 @@ open class PodSetupBuildTask : DefaultTask() {
"-sdk", sdk.get() "-sdk", sdk.get()
) )
val buildSettingsProcess = ProcessBuilder(buildSettingsReceivingCommand) val outputText = runCommand(buildSettingsReceivingCommand, project.logger) { directory(podsXcodeProjDir.parentFile) }
.apply {
directory(podsXcodeProjDir.parentFile)
}.start()
val buildSettingsRetCode = buildSettingsProcess.waitFor() val buildSettingsProperties = PodBuildSettingsProperties.readSettingsFromReader(outputText.reader())
check(buildSettingsRetCode == 0) { buildSettingsFile.get().let { bsf ->
listOf( buildSettingsProperties.writeSettings(bsf)
"Executing of '${buildSettingsReceivingCommand.joinToString(" ")}' failed with code $buildSettingsRetCode and message:",
buildSettingsProcess.errorStream.use { it.reader().readText() }
).joinToString("\n")
}
val stdOut = buildSettingsProcess.inputStream
val buildSettingsProperties = PodBuildSettingsProperties.readSettingsFromStream(stdOut)
buildSettingsFile.get().let {
buildSettingsProperties.writeSettings(it)
} }
} }
} }
@@ -494,20 +489,12 @@ open class PodBuildTask : DefaultTask() {
@get:InputFiles @get:InputFiles
internal val srcDir: FileTree internal val srcDir: FileTree
get() = project.fileTree( get() = project.fileTree(
buildSettingsFile.map { buildSettingsFile.map { PodBuildSettingsProperties.readSettingsFromReader(it.reader()).podsTargetSrcRoot }
PodBuildSettingsProperties.readSettingsFromStream(
FileInputStream(it)
).podsTargetSrcRoot
}
) )
@get:Internal @get:Internal
internal var buildDir: Provider<File> = project.provider { internal var buildDir: Provider<File> = project.provider {
project.file( project.file(PodBuildSettingsProperties.readSettingsFromReader(buildSettingsFile.get().reader()).buildDir)
PodBuildSettingsProperties.readSettingsFromStream(
FileInputStream(buildSettingsFile.get())
).buildDir
)
} }
@get:Input @get:Input
@@ -526,9 +513,7 @@ open class PodBuildTask : DefaultTask() {
@TaskAction @TaskAction
fun buildDependencies() { fun buildDependencies() {
val podBuildSettings = PodBuildSettingsProperties.readSettingsFromStream( val podBuildSettings = PodBuildSettingsProperties.readSettingsFromReader(buildSettingsFile.get().reader())
FileInputStream(buildSettingsFile.get())
)
val podsXcodeProjDir = podsXcodeProjDir.get() val podsXcodeProjDir = podsXcodeProjDir.get()
@@ -540,19 +525,7 @@ open class PodBuildTask : DefaultTask() {
"-configuration", podBuildSettings.configuration "-configuration", podBuildSettings.configuration
) )
val podBuildProcess = ProcessBuilder(podXcodeBuildCommand) runCommand(podXcodeBuildCommand, project.logger) { directory(podsXcodeProjDir.parentFile) }
.apply {
directory(podsXcodeProjDir.parentFile)
inheritIO()
}.start()
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")
}
} }
} }
@@ -596,9 +569,9 @@ internal data class PodBuildSettingsProperties(
const val HEADER_SEARCH_PATHS = "HEADER_SEARCH_PATHS" const val HEADER_SEARCH_PATHS = "HEADER_SEARCH_PATHS"
const val FRAMEWORK_SEARCH_PATHS = "FRAMEWORK_SEARCH_PATHS" const val FRAMEWORK_SEARCH_PATHS = "FRAMEWORK_SEARCH_PATHS"
fun readSettingsFromStream(inputStream: InputStream): PodBuildSettingsProperties { fun readSettingsFromReader(reader: Reader): PodBuildSettingsProperties {
with(Properties()) { with(Properties()) {
load(inputStream) load(reader)
return PodBuildSettingsProperties( return PodBuildSettingsProperties(
readProperty(BUILD_DIR), readProperty(BUILD_DIR),
readProperty(CONFIGURATION), readProperty(CONFIGURATION),