-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement and test 'library/preinstall'
- Loading branch information
Showing
14 changed files
with
277 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
...uage-server/src/main/scala/org/enso/languageserver/libraries/LibraryInstallerConfig.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.enso.languageserver.libraries | ||
|
||
import org.enso.distribution.{DistributionManager, LanguageHome} | ||
import org.enso.distribution.locking.ResourceManager | ||
|
||
/** Gathers configuration needed by the library installer used in the `library/preinstall` endpoint. */ | ||
case class LibraryInstallerConfig( | ||
distributionManager: DistributionManager, | ||
resourceManager: ResourceManager, | ||
languageHome: Option[LanguageHome] | ||
) |
164 changes: 129 additions & 35 deletions
164
...r/src/main/scala/org/enso/languageserver/libraries/handler/LibraryPreinstallHandler.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,150 @@ | ||
package org.enso.languageserver.libraries.handler | ||
|
||
import akka.actor.{Actor, Props} | ||
import akka.actor.{Actor, ActorRef, Props} | ||
import akka.pattern.pipe | ||
import com.typesafe.scalalogging.LazyLogging | ||
import org.enso.cli.task.notifications.ActorProgressNotificationForwarder | ||
import org.enso.jsonrpc.{Request, ResponseError} | ||
import org.enso.cli.task.{ProgressNotification, ProgressReporter} | ||
import org.enso.distribution.ProgressAndLockNotificationForwarder | ||
import org.enso.distribution.locking.LockUserInterface | ||
import org.enso.editions.LibraryName | ||
import org.enso.jsonrpc.{Id, Request, ResponseError, ResponseResult, Unused} | ||
import org.enso.languageserver.filemanager.FileManagerApi.FileSystemError | ||
import org.enso.languageserver.libraries.FakeDownload | ||
import org.enso.languageserver.libraries.LibraryApi._ | ||
import org.enso.languageserver.libraries.handler.LibraryPreinstallHandler.{ | ||
InstallationError, | ||
InstallerError, | ||
InternalError, | ||
LibraryInstallationComplete | ||
} | ||
import org.enso.languageserver.libraries.{ | ||
EditionReference, | ||
EditionReferenceResolver, | ||
LibraryInstallerConfig | ||
} | ||
import org.enso.languageserver.util.UnhandledLogging | ||
import org.enso.librarymanager.ResolvingLibraryProvider.Error | ||
import org.enso.librarymanager.{ | ||
DefaultLibraryProvider, | ||
ResolvedLibrary, | ||
ResolvingLibraryProvider | ||
} | ||
|
||
import java.util.concurrent.Executors | ||
import scala.concurrent.{ExecutionContext, Future} | ||
import scala.util.Try | ||
|
||
/** A request handler for the `library/preinstall` endpoint. | ||
* | ||
* It is currently a stub implementation which will be refined later on. | ||
* @param editionReferenceResolver an [[EditionReferenceResolver]] instance | ||
* @param installerConfig configuration for the library installer | ||
*/ | ||
class LibraryPreinstallHandler | ||
extends Actor | ||
class LibraryPreinstallHandler( | ||
editionReferenceResolver: EditionReferenceResolver, | ||
installerConfig: LibraryInstallerConfig | ||
) extends Actor | ||
with LazyLogging | ||
with UnhandledLogging { | ||
|
||
implicit private val ec: ExecutionContext = | ||
ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) | ||
|
||
override def receive: Receive = { | ||
case Request(LibraryPreinstall, id, LibraryPreinstall.Params(_, name)) => | ||
// TODO [RW] actual implementation | ||
val progressReporter = | ||
ActorProgressNotificationForwarder.translateAndForward( | ||
LibraryPreinstall.name, | ||
sender() | ||
) | ||
|
||
if (name == "Test") { | ||
FakeDownload.simulateDownload( | ||
"Download Test", | ||
progressReporter, | ||
seconds = 1 | ||
) | ||
} else { | ||
FakeDownload.simulateDownload( | ||
"Downloading something...", | ||
progressReporter | ||
) | ||
FakeDownload.simulateDownload( | ||
"Downloading something else...", | ||
progressReporter | ||
) | ||
case Request( | ||
LibraryPreinstall, | ||
id, | ||
LibraryPreinstall.Params(namespace, name) | ||
) => | ||
val replyTo = sender() | ||
val libraryName = LibraryName(namespace, name) | ||
val notificationForwarder = new ProgressAndLockNotificationForwarder { | ||
override def sendProgressNotification( | ||
notification: ProgressNotification | ||
): Unit = | ||
replyTo ! ActorProgressNotificationForwarder | ||
.translateProgressNotification(LibraryPreinstall.name, notification) | ||
} | ||
|
||
val installation = Future { | ||
val result: Either[InstallationError, ResolvedLibrary] = for { | ||
libraryInstaller <- getLibraryProvider( | ||
notificationForwarder | ||
).toEither.left.map(InternalError) | ||
library <- libraryInstaller | ||
.findLibrary(libraryName) | ||
.left | ||
.map(InstallerError) | ||
} yield library | ||
LibraryInstallationComplete(id, replyTo, libraryName, result) | ||
} | ||
installation pipeTo self | ||
|
||
case LibraryInstallationComplete(requestId, replyTo, libraryName, result) => | ||
result match { | ||
case Left(error) => | ||
val errorMessage = error match { | ||
case InternalError(throwable) => | ||
FileSystemError( | ||
s"Could not initialize library installer: " + | ||
s"${throwable.getMessage}" | ||
) | ||
case InstallerError(Error.NotResolved(_)) => | ||
LibraryNotResolved(libraryName) | ||
case InstallerError(Error.RequestedLocalLibraryDoesNotExist) => | ||
LocalLibraryNotFound(libraryName) | ||
case InstallerError(Error.DownloadFailed(version, reason)) => | ||
LibraryDownloadError(libraryName, version, reason.getMessage) | ||
} | ||
replyTo ! ResponseError( | ||
Some(requestId), | ||
errorMessage | ||
) | ||
case Right(_) => | ||
replyTo ! ResponseResult(LibraryPreinstall, requestId, Unused) | ||
} | ||
sender() ! ResponseError( | ||
Some(id), | ||
FileSystemError("Feature not implemented") | ||
) | ||
} | ||
|
||
private def getLibraryProvider( | ||
notificationReporter: ProgressReporter with LockUserInterface | ||
): Try[ResolvingLibraryProvider] = | ||
for { | ||
config <- editionReferenceResolver.getCurrentProjectConfig | ||
edition <- editionReferenceResolver.resolveEdition( | ||
EditionReference.CurrentProjectEdition | ||
) | ||
} yield DefaultLibraryProvider.make( | ||
distributionManager = installerConfig.distributionManager, | ||
resourceManager = installerConfig.resourceManager, | ||
lockUserInterface = notificationReporter, | ||
progressReporter = notificationReporter, | ||
languageHome = installerConfig.languageHome, | ||
edition = edition, | ||
preferLocalLibraries = config.preferLocalLibraries | ||
) | ||
} | ||
|
||
object LibraryPreinstallHandler { | ||
|
||
/** Creates a configuration object to create [[LibraryPreinstallHandler]]. */ | ||
def props(): Props = Props(new LibraryPreinstallHandler) | ||
/** Creates a configuration object to create [[LibraryPreinstallHandler]]. | ||
* | ||
* @param editionReferenceResolver an [[EditionReferenceResolver]] instance | ||
* @param installerConfig configuration for the library installer | ||
*/ | ||
def props( | ||
editionReferenceResolver: EditionReferenceResolver, | ||
installerConfig: LibraryInstallerConfig | ||
): Props = Props( | ||
new LibraryPreinstallHandler(editionReferenceResolver, installerConfig) | ||
) | ||
|
||
case class LibraryInstallationComplete( | ||
requestId: Id, | ||
replyTo: ActorRef, | ||
libraryName: LibraryName, | ||
result: Either[InstallationError, ResolvedLibrary] | ||
) | ||
|
||
sealed trait InstallationError | ||
case class InternalError(throwable: Throwable) extends InstallationError | ||
case class InstallerError(error: Error) extends InstallationError | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.