[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.base64Hash
|
||||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.ensureMaxFileNameLength
|
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.ensureMaxFileNameLength
|
||||||
import org.jetbrains.kotlin.commonizer.identityString
|
import org.jetbrains.kotlin.commonizer.identityString
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.changing
|
||||||
import org.jetbrains.kotlin.gradle.utils.outputFilesProvider
|
import org.jetbrains.kotlin.gradle.utils.outputFilesProvider
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -34,8 +35,10 @@ internal fun AbstractCInteropCommonizerTask.outputDirectory(group: CInteropCommo
|
|||||||
|
|
||||||
internal fun AbstractCInteropCommonizerTask.commonizedOutputLibraries(dependent: CInteropCommonizerDependent): FileCollection {
|
internal fun AbstractCInteropCommonizerTask.commonizedOutputLibraries(dependent: CInteropCommonizerDependent): FileCollection {
|
||||||
return outputFilesProvider {
|
return outputFilesProvider {
|
||||||
(commonizedOutputDirectory(dependent) ?: return@outputFilesProvider emptySet<File>())
|
val outputDirectory = commonizedOutputDirectory(dependent) ?: return@outputFilesProvider emptySet<File>()
|
||||||
.listFiles().orEmpty().toSet()
|
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.ListProperty
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.provider.Provider
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.gradle.api.provider.ProviderFactory
|
||||||
import org.gradle.api.provider.SetProperty
|
import org.gradle.api.provider.SetProperty
|
||||||
|
import org.gradle.api.provider.ValueSource
|
||||||
|
import org.gradle.api.provider.ValueSourceParameters
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.reflect.KProperty
|
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> =
|
internal inline fun <reified T> Project.setProperty(noinline itemsProvider: () -> Iterable<T>): SetProperty<T> =
|
||||||
objects.setProperty(T::class.java).apply { set(provider(itemsProvider)) }
|
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