metals
metals copied to clipboard
Ammonite support is broken when using sources defined as symbolic links
Describe the bug
Using sources that are symbolic links instead of regular files leads to throwing exceptions when running Metals with Ammonite support.
Reproduction steps:
-
mkdir source usage
-
touch source/script.sc
-
ln -fs source/script.sc usage/script.sc
- Open metals in
usage
directory, start ammonite server and try to import the build
Leads to exceptions listed below, replacing symlinks with regular files fixes the problem
java.nio.file.NoSuchFileException: <project-path>/.ammonite/scala-2.13.4/amm-2.5.2/source/script/src/ammonite/$file/^/source/script.scala
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
at java.nio.file.Files.newByteChannel(Files.java:370)
at java.nio.file.Files.newByteChannel(Files.java:421)
at java.nio.file.Files.readAllBytes(Files.java:3205)
at scala.meta.internal.io.PlatformFileIO$.slurp(PlatformFileIO.scala:45)
at scala.meta.internal.io.FileIO$.slurp(FileIO.scala:24)
at scala.meta.internal.metals.InteractiveSemanticdbs.$anonfun$textDocument$2(InteractiveSemanticdbs.scala:90)
at scala.Option.getOrElse(Option.scala:189)
at scala.meta.internal.metals.InteractiveSemanticdbs.$anonfun$textDocument$1(InteractiveSemanticdbs.scala:90)
at java.util.HashMap.compute(HashMap.java:1228)
at java.util.Collections$SynchronizedMap.compute(Collections.java:2692)
at scala.meta.internal.metals.InteractiveSemanticdbs.textDocument(InteractiveSemanticdbs.scala:89)
at scala.meta.internal.metals.InteractiveSemanticdbs.textDocument(InteractiveSemanticdbs.scala:63)
at scala.meta.internal.metals.AggregateSemanticdbs.loop$1(AggregateSemanticdbs.scala:30)
at scala.meta.internal.metals.AggregateSemanticdbs.textDocument(AggregateSemanticdbs.scala:36)
at scala.meta.internal.metals.CodeLensProvider.findLenses(CodeLensProvider.scala:22)
at scala.meta.internal.metals.MetalsLanguageServer.$anonfun$codeLens$2(MetalsLanguageServer.scala:1628)
at scala.meta.internal.metals.TimerProvider.timedThunk(TimerProvider.scala:25)
at scala.meta.internal.metals.MetalsLanguageServer.$anonfun$codeLens$1(MetalsLanguageServer.scala:1626)
at scala.meta.internal.metals.CancelTokens$.$anonfun$apply$2(CancelTokens.scala:26)
at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
at scala.util.Success.$anonfun$map$1(Try.scala:255)
at scala.util.Success.map(Try.scala:213)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:834)
2022.04.06 13:24:54 ERROR text document: file:///<project-path>/.ammonite/scala-2.13.4/amm-2.5.2/source/script/src/ammonite/$file/%5E/source/script.scala
java.nio.file.NoSuchFileException: <project-path>/.ammonite/scala-2.13.4/amm-2.5.2/project-builder/mill/MillCommunityBuild/src/ammonite/$file/^/project-builder/mill/MillCommunityBuild.scala
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
at java.nio.file.Files.newByteChannel(Files.java:370)
at java.nio.file.Files.newByteChannel(Files.java:421)
at java.nio.file.Files.readAllBytes(Files.java:3205)
at scala.meta.internal.io.PlatformFileIO$.slurp(PlatformFileIO.scala:45)
at scala.meta.internal.io.FileIO$.slurp(FileIO.scala:24)
at scala.meta.internal.metals.InteractiveSemanticdbs.$anonfun$textDocument$2(InteractiveSemanticdbs.scala:90)
at scala.Option.getOrElse(Option.scala:189)
at scala.meta.internal.metals.InteractiveSemanticdbs.$anonfun$textDocument$1(InteractiveSemanticdbs.scala:90)
at java.util.HashMap.compute(HashMap.java:1228)
at java.util.Collections$SynchronizedMap.compute(Collections.java:2692)
at scala.meta.internal.metals.InteractiveSemanticdbs.textDocument(InteractiveSemanticdbs.scala:89)
at scala.meta.internal.metals.InteractiveSemanticdbs.textDocument(InteractiveSemanticdbs.scala:63)
at scala.meta.internal.metals.AggregateSemanticdbs.loop$1(AggregateSemanticdbs.scala:30)
at scala.meta.internal.metals.AggregateSemanticdbs.textDocument(AggregateSemanticdbs.scala:36)
at scala.meta.internal.metals.CodeLensProvider.findLenses(CodeLensProvider.scala:22)
at scala.meta.internal.metals.MetalsLanguageServer.$anonfun$codeLens$2(MetalsLanguageServer.scala:1628)
at scala.meta.internal.metals.TimerProvider.timedThunk(TimerProvider.scala:25)
at scala.meta.internal.metals.MetalsLanguageServer.$anonfun$codeLens$1(MetalsLanguageServer.scala:1626)
at scala.meta.internal.metals.CancelTokens$.$anonfun$apply$2(CancelTokens.scala:26)
at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
at scala.util.Success.$anonfun$map$1(Try.scala:255)
at scala.util.Success.map(Try.scala:213)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:834)
2022.04.06 13:24:55 WARN no build target for: <project-path>/repo/.ammonite/scala-2.13.4/amm-2.5.2/source/script//src/ammonite/$file/^/source/script/.scala
Expected behavior
It should not throw exceptions and allow to correctly use metals
Operating system
Linux
Editor/Extension
VS Code
Version of Metals
v0.11.2
Extra context or search terms
No response
It seems the issue is due to the fact that we always unalias all the file uris we get, but ammonite produces ones using the symbolic name. We could add the check in:
https://github.com/scalameta/metals/blob/main/metals/src/main/scala/scala/meta/internal/metals/ammonite/Ammonite.scala#L126
if the file doesn't exist we could fallback to the link without dealias.