Notification about the project rename action (#7613)

close #7604

After moving the rename action to the dashboard, IDE is unaware of the new project name. PR implements a new `refactoring/projectRenamed` notification that is sent from the server to clients and informs them about the changed project name.

# Important Notes
https://github.com/enso-org/enso/assets/357683/7c62726d-217e-4e69-8e48-568e0b7b8c34
This commit is contained in:
Dmitry Bushev 2023-08-22 12:32:46 +01:00 committed by GitHub
parent 54bd83da1e
commit 5dc2c4c5fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 374 additions and 84 deletions

View File

@ -919,6 +919,7 @@
- [Support renaming variable or function][7515]
- [Only use types as State keys][7585]
- [Allow Java Enums in case of branches][7607]
- [Notification about the project rename action][7613]
[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
@ -1052,6 +1053,7 @@
[7515]: https://github.com/enso-org/enso/pull/7515
[7585]: https://github.com/enso-org/enso/pull/7585
[7607]: https://github.com/enso-org/enso/pull/7607
[7613]: https://github.com/enso-org/enso/pull/7613
# Enso 2.0.0-alpha.18 (2021-10-12)

View File

@ -174,6 +174,10 @@ pub enum Notification {
/// visualization.
#[serde(rename = "executionContext/visualizationEvaluationFailed")]
VisualizationEvaluationFailed(VisualizationEvaluationFailed),
/// Sent from server to the client to inform that the project has been renamed.
#[serde(rename = "refactoring/projectRenamed")]
ProjectRenamed(ProjectRenamed),
}
/// Sent from the server to the client to inform about a failure during execution of an execution
@ -382,6 +386,25 @@ pub struct TextFileModifiedOnDisk {
// =================================
// === Refactoring Notifications ===
// =================================
/// The `refactoring/projectRenamed` notification parameters.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProjectRenamed {
/// The old normalized project name.
pub old_normalized_name: String,
/// The new normalized project name.
pub new_normalized_name: String,
/// The new display project name.
pub new_name: String,
}
// ======================
// === FileAttributes ===
// ======================

View File

@ -88,10 +88,6 @@ pub trait API: Debug {
context_id: model::execution_context::Id,
) -> BoxFuture<'a, FallibleResult<model::ExecutionContext>>;
/// Set a new project name.
#[allow(clippy::needless_lifetimes)] // Note: Needless lifetimes
fn rename_project<'a>(&'a self, name: String) -> BoxFuture<'a, FallibleResult<()>>;
/// Returns the primary content root id for this project.
fn project_content_root_id(&self) -> Uuid {
self.json_rpc().project_root().id()
@ -184,6 +180,8 @@ pub enum Notification {
ExecutionComplete,
/// Indicates failure of the project execution.
ExecutionFailed,
/// Project has been renamed.
Renamed,
}
/// Denotes one of backend connections used by a project.

View File

@ -225,6 +225,22 @@ async fn reload_module_on_file_change(
Ok(())
}
/// Update internal state when the `refactoring/projectRenamed` notification received.
#[profile(Detail)]
fn rename_project_on_notification(
project_renamed: language_server::types::ProjectRenamed,
properties: Rc<RefCell<Properties>>,
execution_contexts: Rc<ExecutionContextsRegistry>,
) {
{
let mut properties = properties.borrow_mut();
properties.displayed_name = project_renamed.new_name.into();
properties.project_name.project = project_renamed.new_normalized_name.clone().into();
}
execution_contexts
.rename_project(project_renamed.old_normalized_name, project_renamed.new_normalized_name);
}
// =============
@ -522,10 +538,13 @@ impl Project {
let publisher = self.notifications.clone_ref();
let project_root_id = self.project_content_root_id();
let language_server = self.json_rpc().clone_ref();
let properties = self.properties.clone_ref();
let execution_contexts = self.execution_contexts.clone_ref();
let weak_suggestion_db = Rc::downgrade(&self.suggestion_db);
let weak_content_roots = Rc::downgrade(&self.content_roots);
let weak_module_registry = Rc::downgrade(&self.module_registry);
let execution_update_handler = self.execution_update_handler();
move |event| {
debug!("Received an event from the json-rpc protocol: {event:?}");
use engine_protocol::language_server::Event;
@ -618,6 +637,13 @@ impl Project {
update.message
);
}
Event::Notification(Notification::ProjectRenamed(project_renamed)) => {
let properties = properties.clone_ref();
let execution_contexts = execution_contexts.clone_ref();
rename_project_on_notification(project_renamed, properties, execution_contexts);
let notification = model::project::Notification::Renamed;
publisher.notify(notification);
}
Event::Closed => {
error!("Lost JSON-RPC connection with the Language Server!");
let which = model::project::BackendConnection::LanguageServerJson;
@ -750,33 +776,6 @@ impl model::project::API for Project {
.boxed_local()
}
fn rename_project(&self, name: String) -> BoxFuture<FallibleResult> {
if self.read_only() {
std::future::ready(Err(RenameInReadOnly.into())).boxed_local()
} else {
async move {
let old_name = self.properties.borrow_mut().project_name.project.clone_ref();
let referent_name = name.to_im_string();
let project_manager =
self.project_manager.as_ref().ok_or(ProjectManagerUnavailable)?;
let project_id = self.properties.borrow().id;
let project_name = ProjectName::new_unchecked(name);
project_manager.rename_project(&project_id, &project_name).await.map_err(
|error| match error {
RpcError::RemoteError(cause)
if cause.code == code::PROJECT_NAME_INVALID =>
failure::Error::from(ProjectNameInvalid { cause: cause.message }),
error => error.into(),
},
)?;
self.properties.borrow_mut().project_name.project = referent_name.clone_ref();
self.execution_contexts.rename_project(old_name, referent_name);
Ok(())
}
.boxed_local()
}
}
fn project_content_root_id(&self) -> Uuid {
self.language_server_rpc.project_root().id()
}

View File

@ -224,6 +224,11 @@ impl Model {
self.view.top_bar().project_name().set_project_changed(changed);
}
fn project_renamed(&self) {
let actual_name = self.controller.model.name();
self.view.top_bar().project_name().set_name(actual_name);
}
fn execution_complete(&self) {
self.view.graph().frp.set_read_only(false);
self.view.graph().frp.execution_complete.emit(());
@ -502,6 +507,9 @@ impl Project {
Notification::ExecutionFailed => {
model.execution_failed();
}
Notification::Renamed => {
model.project_renamed();
}
};
std::future::ready(())
});

View File

@ -50,8 +50,6 @@
//! [`SpanWidget::PRIORITY_OVER_OVERRIDE`] as `true` in their implementation. In that case, the
//! override will be applied again on their children that use the same span-tree node.
use crate::prelude::*;
use crate::component::node::input::area::NODE_HEIGHT;

View File

@ -126,6 +126,7 @@ transport formats, please look [here](./protocol-architecture).
- [Refactoring](#refactoring)
- [`refactoring/renameProject`](#refactoringrenameproject)
- [`refactoring/renameSymbol`](#refactoringrenamesymbol)
- [`refactoring/projectRenamed`](#refactoringprojectrenamed)
- [Execution Management Operations](#execution-management-operations)
- [Execution Management Example](#execution-management-example)
- [Create Execution Context](#create-execution-context)
@ -3412,6 +3413,41 @@ Current limitations of the method renaming are:
- [`RefactoringNotSupported`](#refactoringnotsupported) to signal that the
refactoring of the given expression is not supported.
### `refactoring/projectRenamed`
This is a notification sent from the server to the clients to inform them about
the new project name.
- **Type:** Notification
- **Direction:** Server -> Client
- **Connection:** Protocol
- **Visibility:** Public
#### Parameters
```typescript
{
/**
* Old normalized name of the project.
*/
oldNormalizedName: string;
/**
* New normalized name of the prject.
*/
newNormalizedName: string;
/**
* New display name of the project.
*/
newName: string;
}
```
#### Errors
None
## Execution Management Operations
The execution management portion of the language server API deals with exposing

View File

@ -36,6 +36,7 @@ import org.enso.languageserver.refactoring.RefactoringApi.{
RenameProject,
RenameSymbol
}
import org.enso.languageserver.refactoring.{RefactoringApi, RefactoringProtocol}
import org.enso.languageserver.requesthandler._
import org.enso.languageserver.requesthandler.capability._
import org.enso.languageserver.requesthandler.io._
@ -132,6 +133,13 @@ class JsonConnectionController(
implicit val timeout: Timeout = Timeout(requestTimeout)
override def preStart(): Unit = {
super.preStart()
context.system.eventStream
.subscribe(self, classOf[RefactoringProtocol.ProjectRenamedNotification])
}
override def receive: Receive = {
case JsonRpcServer.WebConnect(webActor) =>
unstashAll()
@ -416,6 +424,20 @@ class JsonConnectionController(
)
}
case RefactoringProtocol.ProjectRenamedNotification(
oldNormalizedName,
newNormalizedName,
newName
) =>
webActor ! Notification(
RefactoringApi.ProjectRenamed,
RefactoringApi.ProjectRenamed.Params(
oldNormalizedName,
newNormalizedName,
newName
)
)
case Api.ProgressNotification(payload) =>
val translated: Notification[_, _] =
translateProgressNotification(payload)
@ -582,6 +604,10 @@ class JsonConnectionController(
libraryConfig.localLibraryManager,
libraryConfig.publishedLibraryCache
),
RenameProject -> RenameProjectHandler.props(
requestTimeout,
runtimeConnector
),
RenameSymbol -> RenameSymbolHandler.props(
requestTimeout,
runtimeConnector

View File

@ -122,5 +122,6 @@ object JsonRpc {
.registerNotification(WaitingForStandardInput)
.registerNotification(SuggestionsDatabaseUpdates)
.registerNotification(VisualizationEvaluationFailed)
.registerNotification(ProjectRenamed)
.finalized()
}

View File

@ -27,6 +27,20 @@ object RefactoringApi {
}
}
case object ProjectRenamed extends Method("refactoring/projectRenamed") {
case class Params(
oldNormalizedName: String,
newNormalizedName: String,
newName: String
)
implicit val hasParams: HasParams.Aux[this.type, ProjectRenamed.Params] =
new HasParams[this.type] {
type Params = ProjectRenamed.Params
}
}
case object RenameSymbol extends Method("refactoring/renameSymbol") {
case class Params(
@ -60,4 +74,7 @@ object RefactoringApi {
s"Refactoring not supported for expression [$expressionId]"
)
case class ProjectRenameFailed(oldName: String, newName: String)
extends Error(9004, s"Project rename failed [$oldName, $newName]")
}

View File

@ -0,0 +1,16 @@
package org.enso.languageserver.refactoring
object RefactoringProtocol {
/** Notification signaling about the project being renamed.
*
* @param oldNormalizedName old normalized name of the project
* @param newNormalizedName new normalized name of the project
* @param newName new display name of the project
*/
case class ProjectRenamedNotification(
oldNormalizedName: String,
newNormalizedName: String,
newName: String
)
}

View File

@ -1,15 +1,19 @@
package org.enso.languageserver.requesthandler.refactoring
import java.util.UUID
import akka.actor.{Actor, ActorRef, Cancellable, Props}
import com.typesafe.scalalogging.LazyLogging
import org.enso.jsonrpc._
import org.enso.languageserver.refactoring.RefactoringApi.RenameProject
import org.enso.languageserver.refactoring.RefactoringApi.{
ProjectRenameFailed,
RenameProject
}
import org.enso.languageserver.refactoring.RefactoringProtocol
import org.enso.languageserver.requesthandler.RequestTimeout
import org.enso.languageserver.util.UnhandledLogging
import org.enso.polyglot.runtime.Runtime.Api
import java.util.UUID
import scala.concurrent.duration.FiniteDuration
/** A request handler for `refactoring/renameProject` commands.
@ -52,10 +56,25 @@ class RenameProjectHandler(timeout: FiniteDuration, runtimeConnector: ActorRef)
replyTo ! ResponseError(Some(id), Errors.RequestTimeout)
context.stop(self)
case Api.Response(_, Api.ProjectRenamed(_, _)) =>
case Api.Response(
_,
Api.ProjectRenamed(oldNormalizedName, newNormalizedName, newName)
) =>
context.system.eventStream.publish(
RefactoringProtocol.ProjectRenamedNotification(
oldNormalizedName,
newNormalizedName,
newName
)
)
replyTo ! ResponseResult(RenameProject, id, Unused)
cancellable.cancel()
context.stop(self)
case Api.Response(_, Api.ProjectRenameFailed(oldName, newName)) =>
replyTo ! ResponseError(Some(id), ProjectRenameFailed(oldName, newName))
cancellable.cancel()
context.stop(self)
}
}

View File

@ -13,8 +13,6 @@ import java.util.UUID
* @param executionContextId an execution context of the visualization
* @param expression an expression that creates a visualization
* @param visualizationModule the name of a module to execute expression at
* @param executionContextId an execution context of the visualization
* @param expression an expression that creates a visualization
*/
case class VisualizationConfiguration(
executionContextId: UUID,
@ -26,7 +24,8 @@ case class VisualizationConfiguration(
override def toLogString(shouldMask: Boolean): String =
s"VisualizationConfiguration(" +
s"executionContextId=$executionContextId," +
s"expression=${expression.toLogString(shouldMask)})"
s"expression=${expression.toLogString(shouldMask)}," +
s"visualizationModule=$visualizationModule)"
/** Convert to corresponding [[Api]] message. */
def toApi: Api.VisualizationConfiguration =

View File

@ -608,7 +608,7 @@ class LibrariesTest extends BaseServerTest {
PackageManager.Default
.loadPackage(cachedLibraryRoot.location.toFile)
.get
pkg.module shouldEqual "Bar"
pkg.normalizedName shouldEqual "Bar"
pkg
.listSources()
.map(

View File

@ -7,6 +7,105 @@ import java.util.UUID
class RefactoringTest extends BaseServerTest {
"refactoring/renameProject" should {
"return ok response after a successful renaming" in {
val client = getInitialisedWsClient()
val namespace = "local"
val oldName = "Unnamed"
val newName = "Project1"
client.send(json"""
{ "jsonrpc": "2.0",
"method": "refactoring/renameProject",
"id": 1,
"params": {
"namespace": $namespace,
"oldName": $oldName,
"newName": $newName
}
}
""")
val requestId = runtimeConnectorProbe.receiveN(1).head match {
case Api.Request(requestId, payload: Api.RenameProject) =>
payload.namespace shouldEqual namespace
payload.oldName shouldEqual oldName
payload.newName shouldEqual newName
requestId
case msg =>
fail(s"Runtime connector received unexpected message: $msg")
}
runtimeConnectorProbe.lastSender ! Api.Response(
requestId,
Api.ProjectRenamed(oldName, newName, newName)
)
client.expectJson(json"""
{ "jsonrpc": "2.0",
"id": 1,
"result": null
}
""")
client.expectJson(json"""
{ "jsonrpc": "2.0",
"method": "refactoring/projectRenamed",
"params": {
"oldNormalizedName": $oldName,
"newNormalizedName": $newName,
"newName": $newName
}
}
""")
}
"reply with ProjectRenameFailed in case of failures" in {
val client = getInitialisedWsClient()
val namespace = "local"
val oldName = "Unnamed"
val newName = "Project1"
client.send(json"""
{ "jsonrpc": "2.0",
"method": "refactoring/renameProject",
"id": 1,
"params": {
"namespace": $namespace,
"oldName": $oldName,
"newName": $newName
}
}
""")
val requestId = runtimeConnectorProbe.receiveN(1).head match {
case Api.Request(requestId, payload: Api.RenameProject) =>
payload.namespace shouldEqual namespace
payload.oldName shouldEqual oldName
payload.newName shouldEqual newName
requestId
case msg =>
fail(s"Runtime connector received unexpected message: $msg")
}
runtimeConnectorProbe.lastSender ! Api.Response(
requestId,
Api.ProjectRenameFailed(oldName, newName)
)
client.expectJson(json"""
{ "jsonrpc": "2.0",
"id": 1,
"error": {
"code": 9004,
"message": ${s"Project rename failed [$oldName, $newName]"}
}
}
""")
}
}
"refactoring/renameSymbol" should {
"return ok response after a successful renaming" in {

View File

@ -156,6 +156,10 @@ object Runtime {
value = classOf[Api.ProjectRenamed],
name = "projectRenamed"
),
new JsonSubTypes.Type(
value = classOf[Api.ProjectRenameFailed],
name = "projectRenameFailed"
),
new JsonSubTypes.Type(
value = classOf[Api.RenameSymbol],
name = "renameSymbol"
@ -1638,10 +1642,22 @@ object Runtime {
/** Signals that project has been renamed.
*
* @param namespace the namespace of the project
* @param newName the new project name
* @param oldNormalizedName old normalized name of the project
* @param newNormalizedName new normalized name of the project
* @param newName new display name of the project
*/
final case class ProjectRenamed(namespace: String, newName: String)
final case class ProjectRenamed(
oldNormalizedName: String,
newNormalizedName: String,
newName: String
) extends ApiResponse
/** Signals that project has been renamed.
*
* @param oldName the old name of the project
* @param newName the new name of the project
*/
final case class ProjectRenameFailed(oldName: String, newName: String)
extends ApiResponse
/** A request for symbol renaming.

View File

@ -4,7 +4,6 @@ import java.util.logging.Level
import org.enso.interpreter.instrument.{CacheInvalidation, InstrumentFrame}
import org.enso.interpreter.instrument.execution.RuntimeContext
import org.enso.interpreter.instrument.job.{EnsureCompiledJob, ExecuteJob}
import org.enso.interpreter.runtime.Module
import org.enso.pkg.QualifiedName
import org.enso.polyglot.data.Tree
import org.enso.polyglot.runtime.Runtime.Api
@ -40,16 +39,23 @@ class RenameProjectCmd(
Level.FINE,
s"Renaming project [old:${request.namespace}.${request.oldName},new:${request.namespace}.${request.newName}]..."
)
val projectModules = getProjectModules
val packageRepository =
ctx.executionService.getContext.getPackageRepository
val mainPackage = packageRepository.getMainProjectPackage
.getOrElse(throw new RenameProjectCmd.MainProjectPackageNotFound)
val projectModules =
packageRepository.getModulesForLibrary(mainPackage.libraryName)
val oldConfig = mainPackage.getConfig()
val newConfig = mainPackage
.reloadConfig()
.fold(
cause => throw new RenameProjectCmd.FailedToReloadConfig(cause),
identity
)
projectModules.foreach { module =>
module.setIndexed(false)
val newConfig = module.getPackage.reloadConfig()
if (newConfig.isFailure) {
logger.log(
Level.WARNING,
s"Failed to reload package's config: ${newConfig.failed.get.getMessage}"
)
}
ctx.endpoint.sendToClient(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
@ -76,11 +82,32 @@ class RenameProjectCmd(
clearCache(stack)
}
reply(Api.ProjectRenamed(request.namespace, request.newName))
reply(
Api.ProjectRenamed(
oldConfig.moduleName,
newConfig.moduleName,
newConfig.name
)
)
logger.log(
Level.INFO,
s"Project renamed to ${request.namespace}.${request.newName}"
)
} catch {
case ex: RenameProjectCmd.MainProjectPackageNotFound =>
logger.log(
Level.SEVERE,
"Main project package is not found.",
ex
)
reply(Api.ProjectRenameFailed(request.oldName, request.newName))
case ex: RenameProjectCmd.FailedToReloadConfig =>
logger.log(
Level.SEVERE,
"Failed to reload package config.",
ex
)
reply(Api.ProjectRenameFailed(request.oldName, request.newName))
} finally {
ctx.locking.releaseWriteCompilationLock()
logger.log(
@ -133,13 +160,6 @@ class RenameProjectCmd(
}
}
private def getProjectModules(implicit ctx: RuntimeContext): Seq[Module] = {
val packageRepository = ctx.executionService.getContext.getPackageRepository
packageRepository.getMainProjectPackage
.map { pkg => packageRepository.getModulesForLibrary(pkg.libraryName) }
.getOrElse(List())
}
private def clearCache(stack: Iterable[InstrumentFrame]): Unit = {
stack.foreach(_.syncState.clearMethodPointersState())
CacheInvalidation.run(
@ -152,3 +172,12 @@ class RenameProjectCmd(
}
}
object RenameProjectCmd {
final private class MainProjectPackageNotFound
extends Exception("Main project package is not found.")
final private class FailedToReloadConfig(cause: Throwable)
extends Exception("Failed to reload config", cause)
}

View File

@ -5604,7 +5604,7 @@ class RuntimeServerTest
)
val renameProjectResponses = context.receiveN(6)
renameProjectResponses should contain allOf (
Api.Response(requestId, Api.ProjectRenamed("Enso_Test", "Foo")),
Api.Response(requestId, Api.ProjectRenamed("Test", "Foo", "Foo")),
context.Main.Update.mainX(contextId, typeChanged = false),
TestMessages.update(
contextId,
@ -5720,7 +5720,7 @@ class RuntimeServerTest
)
val renameProjectResponses = context.receiveN(6)
renameProjectResponses should contain allOf (
Api.Response(requestId, Api.ProjectRenamed("Enso_Test", "Foo")),
Api.Response(requestId, Api.ProjectRenamed("Test", "Foo", "Foo")),
context.Main.Update.mainX(contextId, typeChanged = false),
TestMessages.update(
contextId,

View File

@ -728,7 +728,7 @@ class RuntimeSuggestionUpdatesTest
Api.Request(requestId, Api.RenameProject("Enso_Test", "Test", "Foo"))
)
context.receiveN(4) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.ProjectRenamed("Enso_Test", "Foo")),
Api.Response(requestId, Api.ProjectRenamed("Test", "Foo", "Foo")),
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
module = moduleName,

View File

@ -93,7 +93,7 @@ public final class ImportExportCache extends Cache<ImportExportCache.CachedBindi
var distribution = context.getDistributionManager();
var pathSegments = new String[]{
pkg.namespace(),
pkg.module(),
pkg.normalizedName(),
pkg.getConfig().version(),
Info.ensoVersion(),
libraryName.namespace()

View File

@ -112,7 +112,7 @@ public final class ModuleCache extends Cache<ModuleCache.CachedModule, ModuleCac
var pathSegmentsJava = new ArrayList<String>();
pathSegmentsJava.addAll(Arrays.asList(
pkg.namespace(),
pkg.module(),
pkg.normalizedName(),
pkg.getConfig().version(),
Info.ensoVersion()
));

View File

@ -85,7 +85,6 @@ public final class SuggestionsCache
.map(pkg -> computeDigestOfLibrarySources(pkg.listSourcesJava(), logger));
}
@Override
protected Optional<Roots> getCacheRoots(EnsoContext context) {
return context.getPackageRepository().getPackageForLibraryJava(libraryName).map(pkg -> {
@ -94,7 +93,7 @@ public final class SuggestionsCache
var distribution = context.getDistributionManager();
var pathSegments = new String[]{
pkg.namespace(),
pkg.module(),
pkg.normalizedName(),
pkg.getConfig().version(),
Info.ensoVersion(),
libraryName.namespace()

View File

@ -193,26 +193,28 @@ class Compiler(
CompletableFuture.completedFuture(false)
case Some(pkg) =>
val packageModule = packageRepository.getModuleMap.get(
s"${pkg.namespace}.${pkg.module}.Main"
s"${pkg.namespace}.${pkg.normalizedName}.Main"
)
packageModule match {
case None =>
context.log(
Level.SEVERE,
"Could not find entry point for compilation in package [{0}.{1}]",
Array(pkg.namespace, pkg.module)
Array(pkg.namespace, pkg.normalizedName)
)
CompletableFuture.completedFuture(false)
case Some(m) =>
context.log(
Compiler.defaultLogLevel,
s"Compiling the package [${pkg.namespace}.${pkg.module}] " +
s"Compiling the package [${pkg.namespace}.${pkg.normalizedName}] " +
s"starting at the root [${m.getName}]."
)
val packageModules = packageRepository.freezeModuleMap.collect {
case (name, mod)
if name.startsWith(s"${pkg.namespace}.${pkg.module}") =>
if name.startsWith(
s"${pkg.namespace}.${pkg.normalizedName}"
) =>
mod
}.toList

View File

@ -129,7 +129,7 @@ case object Imports extends IRPass {
)
val pkgName =
IR.Name.Literal(
pkg.module,
pkg.normalizedName,
isMethod = false,
location = None
)

View File

@ -327,7 +327,7 @@ private class DefaultPackageRepository(
Left(PackageRepository.Error.PackageLoadingError(err.getMessage()))
case Right(componentGroups) =>
logger.debug(
s"Resolving component groups of package [${pkg.module}]."
s"Resolving component groups of package [${pkg.normalizedName}]."
)
registerComponentGroups(pkg.libraryName, componentGroups.newGroups)

View File

@ -43,7 +43,7 @@ class LibraryDownloadTest
}
val pkg =
PackageManager.Default.loadPackage(libPath.location.toFile).get
pkg.module shouldEqual "Bar"
pkg.normalizedName shouldEqual "Bar"
val sources = pkg.listSources()
sources should have size 1
sources.head.file.getName shouldEqual "Main.enso"

View File

@ -67,7 +67,7 @@ class LibraryUploadTest
PackageManager.Default
.loadPackage(libRoot.toFile)
.get
.module shouldEqual libraryName.name
.normalizedName shouldEqual libraryName.name
assert(Files.exists(libRoot.resolve("manifest.yaml")))
assert(Files.exists(libRoot.resolve("main.tgz")))
@ -83,7 +83,7 @@ class LibraryUploadTest
val pkg = PackageManager.Default
.loadPackage(installedRoot.location.toFile)
.get
pkg.module shouldEqual libraryName.name
pkg.normalizedName shouldEqual libraryName.name
val sources = pkg.listSources()
sources should have size 1
sources.head.file.getName shouldEqual "Main.enso"

View File

@ -181,16 +181,16 @@ class Package[F](
*/
def name: String = config.name
/** Returns the module of this package.
* @return the module of this package.
/** Returns the normalized name of this package.
* @return the normalized name of this package.
*/
def module: String =
def normalizedName: String =
config.normalizedName.getOrElse(NameValidation.normalizeName(name))
def namespace: String = config.namespace
/** A [[LibraryName]] associated with the package. */
def libraryName: LibraryName = LibraryName(config.namespace, module)
def libraryName: LibraryName = LibraryName(config.namespace, normalizedName)
/** Parses a file path into a qualified module name belonging to this
* package.
@ -202,7 +202,10 @@ class Package[F](
val segments = sourceDir.relativize(file).getSegments.asScala.toList
val dirSegments = segments.take(segments.length - 1)
val fileNameWithoutExtension = file.getName.takeWhile(_ != '.')
QualifiedName(namespace :: module :: dirSegments, fileNameWithoutExtension)
QualifiedName(
namespace :: normalizedName :: dirSegments,
fileNameWithoutExtension
)
}
/** Lists the source files in this package.

View File

@ -106,7 +106,7 @@ class ProjectFileRepository[
Project(
id = meta.id,
name = pkg.name,
module = pkg.module,
module = pkg.normalizedName,
namespace = pkg.namespace,
kind = meta.kind,
created = meta.created,

View File

@ -18,7 +18,7 @@ class Project(
def edition: Option[Editions.RawEdition] = pkg.getConfig().edition
/** The package name of the project. */
def name: String = pkg.module
def name: String = pkg.normalizedName
/** The path to the content root of the project. */
def path: Path = pkg.root.toPath