From 0c30db14aa8eb8026b7ffba4b7d05a794b4c1194 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Wed, 15 Mar 2023 11:47:26 -0600 Subject: [PATCH] Use the EclipseModel directly to fetch dependencies --- .../kt/classpath/GradleClassPathResolver.kt | 32 ++++++++++------ .../resources/projectClassPathFinder.gradle | 37 +++++++++++++++---- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/shared/src/main/kotlin/org/javacs/kt/classpath/GradleClassPathResolver.kt b/shared/src/main/kotlin/org/javacs/kt/classpath/GradleClassPathResolver.kt index 60c1b8eed..5476a2224 100644 --- a/shared/src/main/kotlin/org/javacs/kt/classpath/GradleClassPathResolver.kt +++ b/shared/src/main/kotlin/org/javacs/kt/classpath/GradleClassPathResolver.kt @@ -19,15 +19,18 @@ internal class GradleClassPathResolver(private val path: Path, private val inclu return readDependenciesViaGradleCLI(projectDirectory, scripts, tasks) .apply { if (isNotEmpty()) LOG.info("Successfully resolved dependencies for '${projectDirectory.fileName}' using Gradle") } - .map { ClassPathEntry(it, null) }.toSet() } - override val buildScriptClasspath: Set get() { + override val buildScriptClasspath: Set + get() { return if (includeKotlinDSL) { val scripts = listOf("kotlinDSLClassPathFinder.gradle") val tasks = listOf("kotlinLSPKotlinDSLDeps") return readDependenciesViaGradleCLI(projectDirectory, scripts, tasks) .apply { if (isNotEmpty()) LOG.info("Successfully resolved build script dependencies for '${projectDirectory.fileName}' using Gradle") } + .map { + it.compiledJar + }.toSet() } else { emptySet() } @@ -70,7 +73,7 @@ private fun getGradleCommand(workspace: Path): Path { } } -private fun readDependenciesViaGradleCLI(projectDirectory: Path, gradleScripts: List, gradleTasks: List): Set { +private fun readDependenciesViaGradleCLI(projectDirectory: Path, gradleScripts: List, gradleTasks: List): Set { LOG.info("Resolving dependencies for '{}' through Gradle's CLI using tasks {}...", projectDirectory.fileName, gradleTasks) val tmpScripts = gradleScripts.map { gradleScriptToTempFile(it, deleteOnExit = false).toPath().toAbsolutePath() } @@ -78,16 +81,12 @@ private fun readDependenciesViaGradleCLI(projectDirectory: Path, gradleScripts: val command = listOf(gradle.toString()) + tmpScripts.flatMap { listOf("-I", it.toString()) } + gradleTasks + listOf("--console=plain") val dependencies = findGradleCLIDependencies(command, projectDirectory) - ?.also { LOG.debug("Classpath for task {}", it) } - .orEmpty() - .filter { it.toString().lowercase().endsWith(".jar") || Files.isDirectory(it) } // Some Gradle plugins seem to cause this to output POMs, therefore filter JARs - .toSet() tmpScripts.forEach(Files::delete) return dependencies } -private fun findGradleCLIDependencies(command: List, projectDirectory: Path): Set? { +private fun findGradleCLIDependencies(command: List, projectDirectory: Path): Set { val (result, errors) = execAndReadStdoutAndStderr(command, projectDirectory) if ("FAILURE: Build failed" in errors) { LOG.warn("Gradle task failed: {}", errors) @@ -101,13 +100,22 @@ private fun findGradleCLIDependencies(command: List, projectDirectory: P return parseGradleCLIDependencies(result) } -private val artifactPattern by lazy { "kotlin-lsp-gradle (.+)(?:\r?\n)".toRegex() } +private val artifactPattern by lazy { "kotlin-lsp-gradle path:(.+) source:(.+)".toRegex() } private val gradleErrorWherePattern by lazy { "\\*\\s+Where:[\r\n]+(\\S\\.*)".toRegex() } -private fun parseGradleCLIDependencies(output: String): Set? { +private fun parseGradleCLIDependencies(output: String): Set { LOG.debug(output) val artifacts = artifactPattern.findAll(output) - .mapNotNull { Paths.get(it.groups[1]?.value) } - .filterNotNull() + .map { + val path = it.groups[1]?.value + val source = it.groups[2]?.value + val jarPath = if (path == "null" || path == null) null else Path.of(path) + val sourceJarPath = if (source == "null" || source == null) null else Path.of(source) + if (jarPath != null && (path!!.lowercase().endsWith(".jar") || Files.isDirectory(jarPath))) { + LOG.debug { "Adding path:$jarPath source: $sourceJarPath to classpath" } + return@map ClassPathEntry(jarPath, sourceJarPath) + } else return@map null + }.filterNotNull() + return artifacts.toSet() } diff --git a/shared/src/main/resources/projectClassPathFinder.gradle b/shared/src/main/resources/projectClassPathFinder.gradle index 7fce53927..eea5722a7 100644 --- a/shared/src/main/resources/projectClassPathFinder.gradle +++ b/shared/src/main/resources/projectClassPathFinder.gradle @@ -1,6 +1,13 @@ +import org.gradle.plugins.ide.eclipse.model.ClasspathEntry +import org.gradle.plugins.ide.eclipse.model.EclipseModel +import org.gradle.plugins.ide.eclipse.model.Library + allprojects { project -> + apply plugin: "eclipse" + task kotlinLSPProjectDeps { task -> doLast { + def classpaths = new HashMap() System.out.println "" System.out.println "gradle-version $gradleVersion" System.out.println "kotlin-lsp-project ${project.name}" @@ -28,7 +35,7 @@ allprojects { project -> File.separator + variantBase + File.separator + "classes" - System.out.println "kotlin-lsp-gradle $buildClasses" + classpaths[buildClasses.toString()] = null def userClasses = project.getBuildDir().absolutePath + File.separator + "intermediates" + @@ -36,7 +43,7 @@ allprojects { project -> File.separator + variantBase + File.separator + "compile" + variantBase.capitalize() + "JavaWithJavac" + File.separator + "classes" - System.out.println "kotlin-lsp-gradle $userClasses" + classpaths[userClasses.toString()] = null def userVariantClasses = project.getBuildDir().absolutePath + File.separator + "intermediates" + @@ -44,17 +51,19 @@ allprojects { project -> File.separator + variantBase + File.separator + "classes" - System.out.println "kotlin-lsp-gradle $userVariantClasses" + classpaths[userVariantClasses.toString()] = null variant.getCompileClasspath().each { - System.out.println "kotlin-lsp-gradle $it" + classpaths[it.toString()] = null } } + + } else if (project.hasProperty('sourceSets')) { // Print the list of all dependencies jar files. sourceSets.forEach { it.compileClasspath.forEach { - System.out.println "kotlin-lsp-gradle $it" + classpaths[it.toString()] = null } } } @@ -69,10 +78,24 @@ allprojects { project -> kotlinExtension.targets.names.each { def classpath = configurations["${it}CompileClasspath"] classpath.files.each { - System.out.println "kotlin-lsp-gradle $it" + classpaths[it.toString()] = null } } } + + EclipseModel eclipseModel = project.extensions.getByType(EclipseModel.class) + + for (ClasspathEntry dep : (eclipseModel.getClasspath().resolveDependencies())) { + if (dep instanceof Library) { + if (classpaths.get(dep.getPath()) == null){ + classpaths[dep.getPath()] = dep.getSourcePath()?.getPath() + } + } + } + + for (e in classpaths) { + System.out.println "kotlin-lsp-gradle path:$e.key source:$e.value" + } } } @@ -80,7 +103,7 @@ allprojects { project -> doLast { fileTree("$gradle.gradleHomeDir/lib") .findAll { it.toString().endsWith '.jar' } - .forEach { System.out.println "kotlin-lsp-gradle $it" } + .forEach { System.out.println "kotlin-lsp-gradle path:$it source:null" } } } }