@@ -9,13 +9,7 @@ import java.io.File
9
9
import java.nio.file.FileSystems
10
10
import java.nio.file.Files
11
11
import java.nio.file.Path
12
- import java.nio.file.Paths
13
- import java.util.regex.Pattern
14
- import org.gradle.tooling.*
15
- import org.gradle.tooling.model.*
16
- import org.gradle.tooling.model.eclipse.*
17
- import org.gradle.tooling.model.idea.*
18
- import org.gradle.kotlin.dsl.tooling.models.*
12
+ import org.gradle.tooling.GradleConnector
19
13
20
14
fun readBuildGradle (buildFile : Path ): Set <Path > {
21
15
val projectDirectory = buildFile.getParent()
@@ -26,10 +20,6 @@ fun readBuildGradle(buildFile: Path): Set<Path> {
26
20
// The first successful dependency resolver is used
27
21
// (evaluating them from top to bottom)
28
22
var dependencies = firstNonNull<Set <Path >>(
29
- { tryResolving(" dependencies using Gradle task" ) { readDependenciesViaTask(projectDirectory) } },
30
- { tryResolving(" dependencies using Eclipse project model" ) { readDependenciesViaEclipseProject(connection) } },
31
- { tryResolving(" dependencies using Kotlin DSL model" ) { readDependenciesViaKotlinDSL(connection) } },
32
- { tryResolving(" dependencies using IDEA model" ) { readDependenciesViaIdeaProject(connection) } },
33
23
{ tryResolving(" dependencies using Gradle dependencies CLI" ) { readDependenciesViaGradleCLI(projectDirectory) } }
34
24
).orEmpty()
35
25
@@ -42,20 +32,17 @@ fun readBuildGradle(buildFile: Path): Set<Path> {
42
32
}
43
33
44
34
private fun createTemporaryGradleFile (): File {
45
- val temp = File .createTempFile(" tempGradle" , " .config" )
46
35
val config = File .createTempFile(" classpath" , " .gradle" )
47
36
37
+ LOG .info(" Creating temporary gradle file ${config.absolutePath} " )
38
+
48
39
config.bufferedWriter().use { configWriter ->
49
40
ClassLoader .getSystemResourceAsStream(" classpathFinder.gradle" ).bufferedReader().use { configReader ->
50
41
configReader.copyTo(configWriter)
51
42
}
52
43
}
53
44
54
- temp.bufferedWriter().use {
55
- it.write(" rootProject { apply from: '${config.absolutePath.replace(" \\ " , " \\\\ " )} '} " )
56
- }
57
-
58
- return temp
45
+ return config
59
46
}
60
47
61
48
private fun getGradleCommand (workspace : Path ): Path {
@@ -67,101 +54,27 @@ private fun getGradleCommand(workspace: Path): Path {
67
54
}
68
55
}
69
56
70
- val jarArtifactOutputLine by lazy { Pattern .compile(" ^.+?\\ .jar$" ) }
71
-
72
- private fun readDependenciesViaTask (directory : Path ): Set <Path >? {
73
- val gradle = getGradleCommand(directory)
74
- val config = createTemporaryGradleFile()
75
-
76
- val gradleCommand = " $gradle -I ${config.absolutePath} classpath"
77
- val classpathCommand = Runtime .getRuntime().exec(gradleCommand, null , directory.toFile())
78
- val stdout = classpathCommand.inputStream
79
- val dependencies = mutableSetOf<Path >()
80
-
81
- stdout.bufferedReader().use { reader ->
82
- reader.lines().forEach {
83
- val line = it.toString().trim()
84
- if (! line.startsWith(" Download" ) && jarArtifactOutputLine.matcher(line).matches()) {
85
- dependencies.add(Paths .get(line))
86
- }
87
- }
88
- }
89
-
90
- classpathCommand.waitFor()
91
-
92
- if (dependencies.size > 0 ) {
93
- return dependencies
94
- } else {
95
- return null
96
- }
97
- }
98
-
99
- private fun readDependenciesViaEclipseProject (connection : ProjectConnection ): Set <Path > {
100
- val dependencies = mutableSetOf<Path >()
101
- val project: EclipseProject = connection.getModel(EclipseProject ::class .java)
102
-
103
- for (dependency in project.classpath) {
104
- dependencies.add(dependency.file.toPath())
105
- }
106
-
107
- return dependencies
108
- }
109
-
110
- private fun readDependenciesViaIdeaProject (connection : ProjectConnection ): Set <Path > {
111
- val dependencies = mutableSetOf<Path >()
112
- val project: IdeaProject = connection.getModel(IdeaProject ::class .java)
113
-
114
- for (child in project.children) {
115
- for (dependency in child.dependencies) {
116
- if (dependency is ExternalDependency ) {
117
- dependencies.add(dependency.file.toPath())
118
- }
119
- }
120
- }
121
-
122
- return dependencies
123
- }
124
-
125
- private fun readDependenciesViaKotlinDSL (connection : ProjectConnection ): Set <Path > {
126
- val project: KotlinBuildScriptModel = connection.getModel(KotlinBuildScriptModel ::class .java)
127
- return project.classPath.map { it.toPath() }.toSet()
128
- }
129
-
130
57
private fun readDependenciesViaGradleCLI (projectDirectory : Path ): Set <Path >? {
131
58
LOG .fine(" Attempting dependency resolution through CLI..." )
59
+ val config = createTemporaryGradleFile()
132
60
val gradle = getGradleCommand(projectDirectory)
133
- val classpathCommand = " $gradle dependencies --configuration=compileClasspath --console=plain"
134
- val testClasspathCommand = " $gradle dependencies --configuration=testCompileClasspath --console=plain"
135
- val dependencies = findGradleCLIDependencies(classpathCommand, projectDirectory)
136
- val testDependencies = findGradleCLIDependencies(testClasspathCommand, projectDirectory)
137
-
138
- return dependencies?.union(testDependencies.orEmpty()).orEmpty()
61
+ val cmd = " $gradle -I ${config.absolutePath} kotlinLSPDeps --console=plain"
62
+ LOG .fine(" -- executing $cmd " )
63
+ val dependencies = findGradleCLIDependencies(cmd, projectDirectory)
64
+ return dependencies
139
65
}
140
66
141
67
private fun findGradleCLIDependencies (command : String , projectDirectory : Path ): Set <Path >? {
142
- return parseGradleCLIDependencies(execAndReadStdout(command, projectDirectory))
68
+ val result = execAndReadStdout(command, projectDirectory)
69
+ LOG .fine(result)
70
+ return parseGradleCLIDependencies(result)
143
71
}
144
72
145
- private val artifactPattern by lazy { " [\\ S]+:[\\ S]+:[\\ S]+( -> )*([\\ d.]+)*" .toRegex() }
146
- private val jarMatcher by lazy { FileSystems .getDefault().getPathMatcher(" glob:**.jar" ) }
73
+ private val artifactPattern by lazy { " kotlin-lsp-gradle (.+)\n " .toRegex() }
147
74
148
75
private fun parseGradleCLIDependencies (output : String ): Set <Path >? {
149
76
val artifacts = artifactPattern.findAll(output)
150
- .map { findGradleArtifact(parseArtifact (it.value, it. groups[2 ]?.value) ) }
77
+ .mapNotNull { FileSystems .getDefault().getPath (it.groups[1 ]?.value) }
151
78
.filterNotNull()
152
79
return artifacts.toSet()
153
80
}
154
-
155
- private fun findGradleArtifact (artifact : Artifact ): Path ? {
156
- val jarPath = gradleCaches
157
- ?.resolve(artifact.group)
158
- ?.resolve(artifact.artifact)
159
- ?.resolve(artifact.version)
160
- ?.let { dependencyFolder ->
161
- Files .walk(dependencyFolder)
162
- .filter { jarMatcher.matches(it) }
163
- .findFirst()
164
- }
165
- ?.orElse(null )
166
- return jarPath
167
- }
0 commit comments