[Gradle] Evaluate commonizedOutputLibraries in a changing provider
Add `changing` provider for Configuration Cache compatibility. This makes AbstractCInteropCommonizerTask be compatible with Configuration Cache. ^KT-49933
This commit is contained in:
committed by
Space Team
parent
15f2179557
commit
458e69f698
+5
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.base64Hash
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.ensureMaxFileNameLength
|
||||
import org.jetbrains.kotlin.commonizer.identityString
|
||||
import org.jetbrains.kotlin.gradle.utils.changing
|
||||
import org.jetbrains.kotlin.gradle.utils.outputFilesProvider
|
||||
import java.io.File
|
||||
|
||||
@@ -34,8 +35,10 @@ internal fun AbstractCInteropCommonizerTask.outputDirectory(group: CInteropCommo
|
||||
|
||||
internal fun AbstractCInteropCommonizerTask.commonizedOutputLibraries(dependent: CInteropCommonizerDependent): FileCollection {
|
||||
return outputFilesProvider {
|
||||
(commonizedOutputDirectory(dependent) ?: return@outputFilesProvider emptySet<File>())
|
||||
.listFiles().orEmpty().toSet()
|
||||
val outputDirectory = commonizedOutputDirectory(dependent) ?: return@outputFilesProvider emptySet<File>()
|
||||
project.providers.changing {
|
||||
outputDirectory.listFiles().orEmpty().toSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -13,7 +13,10 @@ import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.provider.SetProperty
|
||||
import org.gradle.api.provider.ValueSource
|
||||
import org.gradle.api.provider.ValueSourceParameters
|
||||
import java.io.File
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -125,3 +128,41 @@ internal inline fun <reified T> Project.listProperty(noinline itemsProvider: ()
|
||||
|
||||
internal inline fun <reified T> Project.setProperty(noinline itemsProvider: () -> Iterable<T>): SetProperty<T> =
|
||||
objects.setProperty(T::class.java).apply { set(provider(itemsProvider)) }
|
||||
|
||||
/**
|
||||
* Changing Provider will be evaluated every time it accessed.
|
||||
*
|
||||
* And its producing [code] will be serilalised to Configuration Cache as is
|
||||
* So that it still will be evaluated during Task Execution phase.
|
||||
* It is very convenient for Configuration Cache compatibility.
|
||||
*
|
||||
* It is recommended to use Task Output's and map/flatMap them to other Task Inputs but in cases when TaskOutput's is not available
|
||||
* as Gradle's Properties or Providers then this [changing] provider can be used.
|
||||
*
|
||||
* name `changing` and overall concept is borrowed from Gradle internal API [org.gradle.api.internal.provider.Providers.changing]
|
||||
*
|
||||
* @see org.gradle.api.internal.provider.ChangingProvider
|
||||
*/
|
||||
internal fun <T> ProviderFactory.changing(code: () -> T): Provider<T> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val adhocValueSourceClass = AdhocValueSource::class.java as Class<AdhocValueSource<T>>
|
||||
return of(adhocValueSourceClass) { valueSourceSpec ->
|
||||
valueSourceSpec.parameters {
|
||||
it.producingLambda.set(code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class AdhocValueSource<T> : ValueSource<T, AdhocValueSource.Parameters> {
|
||||
|
||||
// this interface can't be parameterized with T since it breaks internal Gradle logic
|
||||
// This is why producingLambda is '() -> Any?' but not '() -> T'
|
||||
interface Parameters : ValueSourceParameters {
|
||||
val producingLambda: Property<() -> Any?>
|
||||
}
|
||||
|
||||
override fun obtain(): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return parameters.producingLambda.get().invoke() as T
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user