org.gradle.configurationcache.ConfigurationCacheIO.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.configurationcache
import org.gradle.configurationcache.extensions.useToRun
import org.gradle.configurationcache.fingerprint.ConfigurationCacheFingerprint
import org.gradle.configurationcache.problems.ConfigurationCacheProblems
import org.gradle.configurationcache.serialization.DefaultReadContext
import org.gradle.configurationcache.serialization.DefaultWriteContext
import org.gradle.configurationcache.serialization.LoggingTracer
import org.gradle.configurationcache.serialization.Tracer
import org.gradle.configurationcache.serialization.beans.BeanConstructors
import org.gradle.configurationcache.serialization.codecs.Codecs
import org.gradle.configurationcache.serialization.readCollectionInto
import org.gradle.configurationcache.serialization.runReadOperation
import org.gradle.configurationcache.serialization.runWriteOperation
import org.gradle.configurationcache.serialization.writeCollection
import org.gradle.internal.serialize.Encoder
import org.gradle.internal.serialize.kryo.KryoBackedDecoder
import org.gradle.internal.serialize.kryo.KryoBackedEncoder
import org.gradle.internal.service.scopes.Scopes
import org.gradle.internal.service.scopes.ServiceScope
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.DataInputStream
import java.io.DataOutputStream
import java.io.File
import java.io.InputStream
import java.io.OutputStream
@ServiceScope(Scopes.Gradle::class)
class ConfigurationCacheIO internal constructor(
private val host: DefaultConfigurationCache.Host,
private val problems: ConfigurationCacheProblems,
private val scopeRegistryListener: ConfigurationCacheClassLoaderScopeRegistryListener,
private val beanConstructors: BeanConstructors
) {
/**
* See [ConfigurationCacheState.writeRootBuildState].
*/
internal
fun writeRootBuildStateTo(stateFile: ConfigurationCacheStateFile): Set =
writeConfigurationCacheState(stateFile) { cacheState ->
cacheState.run {
writeRootBuildState(host.currentBuild)
}
}
internal
fun readRootBuildStateFrom(stateFile: ConfigurationCacheStateFile) {
withReadContextFor(stateFile.inputStream()) { codecs ->
ConfigurationCacheState(codecs, stateFile).run {
readRootBuildState(host::createBuild)
}
}
}
internal
fun writeIncludedBuildStateTo(stateFile: ConfigurationCacheStateFile, buildTreeState: StoredBuildTreeState) {
writeConfigurationCacheState(stateFile) { cacheState ->
cacheState.run {
writeBuildState(host.currentBuild, buildTreeState)
}
}
}
internal
fun readIncludedBuildStateFrom(stateFile: ConfigurationCacheStateFile, includedBuild: ConfigurationCacheBuild) {
withReadContextFor(stateFile.inputStream()) { codecs ->
ConfigurationCacheState(codecs, stateFile).run {
readBuildState(includedBuild)
}
}
}
private
fun writeConfigurationCacheState(
stateFile: ConfigurationCacheStateFile,
action: suspend DefaultWriteContext.(ConfigurationCacheState) -> T
): T {
val build = host.currentBuild
val (context, codecs) = writerContextFor(stateFile.outputStream(), build.gradle.rootProject.name + " state")
return context.useToRun {
runWriteOperation {
action(ConfigurationCacheState(codecs, stateFile))
}
}
}
internal
fun writerContextFor(outputStream: OutputStream, profile: String): Pair =
codecs().let { codecs ->
KryoBackedEncoder(outputStream).let { encoder ->
writeContextFor(
encoder,
if (logger.isDebugEnabled) LoggingTracer(profile, encoder::getWritePosition, logger)
else null,
codecs
) to codecs
}
}
internal
fun withReadContextFor(
inputStream: InputStream,
readOperation: suspend DefaultReadContext.(Codecs) -> R
): R =
codecs().let { codecs ->
KryoBackedDecoder(inputStream).use { decoder ->
readContextFor(decoder, codecs).run {
initClassLoader(javaClass.classLoader)
runReadOperation {
readOperation(codecs)
}
}
}
}
private
fun writeContextFor(
encoder: Encoder,
tracer: Tracer?,
codecs: Codecs
) = DefaultWriteContext(
codecs.userTypesCodec,
encoder,
scopeRegistryListener,
logger,
tracer,
problems
)
private
fun readContextFor(
decoder: KryoBackedDecoder,
codecs: Codecs
) = DefaultReadContext(
codecs.userTypesCodec,
decoder,
service(),
beanConstructors,
logger,
problems
)
private
fun codecs(): Codecs =
Codecs(
directoryFileTreeFactory = service(),
fileCollectionFactory = service(),
artifactSetConverter = service(),
fileLookup = service(),
propertyFactory = service(),
filePropertyFactory = service(),
fileResolver = service(),
instantiator = service(),
listenerManager = service(),
taskNodeFactory = service(),
fingerprinterRegistry = service(),
buildOperationExecutor = service(),
classLoaderHierarchyHasher = service(),
isolatableFactory = service(),
valueSnapshotter = service(),
managedFactoryRegistry = service(),
parameterScheme = service(),
actionScheme = service(),
attributesFactory = service(),
valueSourceProviderFactory = service(),
calculatedValueContainerFactory = service(),
patternSetFactory = factory(),
fileOperations = service(),
fileFactory = service(),
includedTaskGraph = service(),
buildStateRegistry = service()
)
private
inline fun service() =
host.service()
private
inline fun factory() =
host.factory(T::class.java)
}
internal
fun writeConfigurationCacheFingerprintHeaderTo(outputStream: OutputStream, header: ConfigurationCacheFingerprint.Header) {
val buildRootDirs = header.includedBuildRootDirs
if (buildRootDirs.isEmpty()) {
outputStream.writeInt(0)
return
}
ByteArrayOutputStream().let { bos ->
writeFileSetTo(bos, buildRootDirs)
outputStream.writeInt(bos.size())
bos.writeTo(outputStream)
}
}
internal
fun readConfigurationCacheFingerprintHeaderFrom(inputStream: InputStream): ConfigurationCacheFingerprint.Header? {
val headerSize = inputStream.readInt()
if (headerSize == 0) {
return null
}
val headerBytes = ByteArray(headerSize)
require(inputStream.read(headerBytes) == headerSize)
return ConfigurationCacheFingerprint.Header(
readFileSetFrom(ByteArrayInputStream(headerBytes))
)
}
private
fun writeFileSetTo(outputStream: OutputStream, files: Set) {
KryoBackedEncoder(outputStream).useToRun {
writeCollection(files) { file ->
writeString(file.path)
}
}
}
private
fun readFileSetFrom(inputStream: InputStream) =
KryoBackedDecoder(inputStream).run {
readCollectionInto(::LinkedHashSet) {
File(readString())
}
}
private
fun OutputStream.writeInt(i: Int) = DataOutputStream(this).writeInt(i)
private
fun InputStream.readInt() = DataInputStream(this).readInt()
© 2015 - 2025 Weber Informatics LLC | Privacy Policy