IntelliJ Idea sbt managed source file - scala

I am using sbt-buildinfo plugin that generates Scala source from my build definitions, allowing me to reference project name, version, etc. from my Scala code.
It does this by generating a file BuiltInfo.scala with the following contents:
package hello
case object BuildInfo {
val name = "helloworld"
val version = "0.1-SNAPSHOT"
val scalaVersion = "2.10.3"
val sbtVersion = "0.13.2"
}
in
target/scala-2.10/src_managed/main/sbt-buildinfo/BuildInfo.scala.
Everything compiles and I can reference those vals.
However, IntelliJ Idea doesn't recognize BuildInfo.scala as a managed source file, so that it would stop showing me errors. Any idea how to do that?
Thanks!

Grega, are you working in a Play Framework project? Or do you have any SBT sub-projects? I don't have a complete answer, but may have a lead.
This same problem shows up in my IDEA projects when using sbt-buildinfo and sbt-scalaxb. Frustratingly, it has worked intermittently—usually after lots of tinkering around, but inexplicably stops.
I wound up digging a bit deeper (and eventually issued bug report SCL-7182 to JetBrains), and noticed the root cause was having a sub-project. When present, IDEA doesn't correctly identify src_managed for the root project, but does for the sub-project.
A work-around, for now, is to manually add the correct src_managed directory to your project's sources using the Project Structure dialog.
For reference, I'm running version 0.38.437 of the Scala plugin on IntelliJ IDEA 13.1.3.

Related

Scala "not found: object com" - should i really add entry in build.sbt if there are no other dependencies?

I have created basic Scala Play application with https://www.playframework.com/getting-started play-scala-seed. This project compiles and runs with sbt run. But I have another Scala project that compiles and runs and which I have submitted to my local Ivy repository with command sbt publishLocal. This other project was saved at C:\Users\tomr\.ivy2\local\com.agiintelligence\scala-isabelle_2.13\master-SNAPSHOT as a result of this command.
Then I imported (exactly so - imported, no just opened) my Play project in IntelliJ and I used Project - Open Module Settings - Project Settings - Libraries to add com.agiintelligence jar from my ivy2 location. After such operations IntelliJ editor recognizes com.agiintelligence classes. That is fine.
But when I am trying to run my Play application with sbt run, I experience the error message not found: object com that is exactly when compiling import com.agiintelligence line in my Scala controller file of Play application.
Of course - such error has been reported and resolved with, e.g. object play not found in scala application
But that solution suggests to append build.sbt file. My build.sbt file is pretty bare:
name := """agiintelligence"""
organization := "com.agiintelligence"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.5"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.skaraintelligence.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.skaraintelligence.binders._"
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries' (it shows my com.agiintelligence jar as well), but why should I add my own ivy2 library in build.sbt file if no other libraries are listed here? What is different with my library? It is on my computer, in the repository as expected already?
Of course, I can try to add it build.sbt and issue sbt update and see what happens, but I can not understand this logic? Can someone explain it and provide some clue to intelligible solution of my error message?
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries'
Those are probably just transitive dependencies of your Play dependency, that is why sbt downloaded all of them and put them in your classpath so you could use them without you needing to tell it about them; because the pom of Play already did.
It is not that the build tool or the IDE magically added all those dependencies for you because they read your mind and magically understood you wanted them. And that for some reason the magic stopped working for your own library.
Why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
That is sufficient for the IDE to work, but not for the build tool. The build tool is independent of the IDE; it doesn't know about it. sbt just knows about the dependencies you configured in your definition file.
Even more, you should always configure your dependencies on your build tool and then import that in the IDE; rather than the opposite. IDEs are graphical tools, so their state can not be committed, can not be shared, can not keep track of changes, can not be used in CI / CD environments; additionally, different teammates may want to use different IDEs.
I resolved the error message by adding line in build.sbt file
libraryDependencies += "de.unruh" %% "scala-isabelle" % "master-SNAPSHOT"
and by subsequent run of sbt update.
Error is solved, but the main question still stand - why I had to do this? Why there are tens of dependencies that are not listed in build.sbt and why should I list my dependency in build.sbt and why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
OK, comment by #Luis_Miguel_Mejía_Suárez gave the explanation, that comment is the actual and expected answer to my question.

How to import unmanaged dependencies into code

I'm trying to use sbt to pull down an existing github project and then (obviously) use it in my code. My abbreviated build.sbt is shown below:
lazy val myProjInGit = RootProject(
uri("git://github.com/me/sheet-ref.git#master"))
lazy val root = (project in file("."))
.dependsOn(myProjInGit)
.settings(
name := "MainProj",
)
libraryDependencies ++= Seq( /*other stuff... */)
This is probably a basic one, but how should I then be importing this into code? Could I use, say, import myProjInGit.SampleObject.sampleFunction in my Main.scala? I can see a disconcerting lack of info on SO about this topic so I'm not sure that I'm not barking up completely the wrong tree. Thanks in advance for any help.
EDIT: some further details here. The project I am trying to import is just a library, so it only contains a package object. To try to debug things a little, I'm trying to import it as a ProjectRef, rather than a RootProject. I've discovered the projects sbt command, and if I run it on the project I'm trying to import (not the main one), it gives me:
sbt:SheetRef> projects
[info] In file:/data/va-projects/sheet-ref/
[info] * SheetRef
So... it seems that external project is called SheetRef. If I try to import SheetRef using
lazy val sheetRef = ProjectRef(
uri("git://github.com/me/sheet-ref.git#master"), "SheetRef")
then I get an sbt error:
[error] No project 'SheetRef' in 'git://github.com/me/sheet-r
ef.git#master'.
[error] Valid project IDs: root
Which feels unintuitive. I can import it as root, but then I seem to be unable to access it from my code - if it requires an import statement, it's not obvious to me what it should be.
The dependency has to be an SBT project, so SBT knows how to build it. If it is, then yes, you access it just like any other dependency in your code, because it's added to the classpath (after being built) just like any other dependency.
Which feels unintuitive. I can import it as root, but then I seem to be unable to access it from my code - if it requires an import statement, it's not obvious to me what it should be.
The thing is, it doesn't matter how you add the dependency; it could be a normal library dependency, an unmanaged dependency, a source dependency, etc. Those are SBT concepts, which have no meaning to the Scala compiler.
So the import statement can't depend on project names, jar names or anything like that. In fact, it's the same as if you just put those files into your own project.
Is there someone that made such a thing work? I am trying the same, and somehow manage to get the git project imported but I have no idea how to access the imported scala components.

The meaning of _root_ in sbt

I have two separate Scala projects. In both projects, the build.sbt has the line:
lazy val V = _root_.scalafix.sbt.BuildInfo
The two projects contain several projects so both build.sbt files are multi-project builds. In my research, I came across the idea of a root project and I think _root_ in the above value denotes the root project.
My problem is that in one of the projects, sbt cannot resolve the symbol scalafix in lazy val V = _root_.scalafix.sbt.BuildInfo. When I search scalafix.sbt.BuildInfo in this project, I can find the related jar but sbt somehow misses it. The two projects in so far as I can tell are almost identical but one resolves scalafix while the other does not.
For both projects, the jar seems to be located at the below directory in my Mac:
/Users/soft/.ivy2/cache/scala_2.12/sbt_1.0/ch.epfl.scala/sbt-scalafix/jars/sbt-scalafix-0.6.0-M19.jar!/scalafix/sbt
What is _root_ and how can I help sbt resolve scalafix?
I think root in the above value denotes the root project.
No, this is not true.
All sbt files are scala code and _root_ has the same meaning as _root_ in scala. Thus the answer is the same as in What is the root package in Scala.
The two projects in so far as I can tell are almost identical but one resolves scalafix while the other does not.
The problem is most probably the missing sclafix plugin.
Check that the plugin is enabled in project/plugins.sbt with line
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.1")

IntelliJ IDEA - sbt plugin - 'Expression type Def.Setting[...] must conform DslEntry in sbt file'

I looked for similar questions, I found this:
Expression type DslEntry must conform to Def.SettingsDefinition in SBT file at line enablePlugins(JavaServerAppPackaging)
My issue is similar, but happens in every row.
When I try to run, it compiles and runs successfully.
When I click "Import Project", the yellow notification does not disapear, but the project reloads successfully.
If I rewrite any row as, for example, val _ = scalaVersion := "2.12.4", the error disapear, but it looks awful.
I had the same issue. This solution worked me everytime.
1. Click on sbt tab of right side in IntelliJ Idea
2. Click on Refresh symbol
It will revalidate the Local cache and Gradle dependencies.
That's it.
I closed and removed the project in IntelliJ, then, in my project folder, I removed the subfolders project/, target/ and .idea/. Then there were remaining only build.sbt and src/. Afterwards, in IntelliJ, I did: File -> New -> Project from existing sources -> import project from external model -> sbt.
This procedure has generated a new .idea Project file.
Expression type Def.Setting[String] must conform to DslEntry in SBT file has been gone now.
Hope this helps.
UPDATE 2018-11-17:
When shuffling with modules and projects in IntellIJ SBT, try replacing
lazy val root = (project in file("."))
with an always distinguished
lazy val root = Project(id="module_xyz", base = file("."))
In my case, the problem was solved this way! It occured from having multiple (project in file(".")) in different modules/build.sbt files belonging to the same IntelliJ SBT project. It seems to me that there can only be one (project in file(".")) in an IntelliJ SBT multi module project. So having many different Project(id="module_xyz", base = file(".")) can solve this.
You can also try cutting and pasting everything in your build.sbt file to a word doc, importing your changes, and then pasting it back into the build.sbt file.
I simply installed the newest sbt version on my system and updated project/build.properties so it contains the new version number. This solved the issue for me. You might have to trigger a refresh in IntelliJ manually.

"object index is not a member of package views.html" when opening scala play project in scala ide

I've created a play project with play 2.3.7
In the project directory, I ran activator and ran the eclipse command to generate eclipse project files.
When I go to eclipse (I'm using the Scala IDE from typesafe Build id: 4.0.0-vfinal-20150119-1023-Typesafe , there is an error in my Application.scala file:
object index is not a member of package views.html
Is there something amiss with my setup? The app runs fine when I execute run at the activation console prompt.
Thanks!
EDIT: Added code
package controllers
import play.api._
import play.api.mvc._
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
The error is on the 'Ok..' line.
There is a file in views called index.scala.html, and the app runs file when I run it from activator..
Occasionally after adding a view in Play 2.4.x, IntelliJ IDEA sometimes gets confused and absolutely refuses to build. Even rebuild Project fails:
This still happens from time-to-time in IDEA 15. And when it does, the command line provides the quickest, most-reliable fix:
sbt clean; sbt compile
That's it! IDEA will now compile the project as expected.
Update:
In the rare case that sbt compile completed successfully on the command line, but IntelliJ IDEA 15 still gives the same "object x is not a member" error, then this has solved IDEA's confusion:
File Menu:
The other solutions did not work for me. Some would give me different errors, some would clear the Problems tab but leave me with a red squiggle under views.html.index and auto-complete would not work with the scala.html templates.
What finally worked was to open the project's properties, go to Java Build Path > Source, and add both of the following directories:
target/scala-2.11/src_managed/main
target/scala-2.11/twirl/main
If you only do target/scala-2.11/twirl/main then you'll miss out on the class files generated from the conf directory.
In Scala IDE 4.0.0 thinks there's errors in an out-of-the-box Play Framework 2.3.7 program you can find the solution (in brief: adding target/scala-2.11/twirl/main folder to the compilation path), give it a try.
I had the same problem. I added target/scala-2.x/classes and target/scala-2.x/classes_managed to my Java build path and Eclipse stopped complaining.
Adding target/scala-2.11/twirl/main which is having views.html package to source fixed for me.
I had the same issue running Play 2.4.0-RC1 using default SBT layout (disablePlugins(PlayLayoutPlugin)) and solved it by adding to build.sbt:
sourceDirectories in (Compile, TwirlKeys.compileTemplates) :=
(unmanagedSourceDirectories in Compile).value
#brent-foust 's answer worked for me but only initially. Every time I rebuilt the project from within IDEA I would then get "not found: routes" errors from within target\scala-2.11\twirl\main\views\html\main.template.scala until I performed Brent's workaround again.
I eventually discovered the solution to that was changing a line in the .iml file from
<excludeFolder url="file://$MODULE_DIR$/target/scala-2.11/src_managed/main" />
to
<sourceFolder url="file://$MODULE_DIR$/target/scala-2.11/src_managed/main" isTestSource="false" />
I don't know what the long term implications of doing this are but it has fixed this problem. Some of the other similar problems mentioned might also be fixed by applying the same change to some of the other folders listed in the .iml.
I tried all solutions without any positiv result.
So I went to Preferences > Build, Execution, Deployment > Build Tools > sbt and checked Use sbt shell for imports and builds.
This let the compile button in intelliJ compile with the sbt shell.
I think this is better anyway, since a build server or something similar will compile the same way and not like intelliJ.
For me when importing the project into intellij making sure I "checked" the "auto import" checkbox did the trick.
1) Add the following line to your sbt.build file:
EclipseKeys.preTasks := Seq(compile in Compile)
2) Add the follwing line to your plugins.sbt file under the project folder:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.1.0")
3) Run the "eclipse" command from within sbt
as explained in the documentation of the play framework:
Setting up your preferred IDE
Basically we need a way to put the compiled classes on the path for this to work.
I did the following to fix it.
Since the projects compiles to the target directory.
I went to the Project Properties -> Java Build Path and added a few folders that look like this,
target/scala-2.12/routes/main
target/scala-2.12/twirl
target/scala-2.12/twirl/main
Now i dont want you to assume you will have these exact folders in your case too. That depends on your project setup.
But you should add the folders inside the target/scala-2.x folder.