Skip to content

Commit 5a4dc9e

Browse files
committed
Merge remote-tracking branch 'origin/feature/q-lsp' into lodogga/overrideLSPArtifacts
2 parents aaca577 + e20697a commit 5a4dc9e

File tree

22 files changed

+1445
-52
lines changed

22 files changed

+1445
-52
lines changed

buildspec/linuxUiTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ phases:
4747
- chmod +x gradlew
4848

4949
- ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:[email protected]:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 &
50-
- ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:test coverageReport --console plain --info
50+
- ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info
5151

5252
post_build:
5353
commands:

gradle/libs.versions.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref =
106106
kotlin-stdLibJdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
107107
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
108108
mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" }
109+
mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" }
109110
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockitoKotlin" }
110111
mockk = { module = "io.mockk:mockk", version.ref="mockk" }
111112
nimbus-jose-jwt = {module = "com.nimbusds:nimbus-jose-jwt", version.ref = "nimbus-jose-jwt"}
@@ -121,7 +122,7 @@ zjsonpatch = { module = "com.flipkart.zjsonpatch:zjsonpatch", version.ref = "zjs
121122
[bundles]
122123
jackson = ["jackson-datetime", "jackson-kotlin", "jackson-yaml", "jackson-xml"]
123124
kotlin = ["kotlin-stdLibJdk8", "kotlin-reflect"]
124-
mockito = ["mockito-core", "mockito-kotlin"]
125+
mockito = ["mockito-core", "mockito-junit-jupiter", "mockito-kotlin"]
125126
sshd = ["sshd-core", "sshd-scp", "sshd-sftp"]
126127

127128
[plugins]

noop/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33

44
// project that does nothing
55
tasks.register("test")
6+
tasks.register("uiTest")

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import org.eclipse.lsp4j.InitializedParams
3737
import org.eclipse.lsp4j.SynchronizationCapabilities
3838
import org.eclipse.lsp4j.TextDocumentClientCapabilities
3939
import org.eclipse.lsp4j.WorkspaceClientCapabilities
40-
import org.eclipse.lsp4j.WorkspaceFolder
4140
import org.eclipse.lsp4j.jsonrpc.Launcher
4241
import org.eclipse.lsp4j.launch.LSPLauncher
4342
import org.slf4j.event.Level
@@ -48,14 +47,15 @@ import software.aws.toolkits.jetbrains.isDeveloperMode
4847
import software.aws.toolkits.jetbrains.services.amazonq.lsp.auth.DefaultAuthCredentialsService
4948
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
5049
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.createExtendedClientMetadata
50+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.WorkspaceFolderUtil.createWorkspaceFolders
51+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.workspace.WorkspaceServiceHandler
5152
import software.aws.toolkits.jetbrains.services.telemetry.ClientMetadata
5253
import java.io.IOException
5354
import java.io.OutputStreamWriter
5455
import java.io.PipedInputStream
5556
import java.io.PipedOutputStream
5657
import java.io.PrintWriter
5758
import java.io.StringWriter
58-
import java.net.URI
5959
import java.nio.charset.StandardCharsets
6060
import java.util.concurrent.Future
6161
import kotlin.time.Duration.Companion.seconds
@@ -211,21 +211,11 @@ private class AmazonQServerInstance(private val project: Project, private val cs
211211
fileOperations = FileOperationsWorkspaceCapabilities().apply {
212212
didCreate = true
213213
didDelete = true
214+
didRename = true
214215
}
215216
}
216217
}
217218

218-
// needs case handling when project's base path is null: default projects/unit tests
219-
private fun createWorkspaceFolders(): List<WorkspaceFolder> =
220-
project.basePath?.let { basePath ->
221-
listOf(
222-
WorkspaceFolder(
223-
URI("file://$basePath").toString(),
224-
project.name
225-
)
226-
)
227-
}.orEmpty() // no folders to report or workspace not folder based
228-
229219
private fun createClientInfo(): ClientInfo {
230220
val metadata = ClientMetadata.getDefault()
231221
return ClientInfo().apply {
@@ -239,7 +229,7 @@ private class AmazonQServerInstance(private val project: Project, private val cs
239229
processId = ProcessHandle.current().pid().toInt()
240230
capabilities = createClientCapabilities()
241231
clientInfo = createClientInfo()
242-
workspaceFolders = createWorkspaceFolders()
232+
workspaceFolders = createWorkspaceFolders(project)
243233
initializationOptions = createExtendedClientMetadata()
244234
}
245235

@@ -306,6 +296,7 @@ private class AmazonQServerInstance(private val project: Project, private val cs
306296
}
307297

308298
DefaultAuthCredentialsService(project, encryptionManager, this)
299+
WorkspaceServiceHandler(project, this)
309300
}
310301

311302
override fun dispose() {

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class ArtifactHelper(private val lspArtifactsPath: Path = DEFAULT_ARTIFACT_PATH,
112112
logger.info { "Attempt ${currentAttempt.get()} of $maxDownloadAttempts to download LSP artifacts" }
113113

114114
try {
115-
withBackgroundProgress(
115+
return withBackgroundProgress(
116116
project,
117117
AwsCoreBundle.message("amazonqFeatureDev.placeholder.downloading_and_extracting_lsp_artifacts"),
118118
cancellable = true
@@ -123,9 +123,12 @@ class ArtifactHelper(private val lspArtifactsPath: Path = DEFAULT_ARTIFACT_PATH,
123123
.mapNotNull { it.filename }
124124
.forEach { filename -> extractZipFile(downloadPath.resolve(filename), downloadPath) }
125125
logger.info { "Successfully downloaded and moved LSP artifacts to $downloadPath" }
126+
127+
return@withBackgroundProgress downloadPath
126128
}
129+
130+
return@withBackgroundProgress null
127131
}
128-
return downloadPath
129132
} catch (e: Exception) {
130133
when (e) {
131134
is CancellationException -> {

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ManifestFetcher.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import java.nio.file.Path
1919
class ManifestFetcher(
2020
private val lspManifestUrl: String = DEFAULT_MANIFEST_URL,
2121
private val manifestManager: ManifestManager = ManifestManager(),
22-
private val lspManifestFilePath: Path = DEFAULT_MANIFEST_PATH,
22+
private val manifestPath: Path = DEFAULT_MANIFEST_PATH,
2323
) {
2424
companion object {
2525
private val logger = getLogger<ManifestFetcher>()
@@ -34,6 +34,10 @@ class ManifestFetcher(
3434
.resolve("jetbrains-lsp-manifest.json")
3535
}
3636

37+
@get:VisibleForTesting
38+
internal val lspManifestFilePath: Path
39+
get() = manifestPath
40+
3741
/**
3842
* Method which will be used to fetch latest manifest.
3943
* */
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.util
5+
6+
import com.intellij.openapi.vfs.VfsUtilCore
7+
import com.intellij.openapi.vfs.VirtualFile
8+
import software.aws.toolkits.core.utils.getLogger
9+
import software.aws.toolkits.core.utils.warn
10+
import java.io.File
11+
import java.net.URI
12+
import java.net.URISyntaxException
13+
14+
object FileUriUtil {
15+
16+
fun toUriString(virtualFile: VirtualFile): String? {
17+
val protocol = virtualFile.fileSystem.protocol
18+
val uri = when (protocol) {
19+
"jar" -> VfsUtilCore.convertToURL(virtualFile.url)?.toExternalForm()
20+
"jrt" -> virtualFile.url
21+
else -> toUri(VfsUtilCore.virtualToIoFile(virtualFile)).toASCIIString()
22+
} ?: return null
23+
24+
return if (virtualFile.isDirectory) {
25+
uri.trimEnd('/', '\\')
26+
} else {
27+
uri
28+
}
29+
}
30+
31+
private fun toUri(file: File): URI {
32+
try {
33+
// URI scheme specified by language server protocol
34+
return URI("file", "", file.absoluteFile.toURI().path, null)
35+
} catch (e: URISyntaxException) {
36+
LOG.warn { "${e.localizedMessage}: $e" }
37+
return file.absoluteFile.toURI()
38+
}
39+
}
40+
41+
private val LOG = getLogger<FileUriUtil>()
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.util
5+
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.roots.ProjectRootManager
8+
import org.eclipse.lsp4j.WorkspaceFolder
9+
10+
object WorkspaceFolderUtil {
11+
fun createWorkspaceFolders(project: Project): List<WorkspaceFolder> =
12+
if (project.isDefault) {
13+
emptyList()
14+
} else {
15+
ProjectRootManager.getInstance(project).contentRoots.map { contentRoot ->
16+
WorkspaceFolder().apply {
17+
name = contentRoot.name
18+
this.uri = contentRoot.url
19+
}
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)