diff --git a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinTagWriter.kt b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinTagWriter.kt index ca050e2..4647342 100644 --- a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinTagWriter.kt +++ b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinTagWriter.kt @@ -5,12 +5,16 @@ import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.symbol.KSDeclaration -import org.koin.compiler.generator.KoinCodeGenerator.Companion.LOGGER import org.koin.compiler.generator.ext.getNewFile import org.koin.compiler.metadata.KoinMetaData import org.koin.compiler.verify.ext.getResolution import org.koin.compiler.verify.ext.getResolutionForTag import java.io.OutputStream +import java.nio.file.Files +import java.security.DigestOutputStream +import java.security.MessageDigest +import kotlin.io.path.createTempFile +import kotlin.io.path.outputStream const val tagPrefix = "KoinDef" @@ -22,17 +26,36 @@ class KoinTagWriter(val codeGenerator: CodeGenerator, val logger: KSPLogger) { moduleList: List, default : KoinMetaData.Module ) { - val isAlreadyGenerated = codeGenerator.generatedFile.isEmpty() - val allDefinitions = (moduleList + default).flatMap { it.definitions } - if (!isAlreadyGenerated) { logger.logging("Koin Tags Generation ...") - val tagFileName = "KoinMeta-${hashCode()}" - val tagFileStream = writeTagFile(tagFileName) + createTagFile(moduleList, default) + } + } + + /** + * To realize [reproducible-builds](https://reproducible-builds.org/), write everything to a temporal file + * then copy it to the tag file. + * By this method, we can compute the digest of tag file and use it to name it. + * + * @author Kengo TODA + */ + @OptIn(ExperimentalStdlibApi::class) + private fun createTagFile( + moduleList: List, + default : KoinMetaData.Module, + ) { + val allDefinitions = (moduleList + default).flatMap { it.definitions } + val tempFile = createTempFile("KoinMeta", ".kt") + val sha256 = MessageDigest.getInstance("SHA-256"); + DigestOutputStream(tempFile.outputStream(), sha256).buffered().use { + writeModuleTags(moduleList, it) + writeDefinitionsTags(allDefinitions, it) + } - writeModuleTags(moduleList,tagFileStream) - writeDefinitionsTags(allDefinitions,tagFileStream) + val tagFileName = "KoinMeta-${sha256.digest().toHexString(HexFormat.Default)}" + writeTagFile(tagFileName).buffered().use { + Files.copy(tempFile, it) } }