Most of the time it isn’t convenient to check your project files into your version control system, because they often contain settings specific to your local setup. Additionally project files are difficult to merge when a conflict arises. It may even be the case that team members use a different IDE. Finally, project definitions for your IDE can easily be generated, which is the focus of this article.
To generate the project definitions for IntelliJ IDEA, there is a plugin named sbt-idea. To use the plugin simply add
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.4.0") to
PROJECT_DIR/project/plugins.sbt. Then execute the
gen-idea command (or task as it’s officially called in the documentation) and your project will be generated. Sbt-idea makes sure that dependent libraries are linked to the project, so your IDE is aware of the libraries that your code depends on. Because IntelliJ knows what libraries your code depends on, it can check it directly without the need to compile. Furthermore, it can make suggestions while coding.
Notice that only the class and method names are available. The information from the javadoc or scaladoc, such as parameter names and documentation related to the methods, aren’t. This is because the jars with sources or javadoc aren’t downloaded automatically by SBT.
When the SBT update task is run, only the library jars are downloaded. One way to make SBT download the sources for a library is to add withSources() after each library definition in your build files. When you then update or create a project using gen-idea, these source libraries are also linked to the project.
After regenerating the project you’ll see that parameter names are available and documentation on the method can be viewed directly. You can even directly jump to the source of that method by ctrl-clicking on it. During debugging, you can also step into the code of your dependencies or even place breakpoints on them. However, you will soon notice that this won’t work for libraries that aren’t direct dependencies of your project. So again, only the class and its public members will be shown.
Adding withSources() to every dependency isn’t ideal. You would have to mark every dependency and it wouldn’t download the sources or javadoc for the transitive dependencies (dependencies of your dependencies).
Another way to retrieve the sources and the reference documentation for your dependent libraries is running the update-classifiers command in SBT, before generating your project using sbt-idea. update-classifiers will download the sources and the javadoc for all the libraries in your project. This includes the transitive dependencies. sbt-idea will automatically detect that the sources are available and link them to the project. Now you can also look into the sources of your dependencies.
Disadvantage of this method is that you have to run two commands every time you want to update your project files, for example because you have updated your dependencies or changed your project structure. Luckily SBT allows the definition of aliases for commands. Aliases allow to run one or multiple commands with your own given name.
Aliasses can both be defined inside Build.sbt and Build.scala. In Build.sbt you add the following line (make sure there is an empty line before and after):
In Build.scala you add the addCommandAlias to the project settings.
lazy val projectSettings = Defaults.defaultSettings ++ Seq( libraryDependencies ++= libraries, addCommandAlias("generate-project", ";update-classifiers;gen-idea") ) lazy val root = Project("projectname", file("."), settings = projectSettings )
Then, when you type generate-project into your SBT console, it automatically generates a project for IntelliJ and attaches the libraries with its sources to the project.
By default the sources or javadoc for your Build.scala aren’t attached. When you want to do that, you will also have to run update-sbt-classifiers before generating the project definition and specify the sbt-classifiers parameter for gen-idea.
The alias definition for that is:
addCommandAlias("generate-project", ";update-classifiers;update-sbt-classifiers;gen-idea sbt-classifiers")