KT-57650 run pod install --repo-update if repo is out of date
This commit is contained in:
committed by
Space Team
parent
da4c6dd443
commit
4cdb9301ed
+25
-15
@@ -11,10 +11,10 @@ import org.gradle.api.provider.Property
|
|||||||
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.work.DisableCachingByDefault
|
import org.gradle.work.DisableCachingByDefault
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.CommandFallback
|
||||||
import org.jetbrains.kotlin.gradle.utils.onlyIfCompat
|
import org.jetbrains.kotlin.gradle.utils.onlyIfCompat
|
||||||
import org.jetbrains.kotlin.gradle.utils.runCommand
|
import org.jetbrains.kotlin.gradle.utils.runCommandWithFallback
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The task takes the path to the Podfile and calls `pod install`
|
* The task takes the path to the Podfile and calls `pod install`
|
||||||
@@ -45,19 +45,7 @@ abstract class AbstractPodInstallTask : CocoapodsTask() {
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
open fun doPodInstall() {
|
open fun doPodInstall() {
|
||||||
// env is used here to work around the JVM PATH caching when spawning a child process with custom environment, i.e. LC_ALL
|
runPodInstall(false)
|
||||||
// The caching causes the ProcessBuilder to ignore changes in the PATH that may occur on incremental runs of the Gradle daemon
|
|
||||||
// KT-60394
|
|
||||||
val podInstallCommand = listOf("env", "pod", "install")
|
|
||||||
|
|
||||||
runCommand(podInstallCommand,
|
|
||||||
logger,
|
|
||||||
errorHandler = { retCode, output, process -> sharedHandleError(podInstallCommand, retCode, output, process) },
|
|
||||||
processConfiguration = {
|
|
||||||
directory(workingDir.get())
|
|
||||||
// CocoaPods requires to be run with Unicode external encoding
|
|
||||||
environment().putIfAbsent("LC_ALL", "en_US.UTF-8")
|
|
||||||
})
|
|
||||||
|
|
||||||
with(podsXcodeProjDirProvider.get()) {
|
with(podsXcodeProjDirProvider.get()) {
|
||||||
check(exists() && isDirectory) {
|
check(exists() && isDirectory) {
|
||||||
@@ -66,6 +54,28 @@ abstract class AbstractPodInstallTask : CocoapodsTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun runPodInstall(updateRepo: Boolean): String {
|
||||||
|
// env is used here to work around the JVM PATH caching when spawning a child process with custom environment, i.e. LC_ALL
|
||||||
|
// The caching causes the ProcessBuilder to ignore changes in the PATH that may occur on incremental runs of the Gradle daemon
|
||||||
|
// KT-60394
|
||||||
|
val podInstallCommand = listOfNotNull("env", "pod", "install", if (updateRepo) "--repo-update" else null)
|
||||||
|
|
||||||
|
return runCommandWithFallback(podInstallCommand,
|
||||||
|
logger,
|
||||||
|
fallback = { retCode, output, process ->
|
||||||
|
if (output.contains("out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`") && updateRepo.not()) {
|
||||||
|
CommandFallback.Action(runPodInstall(true))
|
||||||
|
} else {
|
||||||
|
CommandFallback.Error(sharedHandleError(podInstallCommand, retCode, output, process))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
processConfiguration = {
|
||||||
|
directory(workingDir.get())
|
||||||
|
// CocoaPods requires to be run with Unicode external encoding
|
||||||
|
environment().putIfAbsent("LC_ALL", "en_US.UTF-8")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun sharedHandleError(podInstallCommand: List<String>, retCode: Int, error: String, process: Process): String? {
|
private fun sharedHandleError(podInstallCommand: List<String>, retCode: Int, error: String, process: Process): String? {
|
||||||
return if (error.contains("No such file or directory")) {
|
return if (error.contains("No such file or directory")) {
|
||||||
val command = podInstallCommand.joinToString(" ")
|
val command = podInstallCommand.joinToString(" ")
|
||||||
|
|||||||
+79
-15
@@ -6,15 +6,80 @@
|
|||||||
package org.jetbrains.kotlin.gradle.utils
|
package org.jetbrains.kotlin.gradle.utils
|
||||||
|
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import java.io.IOException
|
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a command and returns the input text.
|
||||||
|
*
|
||||||
|
* @param command the command and its arguments to be executed as a list of strings.
|
||||||
|
* @param logger an optional logger to log information about the command execution.
|
||||||
|
* @param errorHandler (Optional) A function that handles any errors that occur during the command execution.
|
||||||
|
* @param processConfiguration a function to configure the process before execution.
|
||||||
|
* @return The input text of the executed command.
|
||||||
|
*/
|
||||||
internal fun runCommand(
|
internal fun runCommand(
|
||||||
command: List<String>,
|
command: List<String>,
|
||||||
logger: Logger? = null,
|
logger: Logger? = null,
|
||||||
errorHandler: ((retCode: Int, output: String, process: Process) -> String?)? = null,
|
errorHandler: ((retCode: Int, output: String, process: Process) -> String?)? = null,
|
||||||
processConfiguration: ProcessBuilder.() -> Unit = { }
|
processConfiguration: ProcessBuilder.() -> Unit = { },
|
||||||
): String {
|
): String {
|
||||||
|
val runResult = assembleAndRunProcess(command, logger, processConfiguration)
|
||||||
|
check(runResult.retCode == 0) {
|
||||||
|
errorHandler?.invoke(runResult.retCode, runResult.output, runResult.process) ?: createErrorMessage(command, runResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
return runResult.inputText
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sealed class representing the fallback behavior for a command.
|
||||||
|
*/
|
||||||
|
sealed class CommandFallback {
|
||||||
|
data class Action(val fallback: String) : CommandFallback()
|
||||||
|
data class Error(val error: String?) : CommandFallback()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the specified command with fallback behavior in case of non-zero return code.
|
||||||
|
*
|
||||||
|
* @param command the command and its arguments to be executed as a list of strings.
|
||||||
|
* @param logger an optional logger to log information about the command execution.
|
||||||
|
* @param fallback a function that provides the fallback behavior. It takes the return code, output, and process as parameters and returns a [CommandFallback] object.
|
||||||
|
* @param processConfiguration a function to configure the process before execution.
|
||||||
|
* @return the output of the command if the return code is 0, otherwise the fallback action or error.
|
||||||
|
*/
|
||||||
|
internal fun runCommandWithFallback(
|
||||||
|
command: List<String>,
|
||||||
|
logger: Logger? = null,
|
||||||
|
fallback: (retCode: Int, output: String, process: Process) -> CommandFallback,
|
||||||
|
processConfiguration: ProcessBuilder.() -> Unit = { },
|
||||||
|
): String {
|
||||||
|
val runResult = assembleAndRunProcess(command, logger, processConfiguration)
|
||||||
|
return if (runResult.retCode != 0) {
|
||||||
|
when (val fallbackOption = fallback(runResult.retCode, runResult.output, runResult.process)) {
|
||||||
|
is CommandFallback.Action -> fallbackOption.fallback
|
||||||
|
is CommandFallback.Error -> error(fallbackOption.error ?: createErrorMessage(command, runResult))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runResult.inputText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class RunProcessResult(
|
||||||
|
val inputText: String,
|
||||||
|
val errorText: String,
|
||||||
|
val retCode: Int,
|
||||||
|
val process: Process,
|
||||||
|
) {
|
||||||
|
val output: String get() = inputText.ifBlank { errorText }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assembleAndRunProcess(
|
||||||
|
command: List<String>,
|
||||||
|
logger: Logger? = null,
|
||||||
|
processConfiguration: ProcessBuilder.() -> Unit = { },
|
||||||
|
): RunProcessResult {
|
||||||
|
|
||||||
val process = ProcessBuilder(command).apply {
|
val process = ProcessBuilder(command).apply {
|
||||||
this.processConfiguration()
|
this.processConfiguration()
|
||||||
}.start()
|
}.start()
|
||||||
@@ -46,17 +111,16 @@ internal fun runCommand(
|
|||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
)
|
)
|
||||||
|
|
||||||
check(retCode == 0) {
|
return RunProcessResult(inputText, errorText, retCode, process)
|
||||||
errorHandler?.invoke(retCode, inputText.ifBlank { errorText }, process)
|
}
|
||||||
?: """
|
|
||||||
|Executing of '${command.joinToString(" ")}' failed with code $retCode and message:
|
private fun createErrorMessage(command: List<String>, runResult: RunProcessResult): String {
|
||||||
|
|
return """
|
||||||
|$inputText
|
|Executing of '${command.joinToString(" ")}' failed with code ${runResult.retCode} and message:
|
||||||
|
|
|
|
||||||
|$errorText
|
|${runResult.inputText}
|
||||||
|
|
|
|
||||||
""".trimMargin()
|
|${runResult.errorText}
|
||||||
}
|
|
|
||||||
|
""".trimMargin()
|
||||||
return inputText
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user