mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +03:00
Reload project's config on rename (#7179)
Package's config information, once loaded, never changed. While there is typically no need for it, this was problematic when the config became out-of-sync with the filesystem, like in the case of project rename action. In rename, the config's properties would be updated in the FS, but that would never be reflected in module's package. Therefore further compilations would continue to ask for the old namespace. Most of the changes are cosmetic (s/`.config`/`.getConfig()`) except for the new `reloadConfig` method on `Package` that is being called in `RenameProjectCmd` handler. Closes #7062. # Important Notes The reported `ExecutionFailed` error should have been mostly fixed already via #7143. This change makes sure that all the related warnings are gone as well and the compiler uses the updated namespace.
This commit is contained in:
parent
b78a7e74e8
commit
3c93c25a5a
@ -31,7 +31,7 @@ class EditionReferenceResolver(
|
||||
}
|
||||
|
||||
/** Returns the configuration of the current project. */
|
||||
def getCurrentProjectConfig: Try[Config] = Try { projectPackage.config }
|
||||
def getCurrentProjectConfig: Try[Config] = Try { projectPackage.getConfig() }
|
||||
|
||||
/** Resolves all edition dependencies of an edition identified by
|
||||
* [[EditionReference]].
|
||||
|
@ -245,7 +245,7 @@ class LocalLibraryManager(
|
||||
*/
|
||||
private def findCurrentProjectEdition(): Option[Editions.RawEdition] = {
|
||||
val pkg = PackageManager.Default.loadPackage(currentProjectRoot).get
|
||||
pkg.config.edition
|
||||
pkg.getConfig().edition
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,16 @@ class ProjectSettingsManager(
|
||||
|
||||
private def loadSettings(): Try[SettingsResponse] = for {
|
||||
pkg <- PackageManager.Default.loadPackage(projectRoot)
|
||||
edition = pkg.config.edition.getOrElse(DefaultEdition.getDefaultEdition)
|
||||
} yield SettingsResponse(edition.parent, pkg.config.preferLocalLibraries)
|
||||
edition = pkg
|
||||
.getConfig()
|
||||
.edition
|
||||
.getOrElse(DefaultEdition.getDefaultEdition)
|
||||
} yield SettingsResponse(edition.parent, pkg.getConfig().preferLocalLibraries)
|
||||
|
||||
private def setParentEdition(editionName: String): Try[SettingsUpdated] =
|
||||
for {
|
||||
pkg <- PackageManager.Default.loadPackage(projectRoot)
|
||||
newEdition = pkg.config.edition match {
|
||||
newEdition = pkg.getConfig().edition match {
|
||||
case Some(edition) => edition.copy(parent = Some(editionName))
|
||||
case None => Editions.Raw.Edition(parent = Some(editionName))
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ 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
|
||||
|
||||
import java.io.{File, FileReader}
|
||||
|
||||
/** A request handler for `workspace/openFile` commands.
|
||||
*/
|
||||
@ -26,10 +26,7 @@ class ProjectInfoHandler(languageServerConfig: Config)
|
||||
|
||||
if (configFile.exists()) {
|
||||
val projectConfig = PkgConfig.fromYaml(
|
||||
new String(
|
||||
new FileInputStream(configFile).readAllBytes(),
|
||||
StandardCharsets.UTF_8
|
||||
)
|
||||
new FileReader(configFile)
|
||||
)
|
||||
if (projectConfig.isSuccess) {
|
||||
val projectInfo = ProjectInfo.Result(
|
||||
|
@ -145,7 +145,7 @@ final class SuggestionsHandler(
|
||||
MaskedPath(config.projectContentRoot.file.toPath),
|
||||
t
|
||||
),
|
||||
pkg => self ! ProjectNameUpdated(pkg.config.name)
|
||||
pkg => self ! ProjectNameUpdated(pkg.getConfig().name)
|
||||
)
|
||||
val requestId = UUID.randomUUID()
|
||||
runtimeConnector ! Api.Request(requestId, Api.GetTypeGraphRequest())
|
||||
|
@ -463,10 +463,10 @@ class LibrariesTest extends BaseServerTest {
|
||||
val mainPackage = libraryRoot.resolve("main.tgz")
|
||||
assert(Files.exists(mainPackage))
|
||||
val pkg = PackageManager.Default.loadPackage(libraryRoot.toFile).get
|
||||
pkg.config.authors should contain theSameElementsAs Seq(
|
||||
pkg.getConfig().authors should contain theSameElementsAs Seq(
|
||||
Contact(name = Some("user"), email = Some("example@example.com"))
|
||||
)
|
||||
pkg.config.maintainers should contain theSameElementsAs Seq(
|
||||
pkg.getConfig().maintainers should contain theSameElementsAs Seq(
|
||||
Contact(name = Some("only-name"), email = None),
|
||||
Contact(name = None, email = Some("foo@example.com"))
|
||||
)
|
||||
|
@ -49,7 +49,7 @@ object DependencyPreinstaller {
|
||||
val editionResolver = EditionResolver(editionProvider)
|
||||
val edition = editionResolver
|
||||
.resolve(
|
||||
pkg.config.edition.getOrElse(DefaultEdition.getDefaultEdition)
|
||||
pkg.getConfig().edition.getOrElse(DefaultEdition.getDefaultEdition)
|
||||
) match {
|
||||
case Left(error) =>
|
||||
throw new RuntimeException(
|
||||
@ -58,7 +58,7 @@ object DependencyPreinstaller {
|
||||
case Right(value) => value
|
||||
}
|
||||
|
||||
val preferLocalLibraries = pkg.config.preferLocalLibraries
|
||||
val preferLocalLibraries = pkg.getConfig().preferLocalLibraries
|
||||
|
||||
val (localLibraryProvider, publishedLibraryProvider) =
|
||||
DefaultLibraryProvider.makeProviders(
|
||||
|
@ -43,6 +43,13 @@ class RenameProjectCmd(
|
||||
val projectModules = getProjectModules
|
||||
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(
|
||||
|
@ -271,7 +271,9 @@ class RuntimeComponentsTest
|
||||
// check the registered component groups
|
||||
val components = context.languageContext.getPackageRepository.getComponents
|
||||
components.get(LibraryName("Enso_Test", "Test")).value shouldEqual
|
||||
context.pkg.config.componentGroups
|
||||
context.pkg
|
||||
.getConfig()
|
||||
.componentGroups
|
||||
.getOrElse(fail("Unexpected config value."))
|
||||
|
||||
components
|
||||
@ -348,7 +350,9 @@ class RuntimeComponentsTest
|
||||
val components = context.languageContext.getPackageRepository.getComponents
|
||||
|
||||
components.get(LibraryName("Enso_Test", "Test")).value shouldEqual
|
||||
context.pkg.config.componentGroups
|
||||
context.pkg
|
||||
.getConfig()
|
||||
.componentGroups
|
||||
.getOrElse(fail("Unexpected config value."))
|
||||
|
||||
components
|
||||
|
@ -92,7 +92,7 @@ public final class ImportExportCache extends Cache<ImportExportCache.CachedBindi
|
||||
var pathSegments = new String[]{
|
||||
pkg.namespace(),
|
||||
pkg.name(),
|
||||
pkg.config().version(),
|
||||
pkg.getConfig().version(),
|
||||
Info.ensoVersion(),
|
||||
libraryName.namespace()
|
||||
};
|
||||
|
@ -112,7 +112,7 @@ public final class ModuleCache extends Cache<ModuleCache.CachedModule, ModuleCac
|
||||
pathSegmentsJava.addAll(Arrays.asList(
|
||||
pkg.namespace(),
|
||||
pkg.name(),
|
||||
pkg.config().version(),
|
||||
pkg.getConfig().version(),
|
||||
Info.ensoVersion()
|
||||
));
|
||||
pathSegmentsJava.addAll(qualName.pathAsJava());
|
||||
|
@ -95,7 +95,7 @@ public final class SuggestionsCache
|
||||
var pathSegments = new String[]{
|
||||
pkg.namespace(),
|
||||
pkg.name(),
|
||||
pkg.config().version(),
|
||||
pkg.getConfig().version(),
|
||||
Info.ensoVersion(),
|
||||
libraryName.namespace()
|
||||
};
|
||||
|
@ -128,7 +128,7 @@ public abstract class EnsoProjectNode extends Node {
|
||||
|
||||
private static Atom createProjectDescriptionAtom(EnsoContext ctx, Package<TruffleFile> pkg) {
|
||||
EnsoFile rootPath = new EnsoFile(pkg.root().normalize());
|
||||
Object cfg = ctx.getEnvironment().asGuestValue(pkg.config());
|
||||
Object cfg = ctx.getEnvironment().asGuestValue(pkg.getConfig());
|
||||
return ctx.getBuiltins()
|
||||
.getProjectDescription()
|
||||
.getUniqueConstructor()
|
||||
|
@ -463,7 +463,7 @@ object PackageRepository {
|
||||
): Either[Error, Unit] =
|
||||
if (loadedComponents.contains(pkg.libraryName)) Right(())
|
||||
else {
|
||||
pkg.config.componentGroups match {
|
||||
pkg.getConfig().componentGroups match {
|
||||
case Left(err) =>
|
||||
Left(Error.PackageLoadingError(err.getMessage()))
|
||||
case Right(componentGroups) =>
|
||||
@ -760,7 +760,7 @@ object PackageRepository {
|
||||
.map(v => Editions.Raw.Edition(parent = Some(v)))
|
||||
.orElse(
|
||||
projectPackage
|
||||
.flatMap(_.config.edition)
|
||||
.flatMap(_.getConfig().edition)
|
||||
)
|
||||
.getOrElse(DefaultEdition.getDefaultEdition)
|
||||
|
||||
@ -777,7 +777,7 @@ object PackageRepository {
|
||||
languageHome = homeManager,
|
||||
edition = edition,
|
||||
preferLocalLibraries =
|
||||
projectPackage.exists(_.config.preferLocalLibraries)
|
||||
projectPackage.exists(_.getConfig().preferLocalLibraries)
|
||||
)
|
||||
new Default(
|
||||
resolvingLibraryProvider,
|
||||
|
@ -66,6 +66,7 @@ case class LibraryResolver(
|
||||
case Some(parentEdition) =>
|
||||
resolveLibraryFromEdition(libraryName, parentEdition)
|
||||
case None =>
|
||||
new Exception("library not found").printStackTrace()
|
||||
Left(
|
||||
LibraryResolutionError(
|
||||
s"The library `$libraryName` is not defined within " +
|
||||
|
@ -44,9 +44,9 @@ class LibraryUploader(dependencyExtractor: DependencyExtractor[File]) {
|
||||
)(implicit ec: ExecutionContext): Try[Unit] = Try {
|
||||
FileSystem.withTemporaryDirectory("enso-upload") { tmpDir =>
|
||||
val pkg = PackageManager.Default.loadPackage(projectRoot.toFile).get
|
||||
val version = SemVer(pkg.config.version).getOrElse {
|
||||
val version = SemVer(pkg.getConfig().version).getOrElse {
|
||||
throw new IllegalStateException(
|
||||
s"Project version [${pkg.config.version}] is not a valid semver " +
|
||||
s"Project version [${pkg.getConfig().version}] is not a valid semver " +
|
||||
s"string."
|
||||
)
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.enso.editions.{
|
||||
SemVerEnsoVersion
|
||||
}
|
||||
|
||||
import java.io.Reader
|
||||
import scala.util.Try
|
||||
|
||||
/** An extra project dependency.
|
||||
@ -250,6 +251,11 @@ object Config {
|
||||
yaml.parser.parse(yamlString).flatMap(_.as[Config]).toTry
|
||||
}
|
||||
|
||||
/** Tries to parse the [[Config]] directly from the Reader */
|
||||
def fromYaml(reader: Reader): Try[Config] = {
|
||||
yaml.parser.parse(reader).flatMap(_.as[Config]).toTry
|
||||
}
|
||||
|
||||
/** Creates a simple edition that just defines the provided engine version.
|
||||
*
|
||||
* A compatibility layer for migrating from just specifying the engine
|
||||
|
@ -25,9 +25,9 @@ case class SourceFile[F](qualifiedName: QualifiedName, file: F)
|
||||
* @param config the metadata contained in the package configuration
|
||||
* @param fileSystem the file system access module
|
||||
*/
|
||||
case class Package[F](
|
||||
root: F,
|
||||
config: Config,
|
||||
class Package[F](
|
||||
val root: F,
|
||||
initialConfig: Config,
|
||||
implicit val fileSystem: FileSystem[F]
|
||||
) {
|
||||
import FileSystem.Syntax
|
||||
@ -47,13 +47,25 @@ case class Package[F](
|
||||
.getChild(Package.cacheDirName)
|
||||
.getChild(Package.suggestionsCacheDirName)
|
||||
|
||||
private[this] var config: Config = initialConfig
|
||||
def getConfig(): Config = config
|
||||
|
||||
/** Reloads the config from file system */
|
||||
def reloadConfig(): Try[Config] = {
|
||||
val configFile = root.getChild(Package.configFileName)
|
||||
val newConfig = Using(configFile.newBufferedReader)(Config.fromYaml).flatten
|
||||
newConfig.foreach(config = _)
|
||||
newConfig
|
||||
}
|
||||
|
||||
/** Sets the package name.
|
||||
*
|
||||
* @param newName the new package name
|
||||
* @return a package with the updated name
|
||||
*/
|
||||
def setPackageName(newName: String): Package[F] =
|
||||
this.copy(config = config.copy(name = newName))
|
||||
def setPackageName(newName: String): Package[F] = {
|
||||
new Package(root, config.copy(name = newName), fileSystem)
|
||||
}
|
||||
|
||||
/** Stores the package metadata on the hard drive. If the package does not exist,
|
||||
* creates the required directory structure.
|
||||
@ -126,7 +138,7 @@ case class Package[F](
|
||||
* valid anymore.
|
||||
*/
|
||||
def updateConfig(update: Config => Config): Package[F] = {
|
||||
val newPkg = copy(config = update(config))
|
||||
val newPkg = new Package(root, update(config), fileSystem)
|
||||
newPkg.saveConfig()
|
||||
newPkg
|
||||
}
|
||||
@ -234,7 +246,7 @@ class PackageManager[F](implicit val fileSystem: FileSystem[F]) {
|
||||
config: Config,
|
||||
template: Template
|
||||
): Package[F] = {
|
||||
val pkg = Package(root, config, fileSystem)
|
||||
val pkg = new Package(root, config, fileSystem)
|
||||
pkg.save()
|
||||
copyResources(pkg, template)
|
||||
pkg
|
||||
@ -300,18 +312,15 @@ class PackageManager[F](implicit val fileSystem: FileSystem[F]) {
|
||||
val result =
|
||||
if (!root.exists) Failure(PackageManager.PackageNotFound())
|
||||
else {
|
||||
def readConfig(file: F): Try[String] =
|
||||
def readConfig(file: F): Try[Config] =
|
||||
if (file.exists)
|
||||
Using(file.newBufferedReader) { reader =>
|
||||
reader.lines().iterator().asScala.mkString("\n")
|
||||
}
|
||||
Using(file.newBufferedReader)(Config.fromYaml).flatten
|
||||
else Failure(PackageManager.PackageNotFound())
|
||||
|
||||
val configFile = root.getChild(Package.configFileName)
|
||||
for {
|
||||
resultStr <- readConfig(configFile)
|
||||
result <- Config.fromYaml(resultStr)
|
||||
} yield Package(root, result, fileSystem)
|
||||
result <- readConfig(configFile)
|
||||
} yield new Package(root, result, fileSystem)
|
||||
}
|
||||
result.recoverWith {
|
||||
case packageLoadingException: PackageManager.PackageLoadingException =>
|
||||
|
@ -109,7 +109,7 @@ class ProjectFileRepository[
|
||||
namespace = pkg.namespace,
|
||||
kind = meta.kind,
|
||||
created = meta.created,
|
||||
edition = pkg.config.edition,
|
||||
edition = pkg.getConfig().edition,
|
||||
lastOpened = meta.lastOpened,
|
||||
path = Some(directory.toString),
|
||||
directoryCreationTime = directoryCreationTime
|
||||
@ -156,7 +156,7 @@ class ProjectFileRepository[
|
||||
for {
|
||||
project <- getProject(projectId)
|
||||
projectPackage <- getPackage(new File(project.path.get))
|
||||
} yield projectPackage.config.name
|
||||
} yield projectPackage.getConfig().name
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
@ -166,7 +166,7 @@ class ProjectFileRepository[
|
||||
for {
|
||||
project <- getProject(projectId)
|
||||
projectPackage <- getPackage(new File(project.path.get))
|
||||
} yield projectPackage.config.namespace
|
||||
} yield projectPackage.getConfig().namespace
|
||||
}
|
||||
|
||||
private def loadPackage(
|
||||
|
@ -15,7 +15,7 @@ class Project(
|
||||
) {
|
||||
|
||||
/** The edition associated with the project. */
|
||||
def edition: Option[Editions.RawEdition] = pkg.config.edition
|
||||
def edition: Option[Editions.RawEdition] = pkg.getConfig().edition
|
||||
|
||||
/** The package name of the project. */
|
||||
def name: String = pkg.name
|
||||
@ -24,5 +24,5 @@ class Project(
|
||||
def path: Path = pkg.root.toPath
|
||||
|
||||
/** Project configuration. */
|
||||
def config: Config = pkg.config
|
||||
def config: Config = pkg.getConfig()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user