Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package org.javacs.kt.classpath
- import org.javacs.kt.LOG
- import org.javacs.kt.util.KotlinLSException
- import org.javacs.kt.util.execAndReadStdoutAndStderr
- import org.javacs.kt.util.findCommandOnPath
- import org.javacs.kt.util.isOSWindows
- import java.nio.file.Files
- import java.nio.file.Path
- import java.nio.file.Paths
- import org.gradle.tooling.GradleConnector
- import org.gradle.tooling.ProjectConnection
- import org.gradle.tooling.model.build.GradleEnvironment
- import java.io.*
- internal class GradleClassPathResolver(
- private val path: Path,
- private val includeKotlinDSL: Boolean
- ) : ClassPathResolver {
- override val resolverType: String = "Gradle"
- private val projectDirectory: Path get() = path.getParent()
- override val classpath: Set<ClassPathEntry>
- get() {
- return emptySet()
- // val scripts = listOf("projectClassPathFinder.gradle")
- // val tasks = listOf("kotlinLSPProjectDeps")
- //
- // // TODO: remove this shit
- // 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<Path>
- get() {
- LOG.info { "BUILDED SCRIPTS" }
- 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") }
- } else {
- emptySet()
- }
- }
- companion object {
- /** Create a Gradle resolver if a file is a pom. */
- fun maybeCreate(file: Path): GradleClassPathResolver? =
- file.takeIf { file.endsWith("build.gradle") || file.endsWith("build.gradle.kts") }
- ?.let {
- GradleClassPathResolver(
- it,
- includeKotlinDSL = file.toString().endsWith(".kts")
- )
- }
- }
- }
- private fun gradleScriptToTempFile(scriptName: String, deleteOnExit: Boolean = false): File {
- val config = File.createTempFile("classpath", ".gradle")
- if (deleteOnExit) {
- config.deleteOnExit()
- }
- LOG.debug("Creating temporary gradle file {}", config.absolutePath)
- config.bufferedWriter().use { configWriter ->
- GradleClassPathResolver::class.java.getResourceAsStream("/$scriptName").bufferedReader()
- .use { configReader ->
- configReader.copyTo(configWriter)
- }
- }
- return config
- }
- private fun getGradleCommand(workspace: Path): Path {
- val wrapperName = if (isOSWindows()) "gradlew.bat" else "gradlew"
- val wrapper = workspace.resolve(wrapperName).toAbsolutePath()
- if (Files.isExecutable(wrapper)) {
- return wrapper
- } else {
- return workspace.parent?.let(::getGradleCommand)
- // TODO: replace it via invoking tooling api
- ?: findCommandOnPath("gradle")
- ?: throw KotlinLSException("Could not find 'gradle' on PATH")
- }
- }
- private fun readDependenciesViaGradleCLI(
- projectDirectory: Path,
- gradleScripts: List<String>,
- gradleTasks: List<String>
- ): 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()
- }
- // TODO: check later
- // try{
- // GradleConnector.newConnector()
- // .forProjectDirectory(projectDirectory.toFile()).connect().use{
- // val gradleUserHome: File = it.getModel(
- // GradleEnvironment::class.java
- // ).gradleUserHome
- //
- // LOG.info { "[Gradle home is]:$gradleUserHome" }
- // }
- // }
- // catch(e : Exception){
- // LOG.info { "[GRADLE ERROR]:$e" }
- // }
- // val gradle = getGradleCommand(projectDirectory)
- //
- val command = listOf("gradle") + 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)
- val stdout = ByteArrayOutputStream()
- val stderr = ByteArrayOutputStream()
- LOG.info { "project directory = $projectDirectory" }
- LOG.info { "command = $command" }
- GradleConnector.newConnector().useGradleVersion("8.2.1")
- .forProjectDirectory(projectDirectory.toFile()).connect().use {
- it.newBuild()
- .addArguments(tmpScripts.flatMap { listOf("-I", it.toString()) })
- .forTasks(gradleTasks.get(0))
- .addArguments("--console=plain")
- .setStandardOutput(stdout)
- .setStandardError(stderr)
- .run()
- }
- if ("FAILURE: Build failed" in stderr.toString()) {
- LOG.warn("Gradle task failed: {}", stderr.toString())
- } else {
- for (error in stderr.toString().lines()) {
- if ("ERROR: " in error) {
- LOG.warn("Gradle error: {}", error)
- }
- }
- }
- val dependencies = parseGradleCLIDependencies(stdout.toString())
- ?.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
- }
- public fun main() {
- val projectDirectory = File("/Users/kolavladimirov/runtime-New_configuration(1)/t/bin")
- val stdout = ByteArrayOutputStream()
- val stderr = ByteArrayOutputStream()
- LOG.info { "project directory = $projectDirectory" }
- GradleConnector.newConnector().useGradleVersion("8.2.1")
- .forProjectDirectory(projectDirectory).connect().use {
- it.newBuild()
- .addArguments("-I kotlinDSLClassPathFinder.gradle")
- .forTasks("kotlinLSPProjectDeps")
- .addArguments("--console=plain")
- .setStandardOutput(stdout)
- .setStandardError(stderr)
- .run()
- }
- if ("FAILURE: Build failed" in stderr.toString()) {
- LOG.warn("Gradle task failed: {}", stderr.toString())
- } else {
- for (error in stderr.toString().lines()) {
- if ("ERROR: " in error) {
- LOG.warn("Gradle error: {}", error)
- }
- }
- }
- }
- private fun findGradleCLIDependencies(command: List<String>, projectDirectory: Path): Set<Path>? {
- val (result, errors) = execAndReadStdoutAndStderr(command, projectDirectory)
- if ("FAILURE: Build failed" in errors) {
- LOG.warn("Gradle task failed: {}", errors)
- } else {
- for (error in errors.lines()) {
- if ("ERROR: " in error) {
- LOG.warn("Gradle error: {}", error)
- }
- }
- }
- return parseGradleCLIDependencies(result)
- }
- private val artifactPattern by lazy { "kotlin-lsp-gradle (.+)(?:\r?\n)".toRegex() }
- private val gradleErrorWherePattern by lazy { "\\*\\s+Where:[\r\n]+(\\S\\.*)".toRegex() }
- private fun parseGradleCLIDependencies(output: String): Set<Path>? {
- LOG.debug(output)
- val artifacts = artifactPattern.findAll(output)
- .mapNotNull { Paths.get(it.groups[1]?.value) }
- .filterNotNull()
- return artifacts.toSet()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement