-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Metals support #15
Comments
Thanks for giving Seed a try! Metals support is still incomplete as you already noticed. Here are the things we will need to change to make the experience smoother:
|
I'm having a try at the first of those checkboxes and have some questions:
|
Thanks for taking a stab at it.
Next, add the project-level seed/src/main/scala/seed/artefact/ArtefactResolution.scala Lines 126 to 127 in 7fa092f
--- a/test/example-paradise/build.toml
+++ b/test/example-paradise/build.toml
@@ -9,6 +9,13 @@ scalaOptions = ["-encoding", "UTF-8", "-unchecked", "-deprecation", "-Xfuture"
root = "macros"
sources = ["macros"]
targets = ["jvm", "js"]
+
+[module.macros.jvm]
+compilerDeps = [
+ ["org.scalamacros", "paradise", "2.1.1", "full"]
+]
+
+[module.macros.js]
compilerDeps = [
["org.scalamacros", "paradise", "2.1.1", "full"]
] |
That's pretty much what I've done now. I'll see if I can wrap it up tonight :) |
Actually now that I think about it, shouldn't an imported project's compilerDeps only be applied to the imported project's modules? This would mean that the combining of project-level deps ++ module-level deps have to happen in val imported = parsed.`import`.flatMap(parse(_))
def combineCompilerDeps(project: Project, module: Module): Module =
module.copy(compilerDeps = (project.compilerDeps ++ module.compilerDeps).distinct)
val parsedModules = parsed.module.mapValues(combineCompilerDeps(parsed.project, _))
val importedModules = imported.foldLeft(Map.empty[String, Module]) { case (acc, importedBuild) =>
importedBuild.module.mapValues(combineCompilerDeps(importedBuild.project, _))
}
parsed.copy(
project = parsed.project.copy(
testFrameworks = (parsed.project.testFrameworks ++ imported.flatMap(_.project.testFrameworks)).distinct,
),
module = parsedModules ++ importedModules) … it then follows that the modules will already have their compilerDeps set once artifact resolution kicks in. The drawback, perhaps, is that the processing of the build now updates module definitions up-front. That is, it's impossible to later see if the compiler dep came from the project or was assigned directly to the module. Maybe this isn't a big deal? |
One more question: README.md states that
Does this mean that, in the scenario of some project "foo" importing project "bar" with |
Agreed. The importing of projects is quite simplistic at the moment. All we do is pull in the modules into the scope. The compiler flags and the Scala/Scala.js/Scala Native versions of the imported projects are ignored. The assumption was that the versions and settings from the root project are indicative. Also, one more limitation is that the module names have to be unique across all imported builds. Despite its simplicity, this approach worked rather well even with multiple levels of inheritance. Still, we should strive for a more correct solution which is to compile the modules exactly with the settings specified in their build files (i.e. versions, plug-ins, flags etc.) Then, the only thing we would have to ensure is that imported modules have a compatible Scala version (importing a Scala 2.13 build into a Scala 2.12 build would not be possible anymore).
If we want to retain the original build definitions, we could represent them as a tree structure rather than flattening them (as we do right now). This would be particularly useful when visualising builds, but for the time being your proposed solution is fairly sufficient.
Yes. This was the approach up until now, but I think we'd better change it. |
I'm looking at checkbox #2 now, "Create a global Seed setting semanticDb". From the context I'm assuming that the setting should be a boolean flag on Build just like tmpfs, but I want to think this through a few extra steps. Notably
|
Good objections. The problem with adding SemanticDB to every Bloop configuration is that it will slow down compilation and can introduce indeterminism (I saw it crash the compiler in some cases). In CI settings, this would be undesired. One more limitation to account for is that SemanticDB is not available for all Scala versions. Mill hard-codes the SemanticDB version as well as the Scala versions the plug-in is compatible with. In Seed, we could define a default version which we treat as the recommended minimum version (similar to how we already do it with Bloop and Coursier). We should let users override this version, such that they do not have to wait for a new Seed release to come out. I am thinking of a separate section that looks as follows: [semantic-db]
enable = true
# The following two settings are optional
version = "4.1.12"
scalaVersions = [
"2.13.0",
"2.12.8",
"2.12.7",
"2.11.12"
]
The setting will be added to the global Seed configuration file ( |
Is the scalaVersions necessary? The plugin needs to be resolved with full Scala versioning and if that fails the build will fail. This also makes me wonder if it's good to have the definition in the global configuration, since it will cause unrelated projects (those with incorrect scalaVersion) to either fail or silently not install semanticdb. This seems like a source of confusion. |
We should only resolve the plug-in if the build file's Scala version is compatible, otherwise a warning will be triggered. Seed already does something similar when generating IDEA projects. If a module does not specify a root path, it will be skipped with a warning. |
This is relevant: scalameta/metals#852 It seems we can drop the last checkbox with this change :) (when/if it ships) |
Great. For reference, the corresponding pull request in Bloop is scalacenter/bloop#942. @tgodzik Do I see correctly that we will only have to set |
Yes, that's needed for one of the parameters of SemanticDB and this path itself might be useful in a number of other things. We default it to the parent of the configDir: project.workspaceDirectory.getOrElse(configDir.getParent) |
Really excited that the next bloop release will support seed out of the box. |
Bloop 1.3.3 is released! And metals has this merged: scalameta/metals#852 although not yet published it seems. |
Should published under a snapshot - will try to release a new version next week or so. |
I've been playing around with this little build tool and I really like the feel of it so far. One problem though is metals integration.
It seems like seed doesn't generate everything metals need to be happy. For instance, the
resolution.modules
path is completely empty. By adding modules manually I was able to get "go to definition" working for the Scala library, but obviously this is not feasible to do for every resolved artifact in the build, especially as things get larger and definitions need to be updated.It is also a bit tricky—but manageable—to add the required semanticdb compiler plugin to the build: resolving the plugin itself is dead easy with
compilerDeps
, but the user also needs to manually add full plugin path to thescalaOptions
, along with a few plugin-specific settings. At least the path could be added automatically.The text was updated successfully, but these errors were encountered: