I've a multi-project structure which builds with sbt 0.11.3. I wanted to centralize my dependency versions, project versions, artifacts, shell prompt stuff and such. It would be really helpful for my plans on release management and version control. So I've created a plugin and put my global configurations there. My projects read it from github and build it as a plugin. Everything is lovely.
./project/project/Build.scala
import sbt._
object PluginDef extends Build {
override lazy val projects = Seq(root)
lazy val root = Project("plugins", file(".")) dependsOn(versionPlugin)
lazy val versionPlugin = uri("git://github.com/config.git") //changed the uri here
}
So sbt fetches the plugins latest version if it haven't been already. Caches that version in ~/.sbt/staging/somehashcode. But I couldn't make it update the project when there are changes in plugin project. I manually go and update it whenever needed. Sadly, in a 20 man team its causing some problems.
How can we make it check for plugin updates?
I haven't tried this, but the following might work.
refreshing plugin
update to sbt 0.12.1, which fixes update
then from sbt shell:
> reload plugins
> update
> reload return
specifying a particular tree
It may be helpful to fix the source dependency to a particular point in time for some situations. If so you can add commit hash or tag as "git://github.com/config.git#hash".
Related
I have an sbt project that I have imported into Intellij. Sometimes I build the project at the command line using sbt, and then when I need to debug I build it from within Intellij. However, each time I alternate it requires a full rebuild when there is no need. Both build procedures output to the same class folder, namely .../target/scala-2.11/classes, so I don't understand why a full rebuild keeps happening?
As stated by CrazyCoder, intellij and sbt build have each their own tracking of changed files for incremental build. Thus each time one re-compile a file, the other treats it as a changed file and recompile it too.
While CrazyCoder's answer describes how to make them work on separated directory, by changing the sbt compiled classes dir. This answer explain how you can configure Intellij to use sbt for all build, thus only sbt does the compilation. This is a relatively new feature.
Just check the option:
file
> Settings
> Build, Execution, Deployment
> Build Tools
> SBT
> Use SBT shell for build and import
It works at least since intellij version 2017.2.3, and most probably it is an option from the SBT plugin.
For details about this feature, see jetbrains ticket: https://youtrack.jetbrains.com/issue/SCL-10984
IntelliJ IDEA cannot reuse the classes produced by the other build systems because it has its own incremental compiler which tracks the dependencies and builds the caches during the compilation so that it can compile only modified and dependent files when you make a change in the code. When you built with SBT/Maven/Gradle or command line javac, IntelliJ IDEA compiler cache doesn't know about what has changed and which files it should compile, therefore it performs the full rebuild.
A solution would be to use different output directories for IDE and SBT, this way IntelliJ IDEA will rebuild only files modified since the last build in the IDE and your command line SBT build will not trigger a rebuild in the IDE.
This configuration is performed using the sbt-ide-settings plug-in.
Add the following into plugins.sbt (or whatever files you configure the plugins in):
resolvers += Resolver.url("jetbrains-bintray",url("http://dl.bintray.com/jetbrains/sbt-plugins/"))(Resolver.ivyStylePatterns)
addSbtPlugin("org.jetbrains" % "sbt-ide-settings" % "0.1.2")
And here is how to customize the IDE output directory in build.sbt:
ideOutputDirectory in Compile := Some(new File("target/idea/classes"))
ideOutputDirectory in Test := Some(new File("target/idea/test-classes"))
Feel free to change the paths according to your needs.
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.
I want to use the sbt-scrooge plugin, but its repo is unavailable now - http://koofr.github.com/.
I thought I'd include this plugin's source code directly in my own repo (as a git submodule).
I tried:
git submodule add https://github.com/bancek/sbt-scrooge.git project/sbt-scrooge
and added:
addSbtPlugin("net.koofr" % "sbt-scrooge" % "3.0.45")
to project/plugins.sbt. But it doesn't work - the following exception is thrown:
sbt.ResolveException: unresolved dependency: net.koofr#sbt-scrooge;3.0.45: not found
What's the right way to do that?
I know that I could checkout sbt-scrooge to the local filesystem, then sbt publish-local, and add the local ivy2 repo to sbt as a resolver. But I just want to know whether there are other ways to do this.
As explained here you can puth this in your project/plugins.sbt:
lazy val root = project.in(file(".")).dependsOn(scroogePlugin)
lazy val scroogePlugin = file("sbt-scrooge")
Or simply (without creating a local submodule):
lazy val root = project.in(file(".")).dependsOn(scroogePlugin)
lazy val scroogePlugin = uri("https://github.com/bancek/sbt-scrooge.git")
If you want to use a plugin it has to be available to sbt (and somehow finds its place in your local repository so addSbtPlugin can eventually find it or the project (sub)project of your sbt project should have it on the classpath).
Be adviced that not all plugins should be an integral part of a sbt project. Quite the contrary - they can be used in a project, but that doesn't necessarily mean they should be referenced by any project-specific files (within the project's directory), e.g. plugins to generate IDE-specific files. These plugins should be part of the global configuration in ~/.sbt under plugins.
There's also the issue of version mismatch between plugins and sbt. In your case, sbt-scrooge supports 0.12.2 (see project/build.properties) that might be unusable in sbt 0.13+.
With that said, I think the "right way" in your case since the sbt-scrooge plugin seems no longer maintained is to fork the project and maintain yourself in your own repository. sbt 0.13.1 is already the latest version, and the plugin may not yet support it. When the plugin gets new life with your fork other developers might benefit from the resurrection, too and having the sources attached to another project would only hinder reusability.
The answer to a similar question has helped me to offer a working solution that works with sbt 0.12.2 and without cloning the git repository.
$ cat project/build.properties
sbt.version=0.12.2
$ cat project/project/SbtScroogePlugin.scala
import sbt._
object SbtScroogePlugin extends Build {
lazy val plugins = Project("plugins", file(".")) dependsOn sbtScroogePlugin
lazy val sbtScroogePlugin = uri("https://github.com/bancek/sbt-scrooge.git")
}
$ cat sbt-scrooge.sbt
import net.koofr.sbt._
seq(CompileThriftScrooge.newSettings: _*)
With the project files above, sbt should be able to use the tasks and settings of the sbt-scrooge plugin.
$ sbt
[info] Loading global plugins from /Users/jacek/.sbt/plugins
[info] Loading project definition from /Users/jacek/sandbox/tmp/sample-project/project/project
[info] Loading project definition from /Users/jacek/.sbt/staging/52a2b7ff1377492a32ff/project
[info] Loading project definition from /Users/jacek/sandbox/tmp/sample-project/project
[info] Set current project to default-fe8e50 (in build file:/Users/jacek/sandbox/tmp/sample-project/)
> about
[info] This is sbt 0.12.2
[info] The current project is {file:/Users/jacek/sandbox/tmp/sample-project/}default-fe8e50
[info] The current project is built against Scala 2.9.2
[info] Available Plugins: org.sbtidea.SbtIdeaPlugin, com.timushev.sbt.updates.UpdatesPlugin, net.koofr.sbt.CompileThriftScrooge
[info] sbt, sbt plugins, and build definitions are using Scala 2.9.2
> scrooge-version
[info] 3.0.43
For the other tasks and settings, write scrooge- and hit TAB.
> scrooge-[TAB]
scrooge-build-options scrooge-cache-folder scrooge-fetch scrooge-gen
scrooge-jar scrooge-name scrooge-thrift-external-source-folder scrooge-thrift-include-folders
scrooge-thrift-namespace-map scrooge-thrift-output-folder scrooge-thrift-source-folder scrooge-thrift-sources
scrooge-unpack-deps scrooge-version
I upgraded my IntelliJ(12.1.4) to the new Play 2.0 Support(0.5.54) plugin and two things happened:
IntelliJ no longer recompiles my .scala classes, this meaning that if
I e.g change the signature of a method from def something(s1:
String) = {} to def something(s1: String, s2: String) = {} I get an
error that ) is expected after the first param. I run the app from
the terminal with play debug ~run and there the app recompiles
without a problem.
The scala.html are not evaluated properly and I get a lot of syntax
errors. The color encoding is also wrong. I tried to change the
Scala plugin to the nightly build(0.10.281) as suggested in the
comments but it still doesn't work.
This is crazy bad since it makes working with the IntelliJ painful and counterproductive.
There is a bug reported: http://youtrack.jetbrains.com/issue/SCL-5749 but what
should I do in the meantime? Anybody solved this issue?
For me play2.0 version 0.2.49 with scala version 0.10.279 does the trick.
With the other versions I ether get bugs, or my IDE just doesn't work correct.
link to play plugin: http://plugins.jetbrains.com/plugin/download?pr=&updateId=13272
link to scala plugin: http://plugins.jetbrains.com/plugin/download?pr=&updateId=13504
instructions:
1 download the .zip (do not extract)
2 make sure there are no play or scala plugins in your IDE folder (C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.2\plugins)
3 op the IDE and open the plugin menu. (file -> settings... -> plugins
4 click the button "install from disk" and select the play zip file and the scala zip file. (you don't need to disable the play and scala plugin in the plugin list, they get swapped after the IDE restart
5 restart your IDE
6(optional) report back here if it worked or not
Use the IntelliJ sbt plugin and compile your classes from sbt with "~compile". You can start play with "container:start".
Here is my own Build.scala file I run from within IntelliJ:
import sbt._
import Keys._
import play.Project._
object ApplicationBuild extends Build {
val appName = "Blade_Night_App"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
anorm
)
val main = play.Project(appName, appVersion, appDependencies).settings(
// Add your own project settings here
)
}
And here the plugins.sbt:
// Comment to get more information during initialization
logLevel := Level.Warn
// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projects
addSbtPlugin("play" % "sbt-plugin" % "2.1.0")
Additional I have a Debug configuration for a Scala application with
Main class: xsbt.boot.Boot
VM-Options: -Dfile.encoding=UTF8 -Dsbt.boot.properties=file:///.../play-2.1-RC4/framework/sbt/sbt.boot.properties -Dplay.version=2.1-RC4 -Dsbt.ivy.home=.../play-2.1-RC4\repository -Dplay.home=.../play-2.1-RC4/framework -Xms128M -Xmx512M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M
Program argument: run
This replaces the Play plugin completely for me :-)
The problem here is that there is a massive incompatibility with the newer Scala plugins and the Play plugin in general. To get it to work, you have to use Scala plugin version 0.7.264 (that is the specific version number the support person gave to me anyway). I had this issue as well and, to be safe, I also reverted back to Play plugin version 0.2.26. Everything works as it did before now.
To go back to the previous version, you have to download the ZIP archive from the JetBrains plugin site and choose "install from disk" in IntelliJ IDEA. Here is the link to get the older Scala plugin version you need: http://plugins.jetbrains.com/plugin/?id=1347
This is a big compatibility issue and apparently JetBrains is aware of it, but only by contacting their help desk did I find out how to fix it for now until a more permanent solution comes along.
Good news everyone: Play 2.0 plugin and Scala plugin versions are synchronized again! For IDEA12 there are 0.13.286 versions (of both) now. After updating I see some new highlighting errors, but at least they work, and there are no error messages about incompatibility!
So, it seems like it is safe now to update to the latest version of both through the built-in mechanism.
From now the build process of Scala and Play 2.0 plugins is common, so Play 2.0 plugin has the same build number.
— this also gives some hopes for not repeating the same problem in future.
I've configured SBT (0.11.0) to pull in a GitHub project as a dependency, as per my answer on this question here.
It works fine except that I can't seem to get SBT to re-compile my Git dependency when it gets updated. In other words: if I make an update to the dependency, push to Git and reload my project's SBT and run package, then SBT does not recompile the external Git dependency when compiling my project.
I've tried creating a new branch in my Git dependency (say, forcenew) and updating the branch in my SBT project configuration to use this:
lazy val depProject = RootProject(uri("git://github.com/me/dep-project.git#forcenew"))
But even this doesn't force a refresh. I'm a bit stumped - I can't even find where SBT puts the Git project to compile it (it doesn't seem to be in ~/.sbt/ or ~/.ivy2/)...
Any help greatly appreciated!
From: https://github.com/sbt/sbt/issues/335
this should be fixed in 0.12.0, just call "sbt update"
It was fixed in 0.12.0 so sbt update is enough, but got back in 13.0 -- for now, you have to wipe dependency from ~/.sbt/staging/ manually
You likely want to clear out ~/.sbt/staging/
A quick hack you can add to your build.sbt:
def removegit = Command.command("removegit"){state =>
val home = sys.env("HOME")
val k = ("rm -rf "+ home + "/.sbt/0.13/staging/").!
state
}
commands ++= Seq(removegit)
And then sbt removegit will wipe that directory. This doesn't do anything smart like checking commits, which would be a great upgrade... The repos are being stored in ~/.sbt/0.13/staging/ on my machine, you may need to adjust that.