Skip to content

Commit

Permalink
add option to use runtimeClasspath
Browse files Browse the repository at this point in the history
  • Loading branch information
NecroKote committed Aug 13, 2024
1 parent 8c40b4f commit 441fc96
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,44 @@ import java.nio.file.Path
import java.nio.file.PathMatcher
import java.nio.file.FileSystems

fun defaultClassPathResolver(workspaceRoots: Collection<Path>, db: Database? = null): ClassPathResolver {
data class ResolverOptions(
// Whether to use the compile classpath or the runtime classpath during classpath resolution
val useCompileClasspath: Boolean,
) {
companion object {
fun default(): ResolverOptions {
return ResolverOptions(useCompileClasspath = true)
}
}
}

val DefaultResolverOptions = ResolverOptions.default()

fun defaultClassPathResolver(
workspaceRoots: Collection<Path>,
db: Database? = null,
resolverOptions: ResolverOptions = DefaultResolverOptions,
): ClassPathResolver {
val childResolver = WithStdlibResolver(
ShellClassPathResolver.global(workspaceRoots.firstOrNull())
.or(workspaceRoots.asSequence().flatMap { workspaceResolvers(it) }.joined)
.or(workspaceRoots.asSequence().flatMap { workspaceResolvers(it, resolverOptions) }.joined)
).or(BackupClassPathResolver)

return db?.let { CachedClassPathResolver(childResolver, it) } ?: childResolver
}

/** Searches the workspace for all files that could provide classpath info. */
private fun workspaceResolvers(workspaceRoot: Path): Sequence<ClassPathResolver> {
private fun workspaceResolvers(workspaceRoot: Path, resolverOptions: ResolverOptions): Sequence<ClassPathResolver> {
val ignored: List<PathMatcher> = ignoredPathPatterns(workspaceRoot, workspaceRoot.resolve(".gitignore"))
return folderResolvers(workspaceRoot, ignored).asSequence()
return folderResolvers(workspaceRoot, ignored, resolverOptions).asSequence()
}

/** Searches the folder for all build-files. */
private fun folderResolvers(root: Path, ignored: List<PathMatcher>): Collection<ClassPathResolver> =
private fun folderResolvers(root: Path, ignored: List<PathMatcher>, resolverOptions: ResolverOptions): Collection<ClassPathResolver> =
root.toFile()
.walk()
.onEnter { file -> ignored.none { it.matches(file.toPath()) } }
.mapNotNull { asClassPathProvider(it.toPath()) }
.mapNotNull { asClassPathProvider(it.toPath(), resolverOptions) }
.toList()

/** Tries to read glob patterns from a gitignore. */
Expand All @@ -51,7 +68,7 @@ private fun ignoredPathPatterns(root: Path, gitignore: Path): List<PathMatcher>
?: emptyList()

/** Tries to create a classpath resolver from a file using as many sources as possible */
private fun asClassPathProvider(path: Path): ClassPathResolver? =
private fun asClassPathProvider(path: Path, resolverOptions: ResolverOptions): ClassPathResolver? =
MavenClassPathResolver.maybeCreate(path)
?: GradleClassPathResolver.maybeCreate(path)
?: GradleClassPathResolver.maybeCreate(path, resolverOptions)
?: ShellClassPathResolver.maybeCreate(path)
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

internal class GradleClassPathResolver(private val path: Path, private val includeKotlinDSL: Boolean): ClassPathResolver {
internal class GradleClassPathResolver(
private val path: Path,
private val includeKotlinDSL: Boolean,
private val useCompileClasspath: Boolean
): ClassPathResolver {
override val resolverType: String = "Gradle"
private val projectDirectory: Path get() = path.parent

override val classpath: Set<ClassPathEntry> get() {
val scripts = listOf("projectClassPathFinder.gradle")
val tasks = listOf("kotlinLSPProjectDeps")

return readDependenciesViaGradleCLI(projectDirectory, scripts, tasks)
return readDependenciesViaGradleCLI(projectDirectory, scripts, tasks, useCompileClasspath)
.apply { if (isNotEmpty()) LOG.info("Successfully resolved dependencies for '${projectDirectory.fileName}' using Gradle") }
.map { ClassPathEntry(it, null) }.toSet()
}
Expand All @@ -38,9 +42,15 @@ internal class GradleClassPathResolver(private val path: Path, private val inclu

companion object {
/** Create a Gradle resolver if a file is a pom. */
fun maybeCreate(file: Path): GradleClassPathResolver? =
fun maybeCreate(file: Path, options: ResolverOptions): GradleClassPathResolver? =
file.takeIf { file.endsWith("build.gradle") || file.endsWith("build.gradle.kts") }
?.let { GradleClassPathResolver(it, includeKotlinDSL = file.toString().endsWith(".kts")) }
?.let {
GradleClassPathResolver(
path = it,
includeKotlinDSL = file.endsWith(".kts"),
useCompileClasspath = options.useCompileClasspath,
)
}
}
}

Expand Down Expand Up @@ -73,13 +83,26 @@ private fun getGradleCommand(workspace: Path): Path {
}
}

private fun readDependenciesViaGradleCLI(projectDirectory: Path, gradleScripts: List<String>, gradleTasks: List<String>): Set<Path> {
private fun readDependenciesViaGradleCLI(
projectDirectory: Path,
gradleScripts: List<String>,
gradleTasks: List<String>,
useCompileClasspath: Boolean = true,
): Set<Path> {
LOG.info("Resolving dependencies for '{}' through Gradle's CLI using tasks {}...", projectDirectory.fileName, gradleTasks)

val tmpScripts = gradleScripts.map { gradleScriptToTempFile(it, deleteOnExit = false).toPath().toAbsolutePath() }
val gradle = getGradleCommand(projectDirectory)

val command = listOf(gradle.toString()) + tmpScripts.flatMap { listOf("-I", it.toString()) } + gradleTasks + listOf("--console=plain")
val command = mutableListOf<String>().apply {
add(gradle.toString())
addAll(tmpScripts.flatMap { listOf("-I", it.toString()) })
addAll(gradleTasks)
add("--console=plain")

if (useCompileClasspath) add("-PuseCompileClasspath=1")
}.toList()

val dependencies = findGradleCLIDependencies(command, projectDirectory)
?.also { LOG.debug("Classpath for task {}", it) }
.orEmpty()
Expand Down
5 changes: 4 additions & 1 deletion shared/src/main/resources/projectClassPathFinder.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ allprojects { project ->
}
} else if (project.hasProperty('sourceSets')) {
// Print the list of all dependencies jar files.
def useCompileClasspath = project.hasProperty("useCompileClasspath")

sourceSets.forEach {
it.compileClasspath.forEach {
def classPathSource = useCompileClasspath ? it.compileClasspath : it.runtimeClasspath
classPathSource.forEach {
System.out.println "kotlin-lsp-gradle $it"
}
}
Expand Down

0 comments on commit 441fc96

Please sign in to comment.