Didier Villevalois
11/27/2022, 6:16 PMdependenciesFromCurrentContext
) fails to load my base script class (which is in the dependencies of my KSP processor).
Should I do something particular to have all the processor's dependencies in the compilation classpath?
jvm {
dependenciesFromCurrentContext(wholeClasspath = true, unpackJarCollections = true)
}
Didier Villevalois
11/27/2022, 6:18 PMpackage com.github.ptitjes.kmf.script
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*
import kotlinx.coroutines.*
import kotlin.script.experimental.annotations.*
import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.*
import kotlin.script.experimental.dependencies.maven.*
import kotlin.script.experimental.jvm.*
@KotlinScript(
displayName = "Kmf script",
fileExtension = "kmf.kts",
compilationConfiguration = KmfScriptConfiguration::class,
evaluationConfiguration = KmfScriptEvaluation::class,
)
open class KmfScript(
val codeGenerator: CodeGenerator,
val logger: KSPLogger,
val resolver: Resolver,
val deferredSymbols: (symbols: List<KSAnnotated>) -> Unit,
)
object KmfScriptConfiguration : ScriptCompilationConfiguration({
defaultImports(
"com.google.devtools.ksp.*",
"com.google.devtools.ksp.processing.*",
"com.google.devtools.ksp.symbol.*",
"com.github.ptitjes.kmf.*",
)
defaultImports(DependsOn::class, Repository::class)
jvm {
dependenciesFromCurrentContext(wholeClasspath = true, unpackJarCollections = true)
}
// Callbacks
refineConfiguration {
// Process specified annotations with the provided handler
onAnnotations(
DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations
)
}
ide {
acceptedLocations(ScriptAcceptedLocation.Everywhere)
}
})
object KmfScriptEvaluation : ScriptEvaluationConfiguration({
scriptsInstancesSharing(true)
})
// Handler that reconfigures the compilation on the fly
fun configureMavenDepsOnAnnotations(
context: ScriptConfigurationRefinementContext
): ResultWithDiagnostics<ScriptCompilationConfiguration> {
val annotations = context.collectedData?.get(ScriptCollectedData.collectedAnnotations)?.takeIf { it.isNotEmpty() }
?: return context.compilationConfiguration.asSuccess()
return runBlocking {
resolver.resolveFromScriptSourceAnnotations(annotations)
}.onSuccess {
context.compilationConfiguration.with {
dependencies.append(JvmDependency(it))
}.asSuccess()
}
}
private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), MavenDependenciesResolver())
Didier Villevalois
11/27/2022, 6:19 PMpackage com.github.ptitjes.kmf.processing
import com.github.ptitjes.kmf.script.*
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*
import java.io.*
import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.*
import kotlin.script.experimental.jvmhost.*
class KmfSymbolProcessor(
private val scripFile: File,
private val codeGenerator: CodeGenerator,
private val logger: KSPLogger,
) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
var deferredSymbols: List<KSAnnotated>? = null
val diagnostics = evalFile(scripFile, codeGenerator, logger, resolver) { deferredSymbols = it }
diagnostics.reports.forEach { diagnostic ->
if (diagnostic.isError()) logger.error(diagnostic.render())
else if (diagnostic.severity > ScriptDiagnostic.Severity.WARNING) logger.warn(diagnostic.render())
else <http://logger.info|logger.info>(diagnostic.render())
}
diagnostics.onFailure {
error("Kmf processor failed due to script issues")
}
return deferredSymbols ?: listOf()
}
}
fun evalFile(
scriptFile: File,
codeGenerator: CodeGenerator,
logger: KSPLogger,
resolver: Resolver,
deferredSymbols: (symbols: List<KSAnnotated>) -> Unit,
): ResultWithDiagnostics<EvaluationResult> {
val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<KmfScript>()
val evaluationConfiguration = createJvmEvaluationConfigurationFromTemplate<KmfScript> {
constructorArgs(codeGenerator, logger, resolver, deferredSymbols)
}
return BasicJvmScriptingHost().eval(
scriptFile.toScriptSource(),
compilationConfiguration,
evaluationConfiguration
)
}
ilya.chernikov
12/02/2022, 11:09 AMdependenciesFromCurrentContext
is rather hacky helper, that tries to extract the classpath from the current thread classloader. There is no guaranteed way to do it, so I can imagine many situations, where it may fail to extract some parts of the classpath.
So, if it doesn't work for you, you need to pass missing parts of the cp using regular dependencies
key manually.