mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 18:38:11 +03:00
Provide API access to the project name (#1759)
This commit is contained in:
parent
3890abe6fa
commit
a981e72fdf
@ -24,6 +24,10 @@
|
||||
- Added support for evaluating one-shot expressions on the result values of
|
||||
arbitrary expressions ([#1749](https://github.com/enso-org/enso/pull/1749)).
|
||||
This is very useful for enabling more advanced introspection in the IDE.
|
||||
- Added the `workspace/projectInfo` endpoint to the language server
|
||||
([#1759](https://github.com/enso-org/enso/pull/1759)). This allows the IDE to
|
||||
get information about the running project in contexts where the project
|
||||
manager isn't available or works differently.
|
||||
|
||||
## Libraries
|
||||
|
||||
|
12
build.sbt
12
build.sbt
@ -915,13 +915,15 @@ lazy val `language-server` = (project in file("engine/language-server"))
|
||||
new TestFramework("org.scalameter.ScalaMeterFramework")
|
||||
)
|
||||
)
|
||||
.dependsOn(`polyglot-api`)
|
||||
.dependsOn(`json-rpc-server`)
|
||||
.dependsOn(`json-rpc-server-test` % Test)
|
||||
.dependsOn(`text-buffer`)
|
||||
.dependsOn(`searcher`)
|
||||
.dependsOn(testkit % Test)
|
||||
.dependsOn(`json-rpc-server`)
|
||||
.dependsOn(`logging-service`)
|
||||
.dependsOn(`polyglot-api`)
|
||||
.dependsOn(`searcher`)
|
||||
.dependsOn(`text-buffer`)
|
||||
.dependsOn(`version-output`)
|
||||
.dependsOn(pkg)
|
||||
.dependsOn(testkit % Test)
|
||||
|
||||
lazy val ast = (project in file("lib/scala/ast"))
|
||||
.settings(
|
||||
|
@ -98,6 +98,7 @@ transport formats, please look [here](./protocol-architecture).
|
||||
- [`text/applyEdit`](#textapplyedit)
|
||||
- [`text/didChange`](#textdidchange)
|
||||
- [Workspace Operations](#workspace-operations)
|
||||
- [`workspace/projectInfo`](#workspaceprojectinfo)
|
||||
- [`workspace/undo`](#workspaceundo)
|
||||
- [`workspace/redo`](#workspaceredo)
|
||||
- [Monitoring](#monitoring)
|
||||
@ -154,6 +155,7 @@ transport formats, please look [here](./protocol-architecture).
|
||||
- [`NotFile`](#notfile)
|
||||
- [`CannotOverwrite`](#cannotoverwrite)
|
||||
- [`ReadOutOfBounds`](#readoutofbounds)
|
||||
- [`CannotDecode`](#cannotdecode)
|
||||
- [`StackItemNotFoundError`](#stackitemnotfounderror)
|
||||
- [`ContextNotFoundError`](#contextnotfounderror)
|
||||
- [`EmptyStackError`](#emptystackerror)
|
||||
@ -2336,6 +2338,44 @@ null;
|
||||
The language server also has a set of operations useful for managing the client
|
||||
workspace.
|
||||
|
||||
### `workspace/projectInfo`
|
||||
|
||||
This request allows the IDE to request information about the currently open
|
||||
project in situations where it does not have a project manager to connect to.
|
||||
|
||||
- **Type:** Request
|
||||
- **Direction:** Client -> Server
|
||||
- **Connection:** Protocol
|
||||
- **Visibility:** Public
|
||||
|
||||
#### Parameters
|
||||
|
||||
```typescript
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
#### Result
|
||||
|
||||
```typescript
|
||||
{
|
||||
// The name of the project.
|
||||
projectName: String;
|
||||
|
||||
// The engine version on which the project is running.
|
||||
engineVersion: String;
|
||||
|
||||
// The version of graal on which the project is running.
|
||||
graalVersion: String;
|
||||
}
|
||||
```
|
||||
|
||||
#### Errors
|
||||
|
||||
- [`CannotDecode`](#cannotdecode) if the project configuration cannot be
|
||||
decoded.
|
||||
- [`FileNotFound`](#filenotfound) if the project configuration cannot be found.
|
||||
|
||||
### `workspace/undo`
|
||||
|
||||
This request is sent from the client to the server to request that an operation
|
||||
@ -3930,6 +3970,17 @@ Signals that the requested file read was out of bounds for the file's size.
|
||||
}
|
||||
```
|
||||
|
||||
### `CannotDecode`
|
||||
|
||||
Signals that the project configuration cannot be decoded.
|
||||
|
||||
```typescript
|
||||
"error" : {
|
||||
"code" : 1010
|
||||
"message" : "Cannot decode the project configuration"
|
||||
}
|
||||
```
|
||||
|
||||
```idl
|
||||
namespace org.enso.languageserver.protocol.binary;
|
||||
|
||||
|
@ -35,7 +35,7 @@ transport formats, please look [here](./protocol-architecture.md).
|
||||
- [`task/started`](#taskstarted)
|
||||
- [`task/progress-update`](#taskprogress-update)
|
||||
- [`task/finished`](#taskfinished)
|
||||
- [Components Management](#components-management)
|
||||
- [Runtime Version Management](#runtime-version-management)
|
||||
- [`engine/list-installed`](#enginelist-installed)
|
||||
- [`engine/list-available`](#enginelist-available)
|
||||
- [`engine/install`](#engineinstall)
|
||||
@ -47,7 +47,7 @@ transport formats, please look [here](./protocol-architecture.md).
|
||||
- [Logging Service](#logging-service)
|
||||
- [`logging-service/get-endpoint`](#logging-serviceget-endpoint)
|
||||
- [Language Server Management](#language-server-management)
|
||||
- [Errors](#errors-15)
|
||||
- [Errors](#errors)
|
||||
- [`MissingComponentError`](#missingcomponenterror)
|
||||
- [`BrokenComponentError`](#brokencomponenterror)
|
||||
- [`ProjectManagerUpgradeRequired`](#projectmanagerupgraderequired)
|
||||
@ -177,7 +177,7 @@ the action.
|
||||
#### Parameters
|
||||
|
||||
```typescript
|
||||
interface ProjectOpenRequest {
|
||||
{
|
||||
projectId: UUID;
|
||||
|
||||
/**
|
||||
@ -192,7 +192,7 @@ interface ProjectOpenRequest {
|
||||
#### Result
|
||||
|
||||
```typescript
|
||||
interface ProjectOpenResult {
|
||||
{
|
||||
/**
|
||||
* The version of the started language server represented by a semver version
|
||||
* string.
|
||||
@ -208,6 +208,9 @@ interface ProjectOpenResult {
|
||||
* The endpoint used for binary protocol.
|
||||
*/
|
||||
languageServerBinaryAddress: IPWithSocket;
|
||||
|
||||
// The name of the project as it is opened.
|
||||
projectName: String;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -247,7 +247,8 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
|
||||
stdOutController,
|
||||
stdErrController,
|
||||
stdInController,
|
||||
runtimeConnector
|
||||
runtimeConnector,
|
||||
languageServerConfig
|
||||
)
|
||||
log.trace(
|
||||
"Created JSON connection controller factory [{}].",
|
||||
|
@ -173,3 +173,6 @@ case class Config(
|
||||
}.headOption
|
||||
|
||||
}
|
||||
object Config {
|
||||
def ensoPackageConfigName: String = "package.yaml"
|
||||
}
|
||||
|
@ -163,4 +163,7 @@ object FileManagerApi {
|
||||
|
||||
case object NotDirectoryError extends Error(1006, "Path is not a directory")
|
||||
|
||||
case object CannotDecodeError
|
||||
extends Error(1010, "Cannot decode the project configuration")
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.enso.languageserver.protocol.json
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import akka.actor.{Actor, ActorLogging, ActorRef, Props, Stash, Status}
|
||||
import akka.pattern.pipe
|
||||
import akka.util.Timeout
|
||||
@ -14,6 +12,7 @@ import org.enso.languageserver.capability.CapabilityApi.{
|
||||
ReleaseCapability
|
||||
}
|
||||
import org.enso.languageserver.capability.CapabilityProtocol
|
||||
import org.enso.languageserver.data.Config
|
||||
import org.enso.languageserver.event.{
|
||||
JsonSessionInitialized,
|
||||
JsonSessionTerminated
|
||||
@ -41,6 +40,7 @@ import org.enso.languageserver.requesthandler.visualisation.{
|
||||
ExecuteExpressionHandler,
|
||||
ModifyVisualisationHandler
|
||||
}
|
||||
import org.enso.languageserver.requesthandler.workspace.ProjectInfoHandler
|
||||
import org.enso.languageserver.runtime.ContextRegistryProtocol
|
||||
import org.enso.languageserver.runtime.ExecutionApi._
|
||||
import org.enso.languageserver.runtime.VisualisationApi.{
|
||||
@ -61,7 +61,9 @@ import org.enso.languageserver.session.SessionApi.{
|
||||
import org.enso.languageserver.text.TextApi._
|
||||
import org.enso.languageserver.text.TextProtocol
|
||||
import org.enso.languageserver.util.UnhandledLogging
|
||||
import org.enso.languageserver.workspace.WorkspaceApi.ProjectInfo
|
||||
|
||||
import java.util.UUID
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/** An actor handling communications between a single client and the language
|
||||
@ -88,6 +90,7 @@ class JsonConnectionController(
|
||||
val stdErrController: ActorRef,
|
||||
val stdInController: ActorRef,
|
||||
val runtimeConnector: ActorRef,
|
||||
val languageServerConfig: Config,
|
||||
requestTimeout: FiniteDuration = 10.seconds
|
||||
) extends Actor
|
||||
with Stash
|
||||
@ -280,7 +283,7 @@ class JsonConnectionController(
|
||||
|
||||
private def createRequestHandlers(
|
||||
rpcSession: JsonSession
|
||||
): Map[Method, Props] =
|
||||
): Map[Method, Props] = {
|
||||
Map(
|
||||
Ping -> PingHandler.props(
|
||||
List(
|
||||
@ -351,8 +354,10 @@ class JsonConnectionController(
|
||||
.props(stdErrController, rpcSession.clientId),
|
||||
RedirectStandardError -> RedirectStdErrHandler
|
||||
.props(stdErrController, rpcSession.clientId),
|
||||
FeedStandardInput -> FeedStandardInputHandler.props(stdInController)
|
||||
FeedStandardInput -> FeedStandardInputHandler.props(stdInController),
|
||||
ProjectInfo -> ProjectInfoHandler.props(languageServerConfig)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -382,6 +387,7 @@ object JsonConnectionController {
|
||||
stdErrController: ActorRef,
|
||||
stdInController: ActorRef,
|
||||
runtimeConnector: ActorRef,
|
||||
languageServerConfig: Config,
|
||||
requestTimeout: FiniteDuration = 10.seconds
|
||||
): Props =
|
||||
Props(
|
||||
@ -397,6 +403,7 @@ object JsonConnectionController {
|
||||
stdErrController,
|
||||
stdInController,
|
||||
runtimeConnector,
|
||||
languageServerConfig,
|
||||
requestTimeout
|
||||
)
|
||||
)
|
||||
|
@ -1,10 +1,11 @@
|
||||
package org.enso.languageserver.protocol.json
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import akka.actor.{ActorRef, ActorSystem}
|
||||
import org.enso.jsonrpc.ClientControllerFactory
|
||||
import org.enso.languageserver.boot.resource.InitializationComponent
|
||||
import org.enso.languageserver.data.Config
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
/** Language server client controller factory.
|
||||
*
|
||||
@ -23,7 +24,8 @@ class JsonConnectionControllerFactory(
|
||||
stdOutController: ActorRef,
|
||||
stdErrController: ActorRef,
|
||||
stdInController: ActorRef,
|
||||
runtimeConnector: ActorRef
|
||||
runtimeConnector: ActorRef,
|
||||
config: Config
|
||||
)(implicit system: ActorSystem)
|
||||
extends ClientControllerFactory {
|
||||
|
||||
@ -45,7 +47,8 @@ class JsonConnectionControllerFactory(
|
||||
stdOutController,
|
||||
stdErrController,
|
||||
stdInController,
|
||||
runtimeConnector
|
||||
runtimeConnector,
|
||||
config
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import org.enso.languageserver.search.SearchApi._
|
||||
import org.enso.languageserver.runtime.VisualisationApi._
|
||||
import org.enso.languageserver.session.SessionApi.InitProtocolConnection
|
||||
import org.enso.languageserver.text.TextApi._
|
||||
import org.enso.languageserver.workspace.WorkspaceApi.ProjectInfo
|
||||
|
||||
object JsonRpc {
|
||||
|
||||
@ -62,6 +63,7 @@ object JsonRpc {
|
||||
.registerRequest(Completion)
|
||||
.registerRequest(Import)
|
||||
.registerRequest(RenameProject)
|
||||
.registerRequest(ProjectInfo)
|
||||
.registerNotification(ForceReleaseCapability)
|
||||
.registerNotification(GrantCapability)
|
||||
.registerNotification(TextDidChange)
|
||||
@ -74,5 +76,4 @@ object JsonRpc {
|
||||
.registerNotification(WaitingForStandardInput)
|
||||
.registerNotification(SuggestionsDatabaseUpdates)
|
||||
.registerNotification(VisualisationEvaluationFailed)
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
package org.enso.languageserver.requesthandler.workspace
|
||||
|
||||
import akka.actor.{Actor, ActorLogging, Props}
|
||||
import buildinfo.Info
|
||||
import org.enso.jsonrpc.{Request, ResponseError, ResponseResult}
|
||||
import org.enso.languageserver.data.Config
|
||||
import org.enso.languageserver.filemanager.FileManagerApi
|
||||
import org.enso.languageserver.util.UnhandledLogging
|
||||
import org.enso.languageserver.workspace.WorkspaceApi.ProjectInfo
|
||||
import org.enso.logger.masking.MaskedPath
|
||||
import org.enso.pkg.{Config => PkgConfig}
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
/** A request handler for `workspace/openFile` commands.
|
||||
*/
|
||||
class ProjectInfoHandler(languageServerConfig: Config)
|
||||
extends Actor
|
||||
with ActorLogging
|
||||
with UnhandledLogging {
|
||||
|
||||
override def receive: Receive = { case Request(ProjectInfo, id, _) =>
|
||||
val projectRoot = languageServerConfig.directories.root.toPath.toFile
|
||||
val configFile = new File(projectRoot, Config.ensoPackageConfigName)
|
||||
|
||||
if (configFile.exists()) {
|
||||
val projectConfig = PkgConfig.fromYaml(
|
||||
new String(
|
||||
new FileInputStream(configFile).readAllBytes(),
|
||||
StandardCharsets.UTF_8
|
||||
)
|
||||
)
|
||||
if (projectConfig.isSuccess) {
|
||||
val projectInfo = ProjectInfo.Result(
|
||||
projectName = projectConfig.get.name,
|
||||
engineVersion = Info.ensoVersion,
|
||||
graalVersion = Info.graalVersion
|
||||
)
|
||||
sender() ! ResponseResult(
|
||||
ProjectInfo,
|
||||
id,
|
||||
projectInfo
|
||||
)
|
||||
} else {
|
||||
log.error(
|
||||
"Could not decode the package configuration at [{}].",
|
||||
MaskedPath(configFile.toPath)
|
||||
)
|
||||
sender() ! ResponseError(Some(id), FileManagerApi.CannotDecodeError)
|
||||
}
|
||||
} else {
|
||||
log.error(
|
||||
"Could not find the package configuration in the project at [{}].",
|
||||
MaskedPath(projectRoot.toPath)
|
||||
)
|
||||
sender() ! ResponseError(Some(id), FileManagerApi.FileNotFoundError)
|
||||
}
|
||||
}
|
||||
}
|
||||
object ProjectInfoHandler {
|
||||
|
||||
/** Creates a configuration object used to create a [[ProjectInfoHandler]].
|
||||
*
|
||||
* @return a configuration object
|
||||
*/
|
||||
def props(languageServerConfig: Config): Props = Props(
|
||||
new ProjectInfoHandler(languageServerConfig)
|
||||
)
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.enso.languageserver.workspace
|
||||
|
||||
import org.enso.jsonrpc.{HasParams, HasResult, Method}
|
||||
|
||||
/** The workspace management JSON RPC API provided by the language server.
|
||||
*
|
||||
* See [[https://github.com/enso-org/enso/blob/main/docs/language-server/README.md]]
|
||||
* for message specifications.
|
||||
*/
|
||||
object WorkspaceApi {
|
||||
|
||||
case object ProjectInfo extends Method("workspace/projectInfo") {
|
||||
case class Params()
|
||||
case class Result(
|
||||
projectName: String,
|
||||
engineVersion: String,
|
||||
graalVersion: String
|
||||
)
|
||||
implicit val hasParams = new HasParams[this.type] {
|
||||
type Params = ProjectInfo.Params
|
||||
}
|
||||
implicit val hasResult = new HasResult[this.type] {
|
||||
type Result = ProjectInfo.Result
|
||||
}
|
||||
}
|
||||
}
|
6
engine/language-server/src/test/resources/package.yaml
Normal file
6
engine/language-server/src/test/resources/package.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
license: APLv2
|
||||
name: Standard
|
||||
enso-version: default
|
||||
version: "0.1.0"
|
||||
author: "Enso Team <contact@enso.org>"
|
||||
maintainer: "Enso Team <contact@enso.org>"
|
@ -1,8 +1,5 @@
|
||||
package org.enso.languageserver.websocket.json
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.util.UUID
|
||||
|
||||
import akka.testkit.TestProbe
|
||||
import io.circe.literal._
|
||||
import org.apache.commons.io.FileUtils
|
||||
@ -37,6 +34,8 @@ import org.enso.polyglot.runtime.Runtime.Api
|
||||
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
|
||||
import org.enso.text.Sha3_224VersionCalculator
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.util.UUID
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
|
||||
@ -186,7 +185,8 @@ class BaseServerTest extends JsonRpcServerTestKit {
|
||||
stdOutController,
|
||||
stdErrController,
|
||||
stdInController,
|
||||
runtimeConnectorProbe.ref
|
||||
runtimeConnectorProbe.ref,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,97 @@
|
||||
package org.enso.languageserver.websocket.json
|
||||
|
||||
import buildinfo.Info
|
||||
import io.circe.literal.JsonStringContext
|
||||
import org.enso.languageserver.data.Config
|
||||
import org.enso.testkit.FlakySpec
|
||||
|
||||
import java.io.{File, FileOutputStream}
|
||||
|
||||
class WorkspaceOperationsTest extends BaseServerTest with FlakySpec {
|
||||
|
||||
"workspace/projectInfo" must {
|
||||
val packageConfigName = Config.ensoPackageConfigName
|
||||
val testYamlPath = new File(testContentRoot.toFile, packageConfigName)
|
||||
|
||||
"return the project info" taggedAs Flaky in {
|
||||
testYamlPath.delete()
|
||||
val packageYamlContents =
|
||||
getClass.getClassLoader.getResourceAsStream(packageConfigName)
|
||||
val yamlOutStream = new FileOutputStream(testYamlPath)
|
||||
yamlOutStream.write(packageYamlContents.readAllBytes())
|
||||
yamlOutStream.close()
|
||||
|
||||
val client = getInitialisedWsClient()
|
||||
|
||||
client.send(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"method": "workspace/projectInfo",
|
||||
"id": 1,
|
||||
"params": {}
|
||||
}
|
||||
""")
|
||||
|
||||
client.expectJson(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"projectName" : "Standard",
|
||||
"engineVersion" : ${Info.ensoVersion},
|
||||
"graalVersion" : ${Info.graalVersion}
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
"return an error when the project configuration cannot be decoded" in {
|
||||
testYamlPath.delete()
|
||||
val yamlOutStream = new FileOutputStream(testYamlPath)
|
||||
yamlOutStream.write(0x00)
|
||||
yamlOutStream.close()
|
||||
|
||||
val client = getInitialisedWsClient()
|
||||
|
||||
client.send(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"method": "workspace/projectInfo",
|
||||
"id": 1,
|
||||
"params": {}
|
||||
}
|
||||
""")
|
||||
|
||||
client.expectJson(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"error": {
|
||||
"code": 1010,
|
||||
"message": "Cannot decode the project configuration"
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
"return an error when the project configuration is not present" in {
|
||||
testYamlPath.delete()
|
||||
|
||||
val client = getInitialisedWsClient()
|
||||
|
||||
client.send(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"method": "workspace/projectInfo",
|
||||
"id": 1,
|
||||
"params": {}
|
||||
}
|
||||
""")
|
||||
|
||||
client.expectJson(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"error": {
|
||||
"code": 1003,
|
||||
"message": "File not found"
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
}
|
||||
}
|
@ -6,8 +6,10 @@ import nl.gn0s1s.bump.SemVer
|
||||
*
|
||||
* @param engineVersion the version of the started language server
|
||||
* @param sockets the sockets listened by the language server
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
case class RunningLanguageServerInfo(
|
||||
engineVersion: SemVer,
|
||||
sockets: LanguageServerSockets
|
||||
sockets: LanguageServerSockets,
|
||||
projectName: String
|
||||
)
|
||||
|
@ -76,7 +76,8 @@ object ProjectManagementApi {
|
||||
case class Result(
|
||||
engineVersion: SemVer,
|
||||
languageServerJsonAddress: Socket,
|
||||
languageServerBinaryAddress: Socket
|
||||
languageServerBinaryAddress: Socket,
|
||||
projectName: String
|
||||
)
|
||||
|
||||
implicit val hasParams = new HasParams[this.type] {
|
||||
|
@ -54,7 +54,8 @@ class ProjectOpenHandler[F[+_, +_]: Exec: CovariantFlatMap](
|
||||
} yield ProjectOpen.Result(
|
||||
engineVersion = server.engineVersion,
|
||||
languageServerJsonAddress = server.sockets.jsonSocket,
|
||||
languageServerBinaryAddress = server.sockets.binarySocket
|
||||
languageServerBinaryAddress = server.sockets.binarySocket,
|
||||
projectName = server.projectName
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ class ProjectService[
|
||||
s"Language server boot failed. ${th.getMessage}"
|
||||
)
|
||||
}
|
||||
} yield RunningLanguageServerInfo(version, sockets)
|
||||
} yield RunningLanguageServerInfo(version, sockets, project.name)
|
||||
|
||||
/** @inheritdoc */
|
||||
override def closeProject(
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.enso.projectmanager
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import akka.testkit.TestDuration
|
||||
import io.circe.Json
|
||||
import io.circe.syntax._
|
||||
@ -10,6 +9,7 @@ import org.enso.pkg.SemVerJson._
|
||||
import io.circe.parser.parse
|
||||
import nl.gn0s1s.bump.SemVer
|
||||
import org.enso.projectmanager.data.{MissingComponentAction, Socket}
|
||||
import org.enso.projectmanager.protocol.ProjectManagementApi.ProjectOpen
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
@ -70,6 +70,26 @@ trait ProjectManagementOps { this: BaseServerSpec =>
|
||||
socket.fold(fail(s"Failed to decode json: $openReply", _), identity)
|
||||
}
|
||||
|
||||
def openProjectData(implicit client: WsTestClient): ProjectOpen.Result = {
|
||||
val Right(openReply) = parse(client.expectMessage(20.seconds.dilated))
|
||||
val openResult = for {
|
||||
result <- openReply.hcursor.downExpectedField("result")
|
||||
engineVer <- result.downField("engineVersion").as[SemVer]
|
||||
jsonAddr <- result.downExpectedField("languageServerJsonAddress")
|
||||
jsonHost <- jsonAddr.downField("host").as[String]
|
||||
jsonPort <- jsonAddr.downField("port").as[Int]
|
||||
binAddr <- result.downExpectedField("languageServerBinaryAddress")
|
||||
binHost <- binAddr.downField("host").as[String]
|
||||
binPort <- binAddr.downField("port").as[Int]
|
||||
name <- result.downField("projectName").as[String]
|
||||
} yield {
|
||||
val jsonSock = Socket(jsonHost, jsonPort)
|
||||
val binSock = Socket(binHost, binPort)
|
||||
ProjectOpen.Result(engineVer, jsonSock, binSock, name)
|
||||
}
|
||||
openResult.getOrElse(throw new Exception("Should have worked."))
|
||||
}
|
||||
|
||||
def closeProject(
|
||||
projectId: UUID
|
||||
)(implicit client: WsTestClient): Unit = {
|
||||
|
@ -303,6 +303,26 @@ class ProjectManagementApiSpec
|
||||
|
||||
"project/open" must {
|
||||
|
||||
"open a project" taggedAs Flaky in {
|
||||
val projectName = "Test_Project"
|
||||
implicit val client: WsTestClient = new WsTestClient(address)
|
||||
val projectId = createProject(projectName)
|
||||
client.send(json"""
|
||||
{ "jsonrpc": "2.0",
|
||||
"method": "project/open",
|
||||
"id": 0,
|
||||
"params": {
|
||||
"projectId": $projectId
|
||||
}
|
||||
}
|
||||
""")
|
||||
val result = openProjectData
|
||||
result.projectName shouldEqual projectName
|
||||
result.engineVersion shouldEqual SemVer("0.0.1").get
|
||||
closeProject(projectId)
|
||||
deleteProject(projectId)
|
||||
}
|
||||
|
||||
"fail when project doesn't exist" in {
|
||||
val client = new WsTestClient(address)
|
||||
client.send(json"""
|
||||
|
@ -1,3 +1,3 @@
|
||||
F22125736BE5D0452B568F45CE4A76EBEF27F339469B9DD3F5476B43369DBEB3
|
||||
99F30FC4FA243330ADBC746BDB8F5B7CF2DD82FB7C4E023F1ED29B231395B46A
|
||||
DBB6898C0166DF679A4179FFFADD4CD98C48D42AF072CA168FED27B41E1C3E43
|
||||
0
|
||||
|
Loading…
Reference in New Issue
Block a user