Skip to content

Commit e1d9c73

Browse files
committed
Squashed commit of the following:
commit e19012e63381125042018e60b8fb2e7095db8dfd Author: Stefano Furi <[email protected]> Date: Wed Oct 29 13:21:24 2025 +0100 feat: generate workspace root with correct deps A new Gradle task named "generateLspWorkspaceRoot" builds the `lsp-workspace-root` with the kotlin version associated with this application, and is including the `kotlinDependency` declared in `:dependencies` subproject. commit f104477 Author: Stefano Furi <[email protected]> Date: Wed Oct 29 11:07:13 2025 +0100 chore: add additional config to spring docker compose configuration commit 5a8ee28 Author: Stefano Furi <[email protected]> Date: Wed Oct 29 10:35:56 2025 +0100 refactor: rename jackson extensions commit abd08d9 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 16:39:45 2025 +0100 chore: use single compose file for lsp commit 529d1b8 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 15:52:09 2025 +0100 fix: do not start spring docker compose with prod config commit 825c065 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 15:41:36 2025 +0100 fix: use single project root workspace as remote for lsp now we can set the lsp remote workspace path (vital for containerized environments) through spring's application config. Moreover, a single workspace is now being used (i.e. no distinction between test and prod workspace). commit ab77dd8 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 12:20:35 2025 +0100 chore: set up springdoc for completions subproject commit 7583164 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 12:20:06 2025 +0100 refactor: distinguish between springdoc versions (webmvc or webflux) commit 88e51fb Author: Stefano Furi <[email protected]> Date: Tue Oct 28 11:15:42 2025 +0100 fix: fix typo in application-local config commit bfc4a9e Author: Stefano Furi <[email protected]> Date: Tue Oct 28 10:53:54 2025 +0100 chore: increase lsp-connection timeout in containerized environments commit aaa9ee3 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 10:43:51 2025 +0100 chore: use websites-team registry intellij-lsp docker image commit 6ff3f95 Author: Stefano Furi <[email protected]> Date: Tue Oct 28 10:42:43 2025 +0100 fix: make tests use lsp configuration taken from compose Containerized intellij-lsp uses a dynamic port, we need to provide a way to make spring aware of this `through `LspIntegrationTest`. commit 3c22338 Author: Stefano Furi <[email protected]> Date: Mon Oct 27 17:59:07 2025 +0100 chore: try use websites-team `intellij-lsp` docker image commit be1136a Author: Stefano Furi <[email protected]> Date: Mon Oct 27 17:21:36 2025 +0100 chore: use `local` spring profile for running with local compose commit 3bb3a82 Author: Stefano Furi <[email protected]> Date: Mon Oct 27 17:17:07 2025 +0100 chore: pass LspConfig to clients # Conflicts: # completions/lsp-compose.yml # completions/src/main/kotlin/completions/configuration/lsp/LspProperties.kt # completions/src/main/resources/application-local.yml # completions/src/main/resources/application.yml # completions/src/main/resources/lsp-users-projects-root/gradle.properties # completions/src/main/resources/lsp-users-projects-root/settings.gradle.kts # completions/src/main/resources/lsp/workspaces/lsp-users-projects-root/build.gradle.kts # completions/src/main/resources/lsp/workspaces/lsp-users-projects-root/gradle.properties # completions/src/main/resources/lsp/workspaces/lsp-users-projects-root/settings.gradle.kts # completions/src/main/resources/lsp/workspaces/root-template/gradle.properties # completions/src/main/resources/lsp/workspaces/root-template/settings.gradle.kts # completions/src/test/resources/lsp/compose.yaml
1 parent 0d80a51 commit e1d9c73

File tree

18 files changed

+124
-41
lines changed

18 files changed

+124
-41
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ out/
3838
### VS Code ###
3939
.vscode/
4040

41-
kotlin-lsp/
41+
### LSP (:completions) generated workspace root
42+
completions/**/lsp-workspace-root-*

completions/build.gradle.kts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ plugins {
44
id("base-spring-boot-conventions")
55
}
66

7-
version = "${libs.versions.kotlin.get()}-SNAPSHOT"
7+
val kotlinVersion = libs.versions.kotlin.get()
8+
version = "$kotlinVersion-SNAPSHOT"
9+
10+
val depsProject = project(":dependencies")
811

912
dependencies {
1013
implementation(libs.spring.boot.starter.webflux)
@@ -15,6 +18,7 @@ dependencies {
1518
testImplementation(libs.kotlin.test)
1619
testImplementation(libs.bundles.testcontainers)
1720
testImplementation(libs.rector.test)
21+
implementation(depsProject)
1822
}
1923

2024
tasks.named<BootBuildImage>("bootBuildImage") {
@@ -24,3 +28,46 @@ tasks.named<BootBuildImage>("bootBuildImage") {
2428
imageName = "$baseImageName:${project.version}"
2529
tags = setOf("$baseImageName:latest")
2630
}
31+
32+
tasks.register("generateLspWorkspaceRoot") {
33+
dependsOn(":dependencies:jar")
34+
35+
val (rootDir, targetDir) = layout.projectDirectory.dir("src/main/resources/lsp/workspaces").let {
36+
it.dir("root-template").asFile to it.dir("lsp-workspace-root-${kotlinVersion}").asFile
37+
}
38+
targetDir.mkdirs()
39+
rootDir.copyRecursively(targetDir, overwrite = true)
40+
41+
val buildFile = targetDir.resolve("build.gradle.kts")
42+
43+
val compilerPlugins = depsProject.configurations["kotlinCompilerPluginDependency"]
44+
?.resolvedConfiguration
45+
?.resolvedArtifacts
46+
?.map { "id(\"${it.moduleVersion}\")" }
47+
?: emptySet()
48+
49+
val deps = depsProject.configurations["kotlinDependency"]
50+
?.resolvedConfiguration
51+
?.resolvedArtifacts
52+
?.map { "implementation(\"${it.moduleVersion}\")" }
53+
?: emptySet()
54+
55+
val kotlinVersionPlaceholder = "{{kotlin_version}}"
56+
val pluginsPlaceholder = "{{plugins}}"
57+
val dependenciesPlaceholder = "{{dependencies}}"
58+
59+
val newContent: String = listOf(kotlinVersionPlaceholder, pluginsPlaceholder, dependenciesPlaceholder)
60+
.zip(listOf(setOf(kotlinVersion), compilerPlugins, deps))
61+
.fold(buildFile.readText()) { acc, (placeholder, values) ->
62+
acc.replace(placeholder, values.joinToString("\n "))
63+
}
64+
buildFile.writeText(newContent)
65+
}
66+
67+
tasks.processResources {
68+
val kotlinVersionProvider = providers.provider { kotlinVersion }
69+
70+
filesMatching("**/application*.yml") {
71+
filter { line -> line.replace("@@KOTLIN_VERSION@@", kotlinVersionProvider.get()) }
72+
}
73+
}

completions/lsp-compose.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +0,0 @@
1-
services:
2-
kotlin-lsp:
3-
image: registry.jetbrains.team/p/kotlin-website-team/kotlin-playground/intellij-lsp:latest
4-
ports:
5-
- "9999:9999"

completions/src/main/kotlin/completions/configuration/lsp/LspProperties.kt

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,45 @@ package completions.configuration.lsp
33
import org.springframework.boot.context.properties.ConfigurationProperties
44

55
/**
6-
* Simple LSP configuration properties which expose a way to be accessed
7-
* even from non-spring managed components, i.e. [completions.lsp.client.LspConnectionManager].
6+
* Configuration properties for the Kotlin-LSP server client. These properties
7+
* are bound to the `lsp` prefix in the configuration file.
8+
*
9+
* > Note: the default behaviour of this component expects the Kotlin-LSP instancy running locally
10+
* on the same machine as this application is running. In this case, there's no difference between
11+
* [local][localWorkspaceRoot] and [remote][remoteWorkspaceRoot] workspaces. In this case, the paths
12+
* are computed as absolute paths.
13+
* However, if [local][localWorkspaceRoot] or [remote][remoteWorkspaceRoot] are overridden in the application
14+
* configuration file, they will not be resolved and are **used as is**.
15+
*
16+
* @property host The hostname of the LSP server.
17+
* @property port The port number to connect to the LSP server.
18+
* @property reconnectionRetries The maximum number of reconnection attempts in case of connection failure.
19+
* @property kotlinVersion The Kotlin version used by the LSP client. Defaults to the current runtime Kotlin version.
20+
* @property remoteWorkspaceRoot The root directory for the LSP workspace wrt to the LSP server, derived from the provided Kotlin version.
21+
* @property localWorkspaceRoot The root directory for the LSP workspace wrt to the host machine, derived from the provided Kotlin version.
822
*/
923
@ConfigurationProperties(prefix = "lsp")
1024
data class LspProperties(
1125
val host: String,
1226
val port: Int,
1327
val reconnectionRetries: Int,
14-
val remoteWorkspaceRoot: String = "/lsp/workspaces/lsp-users-projects-root",
15-
val localWorkspaceRoot: String = "/lsp/workspaces/lsp-users-projects-root"
16-
)
28+
val kotlinVersion: String = KotlinVersion.CURRENT.toString(),
29+
val remoteWorkspaceRoot: String = resolveWorkspacePaths(kotlinVersion),
30+
val localWorkspaceRoot: String = resolveWorkspacePaths(kotlinVersion),
31+
) {
32+
companion object {
33+
private const val DEFAULT_WORKSPACE_ROOT_PATH: String = "/lsp/workspaces/lsp-workspace-root-"
34+
35+
private fun resolveWorkspacePaths(kotlinVersion: String): String {
36+
val path = DEFAULT_WORKSPACE_ROOT_PATH + kotlinVersion
37+
return this::class.java.getResource(path)?.toURI()?.path
38+
?: error(
39+
"""
40+
Could not find '$path' in project resources. Please make sure you either do one of the following:
41+
- Generate workspace for kotlin=$kotlinVersion with `./gradlew :completions:generateLspWorkspaceRoot`
42+
- Override in the `application.yml` `remoteWorkspaceRoot` and `localWorkspaceRoot`.
43+
""".trimIndent()
44+
)
45+
}
46+
}
47+
}

completions/src/main/kotlin/completions/lsp/LspCompletionParser.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
44
import org.eclipse.lsp4j.CompletionItem
55
import completions.dto.api.CompletionResponse
66
import completions.enums.Icon
7-
import completions.util.SerializationUtil.walk
7+
import completions.util.SerializationExtensions.walk
88
import org.eclipse.lsp4j.CompletionItemLabelDetails
99
import org.springframework.stereotype.Component
1010

completions/src/main/kotlin/completions/lsp/util/completions/FuzzyCompletionRanker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
package completions.lsp.util.completions
33

44
import com.fasterxml.jackson.databind.ObjectMapper
5-
import completions.util.SerializationUtil.walk
5+
import completions.util.SerializationExtensions.walk
66
import org.eclipse.lsp4j.CompletionItem
77
import org.springframework.stereotype.Component
88

completions/src/main/kotlin/completions/util/serializationUtil.kt renamed to completions/src/main/kotlin/completions/util/SerializationExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ package completions.util
22

33
import com.fasterxml.jackson.databind.JsonNode
44

5-
object SerializationUtil {
5+
object SerializationExtensions {
66
fun JsonNode.walk(fieldName: String): JsonNode? = path(fieldName).takeIf { !it.isMissingNode }
77
}

completions/src/main/resources/application-local.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ lsp:
44
host: ${LSP_HOST:localhost}
55
port: ${LSP_PORT:9999}
66
reconnection-retries: 10
7-
remote-workspace-root: /workspaces/lsp-users-projects-root
7+
kotlin-version: @@KOTLIN_VERSION@@
8+
remote-workspace-root: /workspaces/lsp-workspace-root-@@KOTLIN_VERSION@@
9+
810
spring:
911
docker:
1012
compose:
11-
file: completions/lsp-compose.yml
13+
enabled: true
14+
file: completions/src/main/resources/lsp-compose.yml
15+
lifecycle-management: start_and_stop
16+
1217
springdoc:
1318
swagger-ui:
1419
enabled: true

completions/src/main/resources/application.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
server:
22
port: ${COMPLETION_SERVICE_PORT:8082}
33
lsp:
4-
host: {$LSP_HOST:localhost}
4+
host: ${LSP_HOST:localhost}
55
port: ${LSP_PORT:9999}
66
reconnection-retries: 10
7-
remote-workspace-root: /workspaces/lsp-users-projects-root
7+
kotlin-version: @@KOTLIN_VERSION@@
8+
9+
spring:
10+
docker:
11+
compose:
12+
enabled: false
813

914
springdoc:
1015
swagger-ui:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
kotlin-lsp:
3+
image: registry.jetbrains.team/p/kotlin-website-team/kotlin-playground/intellij-lsp:latest
4+
ports:
5+
- "9999:9999"

0 commit comments

Comments
 (0)